// Пример 15. Загрузка данных в Excel через промежуточный файл

var Tabl; // объект класса для работы таблицей

int idxTN  =0, // табельный номер
    idxPODR=1, // подразделение
    idxFIO =2, // ФИО
    CntIdx =3;

int fld[CntIdx];

int len=256;
char str[len];

Primer15()
{
  int type=0; // 0-путь; 1-файл
  int Dist=-1;

  char Heading[len],
       Path[len]; 

  sprintf(Heading,"Путь для передачи в файл:");
  sprintf(Path,"c:\\%-200.200s","");
  FreeSpaceString(Path,3,"");

  var CFile=CreateObject("CurPrnFile"); // объект класса для работы с текущим файлом печати
  CFile.SetFlagBrowse(0);               // запрещаем просмотр

  int hf;                // хэндл создаваемого файла
  char Buffer[len];      // буфер для строки выводимой в файл
  char TmpFileName[len]; // буфер для имени временного файла
  char NameStr[len];     // буфер для имени файла
  unsigned long dwBytes;
  sprintf(NameStr,"%s%s", Path, "prim15.txt"); 

  // создадим временный файл в текущей директории
  sprintf(TmpFileName,"test.tmp");
  DeleteFile(TmpFileName);

//if ((stream = CreateFile(name       ,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL)) == INVALID_HANDLE_VALUE)
  if ((hf  =    CreateFile(TmpFileName,1073741824   ,1              ,0   ,1         ,128                  ,0   )) == -1)
  {
    AmbaMessageBox("невозможно создать файл","ошибка",1,0);
  }

  Tabl = CreateObject("CurPrnTbl");
  int cnt=Tabl.Count_Rcr(); // полное число записей   

  FillFld();

  for ( long rcr=0; rcr<cnt; ++rcr) // идем по всей таблице
  {
    long   tn   = atol(Tabl.Text(fld[idxTN],rcr)),
           podr = atol(Tabl.Text(fld[idxPODR],rcr));
    string fio  = Ansi(Tabl.Text(fld[idxFIO],rcr)); 
    FreeSpaceString(fio,3,""); // убираем лишние пробелы

    sprintf(Buffer,"%s\r\n",fio); 
    WriteFile(hf,Buffer,strlen(Buffer),dwBytes,0); // пишем в файл
  }

  long FileSize=SetFilePointer(hf,0,0,1); // установив указатель таким образом можно определить размер файла
  CloseHandle(hf); // записали и закрыли

  char RootPathName[20];
  unsigned long SectorsPerCluster=0;
  unsigned long BytesPerSector=0;
  unsigned long NumberOfFreeClusters=0;
  unsigned long TotalNumberOfClusters=0;

  sprintf(RootPathName,"%s",Path); FreeSpaceString(RootPathName,3,"");

  int iDisk=GetDiskFreeSpace(RootPathName,SectorsPerCluster,BytesPerSector,
                             NumberOfFreeClusters,TotalNumberOfClusters);

  double FreeSpace=static_cast_to_double(NumberOfFreeClusters) *
                   static_cast_to_double(SectorsPerCluster) *
                   static_cast_to_double(BytesPerSector);

  if (iDisk==0)
  {
    AmbaMessageBox("устройство не готово\nфайл не будет создан","ошибка",1,0);
    DeleteFile(TmpFileName);
  }
  else
  {
    if (FreeSpace<static_cast_to_double(FileSize))
    {
      AmbaMessageBox("на диске недостаточно места\nфайл не будет создан","ошибка",1,0);
      DeleteFile(TmpFileName);
    }
    else
    {
      DeleteFile(NameStr);
      CopyFile(TmpFileName,NameStr,0); 
      DeleteFile(TmpFileName);
    }
  }

  var xls=CreateObject("Excel.Application");  // создаем объект Excel.Application, т.е. запускаем Excel, если он установлен конечно
  char Dir[len];                              // строка для текущей директории
  GetCurrentDirectory(len,Dir);               // получаем текущую директорию (это корень каталога ZPL из которого запустили АМБу)
  string nm="prim15.xls";                     // имя Excel'евского файла, он должен находиться в каталоге USER
  var WorkDir = Dir + "\\..\\script\\user\\"; // получаем рабочий каталог, т.е. из ZPL переходим в USER
  xls.Caption=Ansi("Список ЛС");              // заголовок (в windows кодировке)
  xls.Workbooks.Add(WorkDir+nm);              // открываем в Excel'е наш файл ls.xls

  string name=xls.Workbooks.Item(1).Name;              // читаем имя workbook'а, чтобы обращатья потом к нему по имени
  var wsh=xls.Workbooks.Item(name).Worksheets.Item(1); // создаем ссылку на на наш worksheet чтобы избежать впоследствии длинных записей

  wsh.Name=Ansi("Список ЛС"); 

  xls.Visible=true;               // делаем Excel видимым

}


FillFld()
// находим поля в таблице и определяем их номера
{
  fld[idxTN]   = Tabl.Find_Name_Fld("TN");
  fld[idxPODR] = Tabl.Find_Name_Fld("PODR");
  fld[idxFIO]  = Tabl.Find_Name_Fld("FIO");
}


Ansi( Str )
// функция перекодирует значение Str в windows-кодировку и возвращает перекодированное значение
// Str - строка, которую нужно перекодировать
{
   string Ans=Str;
   OemToChar(Str,Ans);
   return Ans;
}
