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

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

int idxTN    = 0, // табельный номер
    idxPODR  = 1, // подразделение
    idxFIO   = 2, // ФИО
    idxINCOM = 3, // облагаемый доход
    idxTAX   = 4, // исчисленный подоходный налог

    CntIdx   = 5;

int fld[CntIdx];

int len=256;
char str[len];

Primer17()
{

  char Path[len]; sprintf(Path,"c:\\");

  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, "prim17.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(); // находим поля

  // напечатаем на первом листе название организации и количество ЛС

  // Данные из справки о предприятии

  char Org[len];
  char Ruk[len];
  char Glb[len];

  GetEnterpriseVar("ИМЯП", Org,len-1); // Наименование предприятия или отделения иностранной организации
  GetEnterpriseVar("РУКП", Ruk,len-1); // Руководитель
  GetEnterpriseVar("ГЛБУХ",Glb,len-1); // Главбух

  FreeSpaceString(Org,3,""); UpperString(Org); OemToChar(Org,Org);
  FreeSpaceString(Ruk,3,""); UpperString(Ruk); OemToChar(Ruk,Ruk);
  FreeSpaceString(Glb,3,""); UpperString(Glb); OemToChar(Glb,Glb);

  sprintf(Buffer,"1:E3:%s\r\n",Org); WriteFile(hf,Buffer,strlen(Buffer),dwBytes,0); // пишем в файл
  sprintf(Buffer,"1:E5:%s\r\n",Ruk); WriteFile(hf,Buffer,strlen(Buffer),dwBytes,0); // пишем в файл
  sprintf(Buffer,"1:E6:%s\r\n",Glb); WriteFile(hf,Buffer,strlen(Buffer),dwBytes,0); // пишем в файл
  sprintf(Buffer,"1:E8:%d\r\n",cnt); WriteFile(hf,Buffer,strlen(Buffer),dwBytes,0); // пишем в файл


  string cell = ""; // номер ячейки

  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,""); // убираем лишние пробелы

    char inc[len]; sprintf(inc,"%s",Tabl.Text(fld[idxINCOM],rcr)); FreeSpaceString(inc,3,""); // доход
    char tax[len]; sprintf(tax,"%s",Tabl.Text(fld[idxTAX],rcr));   FreeSpaceString(tax,3,""); // налог

    cell = "A" + static_cast_to_string(rcr+1) + ":";
    sprintf(Buffer,"2:%s%s\r\n",cell,fio); WriteFile(hf,Buffer,strlen(Buffer),dwBytes,0); // пишем в файл

    cell = "F" + static_cast_to_string(rcr+1) + ":";
    sprintf(Buffer,"2:%s%s\r\n",cell,inc); WriteFile(hf,Buffer,strlen(Buffer),dwBytes,0); // пишем в файл

    cell = "H" + static_cast_to_string(rcr+1) + ":";
    sprintf(Buffer,"2:%s%s\r\n",cell,tax); 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);
    }
  }


  // запускаем Excel
  var xls=CreateObject("Excel.Application");  // создаем объект Excel.Application, т.е. запускаем Excel, если он установлен конечно
  char Dir[len];                              // строка для текущей директории
  GetCurrentDirectory(len,Dir);               // получаем текущую директорию (это корень каталога ZPL из которого запустили АМБу)
  string nm="prim17.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 wsh1=xls.Workbooks.Item(name).Worksheets.Item(1), // создаем ссылку на на наш worksheet чтобы избежать впоследствии длинных записей
      wsh2=xls.Workbooks.Item(name).Worksheets.Item(2); 

  wsh1.Name=Ansi("Общие сведения"); 
  wsh2.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");
  fld[idxINCOM] = Tabl.Find_Name_Fld("INCOM");
  fld[idxTAX]   = Tabl.Find_Name_Fld("TAX");
}


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