// Пример 3. Печать списка лицевых счетов в Excel, каждый ЛС печатается на отдельном листе

var CFile,  // объект класса для работы с текущим файлом печати
    CTabl,  // объект класса для работы таблицей  
    xls,    // объект Excel.Application
    wb,     // объект workbook
    wsh;    // объект worksheet

int idxC_FIO=0, // табельный номер
    idxFIO=1;   // ФИО

int nFld=2; // число элементов в массиве aFld

Primer03()
{
  var CMsg=0;     // Процент выполненной работы

  int bTime = false;   // false-показывать процент,
                       // true-показывать оставшееся время

  CMsg=CreateObject("ProgressBar");
  CMsg.Initial(0,100,1);
  CMsg.SetShowTime(static_cast_to_int(bTime));

  int cListInBook=400+1; // максимальное число листов в книге (для печати в Excel) (+1 это шаблон)

  string aFld[nFld];

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

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

  int cWsh=1,   // число worksheet'ов в workbook'е
      cWb=1,    // число workbook'ов
      cWbTmp=1; // число временных workbook'ов

  char Dir[128];
  char FileName[250];

  string WorkDir, // рабочий каталог
         nm,      // имя файла
         tmpnm;   // имя временного файла

  xls=CreateObject("Excel.Application");
  GetCurrentDirectory(128,Dir);
  nm="prim03.xls";
  WorkDir = Dir + "\\..\\script\\user\\";
  xls.Caption=Ansi("Список лицевых счетов");
  xls.Workbooks.Add(WorkDir+nm);
  wb=xls.Workbooks(1);

  // убираем мусор
  DeleteFiles(WorkDir,"wb*.tmp");

  // ищем подходящее имя для файла, если же остался "мусор" то подбираем имя (FileName) 
  // перебирая номера (cWbTmp)
  for (;;)
  {
    sprintf(FileName,"wb%d.tmp", cWbTmp);
    tmpnm=WorkDir+FileName;

    if ( access(tmpnm,0) ) 
    {
      break;
    }
    else 
    {
      cWbTmp++; continue;
    }
  }

  // цикл по записям таблицы
  for (int zap=0; zap<cr; zap++)
  {
    FillFld(aFld,zap); // заполняем массив aFld значениями полей из таблицы

    // если число WorkShitov равно заданному максимальному добавляем новый WorkBook
    if (cWsh==cListInBook)
    {
      wb.Worksheets(cWsh).Visible=false; // делаем лист шаблона невидимым
      wb.Worksheets(1).Select();         // выбираем первый лист (он же последний из добавленных в этой книге, при добавлении лист ставится вперед)
      xls.Workbooks.Add(WorkDir+nm);     // создаем новую книгу на основе шаблона ( это файл prim03.xls )
      sprintf(FileName,"wb%d.tmp", cWbTmp); 
      cWbTmp++;                
      tmpnm=WorkDir+FileName;  // подбираем имя для заполненной книги
      wb.SaveAs(tmpnm);        // и сохраняем ее
      cWb++;                   // увеличиваем счетчик книг
      wb=xls.Workbooks(cWb);   // переменной wb присваиваем ссылку на вновь созданную книгу
      cWsh=1;                  // сбрасываем счетчик листов
    }

    wb.Worksheets(cWsh).Copy(wb.Worksheets(cWsh)); // создаем новый лист копированием шаблонного листа
    cWsh++;                                        // увеличиваем счетчик листов
    wsh=wb.ActiveSheet; // переменной wsh присваиваем ссылку на активный лист (тот который только что создали)
    wsh.Name="TH " + aFld[idxC_FIO]; // присваиваем имя листу

    excel_DL(aFld); // печатаем в Excel

    // progress bar - чтобы видеть процент выполненной работы до того как появится результат
    if ( CMsg.Msg_Proc(" Подождите немного. Идет подготовка к печати. ",100.*zap/cr)==ESC )
    {
      return 0;
    }

  } // конец цикла по записям таблицы


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

  wb.Worksheets(1).Select(); // выделяем первый лист

  wb.Worksheets(cWsh).Visible=false; // шаблонный лист делаем невидимым
  sprintf(FileName,"wb%d.tmp", cWbTmp);
  tmpnm=WorkDir+FileName; // подбираем имя для книги
  wb.SaveAs(tmpnm); // сохраняем книгу

  return 0;
}


excel_DL(&aFld)
// функция печати в Excel
// aFld - массив значений полей таблицы
{
  WriteToCell("A1",aFld[idxFIO]); // печатаем в ячейку A1 текущего листа ФИО данной записи

  return 0;
}


FillFld(&aFld, zap)
// функция заполняет массив aFld
// aFld - массив который нужно заполнить
// zap - номер записи
{
  aFld[idxC_FIO]=CTabl.TextS("C_FIO",zap); FreeSpaceString(aFld[idxC_FIO],3,"");
  aFld[idxFIO]  =CTabl.TextS("FIO",zap);   FreeSpaceString(aFld[idxFIO],3,"");

  ToAnsi(aFld, nFld);

  return 0;
}


ToAnsi(&Array, n)
// функция переводим значения массива Array в windows-кодировку
// Array - массив, значения которого нужно перекодировать
// n - размер массива
{
  string str;
  for (int i=0; i<n; i++) 
  {
    str=Array[i];
    OemToChar(str,Array[i]); 
  }

  return 0;
}


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


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