// Пример 4. Печать списка ЛС в Excel с удалением и добавлением строк в листе.

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

  var CTabl=CreateObject("CurPrnTbl");  // объект класса для работы с текущей таблицей
  int cr=CTabl.Count_Rcr();             // число рабочих записей в таблице   

  string tn,  // табельный номер
         fio; // фамилия, имя, отчество

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

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

  char Org[201];
  char Inn[128];
  char Kpp[128];
  char Ruk[128];
  char Glb[128];

  GetEnterpriseVar("ИМЯП",     Org,200); // Наименование предприятия или отделения иностранной организации
  GetEnterpriseVar("ИНН",      Inn,127); // ИНН
  GetEnterpriseVar("КОДПОСУЧ", Kpp,127); // Код причины постановки на учет
  GetEnterpriseVar("РУКП",     Ruk,127); // Руководитель
  GetEnterpriseVar("ГЛБУХ",    Glb,127); // Главбух

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

  WriteToCell(wsh,"G2",  Org); // печатаем название организации
  WriteToCell(wsh,"I26", Ruk); // печатаем фамилию и инициалы руководителя     
  WriteToCell(wsh,"I28", Glb); // печатаем фамилию и инициалы гл.бухгалтера     

  string AC[20];

  // печатаем ИНН
  AC[0]= "G4"; 
  AC[1]= "H4"; 
  AC[2]= "I4"; 
  AC[3]= "J4"; 
  AC[4]= "K4"; 
  AC[5]= "L4"; 
  AC[6]= "M4"; 
  AC[7]= "N4"; 
  AC[8]= "O4"; 
  AC[9]= "P4"; 
  TypeCharArray(wsh,AC,Inn,10);

  // печатаем КПП
  AC[0]= "R4"; 
  AC[1]= "S4"; 
  AC[2]= "T4"; 
  AC[3]= "U4"; 
  AC[4]= "V4"; 
  AC[5]= "W4"; 
  AC[6]= "X4"; 
  AC[7]= "Y4"; 
  AC[8]= "Z4"; 
  TypeCharArray(wsh,AC,Kpp,9);

  string cell; // в эту строку будем записывать имена ячеек worksheet'а

  int row=9; // стоя на этой строке начнем удалять строки бланка
  char rCel[20]; // буфер для диапазона ячеек

  // удаляем 14 строк бланка
  for (int i=0; i<14; i++) 
  {
    wsh.Rows(row).Delete();
  }

  // вставляем нужное нам число строк, равное числу записей таблицы
  for (int i=0; i<cr; i++)
  {
    wsh.Rows(row).Insert(); // вставляем строку

    sprintf(rCel,"B%d:C%d",row,row);
    wsh.Range(static_cast_to_string(rCel)).MergeCells=true;       // выполняем объединение ячеек для диапазона rCell
    wsh.Range(static_cast_to_string(rCel)).HorizontalAlignment=1; // устанавливаем горизонтальное выравнивание по правому краю

    sprintf(rCel,"D%d:E%d",row,row);
    wsh.Range(static_cast_to_string(rCel)).MergeCells=true;       // выполняем объединение ячеек для диапазона rCell          
    wsh.Range(static_cast_to_string(rCel)).HorizontalAlignment=1; // устанавливаем горизонтальное выравнивание по правому краю

    sprintf(rCel,"F%d:Z%d",row,row);
    wsh.Range(static_cast_to_string(rCel)).MergeCells=true;       // выполняем объединение ячеек для диапазона rCell          
    wsh.Range(static_cast_to_string(rCel)).HorizontalAlignment=2; // устанавливаем горизонтальное выравнивание по левому краю
  }

  // цикл по записям таблицы
  for (int zap=0; zap<cr; zap++)
  {
    string n=static_cast_to_string(zap+1); // номер по порядку
    tn=CTabl.TextS("C_FIO",zap); FreeSpaceString(tn,3,"");  // читаем из таблицы значение поля C_FIO для записи zap (табельный номер)
    fio=Ansi(CTabl.TextS("FIO",zap)); FreeSpaceString(fio,3,""); // читаем из таблицы значение поля FIO для записи zap

    row=9+zap; // вычисляем номер строки на листе

    cell="B" + static_cast_to_string(row); 
    WriteToCell(wsh, cell, n); // пишем номер по порядку

    cell="D" + static_cast_to_string(row); 
    WriteToCell(wsh, cell, tn); // пишем табельный номер

    cell="F" + static_cast_to_string(row); 
    WriteToCell(wsh, cell, fio); // пишем ФИО
  }

  row=9+cr; wsh.Rows(row).Delete(); // удаляем лишнюю строчку на листе

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

  return 0;
}

WriteToCell(wsh,cell,str)
// функция печатает значение str в ячейку cell листа wsh
// wsh  - ссылка на worksheet
// cell - имя ячейки
// str  - значение, которое требуется записать в ячейку Cell рабочего листа WSheet
{
  wsh.Range(cell).Value=static_cast_to_string(str);
  return 0;
}

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

TypeCharArray(wsh,&ACell,&str,n)
// функция печатает значения символьного массива str в ячейки листа wsh, адреса ячеек содержатся в массиве ACell
// wsh - ссылка на рабочий лист
// ACell - массив с адресами ячеек
// str - строка, массив символов
// n - сколько символов из строки str нужно печатать
{
  char t[10];
  for (int i=0; i<n; i++)
  {
    sprintf(t,"%c",str[i]);                     
    wsh.Range(ACell[i]).Value=static_cast_to_string(t);
  }

  return 0;
}
