// Пример 39. Печать в Excel таблицы с шапкой и подножием с разбивкой на Worksheet'ы.
// Документарная ведомость передачи сумм в НовикомБанк
// в "Начало печати" ставим: 
//    return -1;

int CntHead = 11, // число строк под шапку
    CntFoot = 0, // число строк под подножие
    nStart = 14,  // стартовый номер печатаемой строки
    n = 0;       // номер печатаемой строки

double eps = 0.0001;
double Itog=0;

int zap = 0,   // счетчик записей таблицы
    len = 512; // количество символов в строке

int lin = 0,  // счетчик напечатанных строк на листе
    alin = 0; // счетчик напечатанных строк

int tmpi = 0; // вспомогательная переменная

// Параметры
int CntStr = 0; // количество строк на листе

VedNovikBnk(&param,npar) 
//Prikaz(&param,npar)
// param - массив для передачи параметров из формы печати
// npar - число элементов в массиве param
{
  // параметры
  CntStr = atoi(param[0]); if (CntStr<1) CntStr=1; if (atoi(param[0])==0) CntStr=25; // число строк на листе (по умолчанию 25)


  var File;                             //  привет
  File = CreateObject("CurPrnFile");    //        от 
  File.SetFlagBrowse(0);                //          Вита
  File.SetFlag_Print(0);                //              лия

  Setup();  

  try
  {
    SetupExcel();

    Header();   // шапка
    Footer();   // подножие

    // цикл по записям таблицы
    for ( zap = 0; zap < cr; zap++ )
    {
      rec_ins = CTabl.Flag_Action_1(zap);
      if (cr_ins) if (!rec_ins) continue; // если какие-то записи выделены, печатаем только их

      //if (ESC==Panel_Zapros(" Control() ","",
      //                  " lin   ",lin, 20,
      //                  " vp    ",vp, 20,
      //                  " nlst  ",nlst, 20)
      //                                                        ) return ESC;


      if ( !lin )   {   NextWorksheet();   }


      PrintTableToExcel(); // печать одной строки в Excel
    
    //  Control(); // проверка условий для перехода к следующему Worksheet'у
      
      if ( CMsg.Msg_Proc(" Подождите немного. Идет подготовка к печати. ",100.*zap/cr)==ESC )
      {
        AmbaMessageBox("Печать не была завершена!","Предупреждение!",0,0);
        xls.Visible = true;

        return;
      }
    }
  }
  catch(...)
  {
    xls.Visible = true;
    throw;
  }

  wsh.Rows(n-1).Delete(); // удаление лишней строки
  wsh.Cells(1,1).Select();
  cwsh = wb.Worksheets.Count();
  wb.Worksheets.Item(cwsh).Visible = false;
  wb.Worksheets.Item(1).Select();
  wb.Worksheets.Item(1).Range("A1").Select();
  xls.Visible = true;

  return xls;
}


Control()
{ // проверка условий для перехода к следующему Worksheet'у
      if (ESC==Panel_Zapros(" Control() ","",
                        " vp    ",vp, 20,
                        " nlst  ",nlst, 20)
                                                              ) return ESC;
  if ( vp )
  { //__________________________ больше одного листа
    if ( nlst == 1 )    {    // первый лист
      tmpi = CntHead + lin;  // число напечатаных строк вместе с шапкой                                               
      if ( tmpi >= CntStr && rec_work > alin )  PrepareNextWorksheet();  // нужно перех на след страницу
    }

    if ( nlst > 1 )
    {
      if ( lin >= CntStr && rec_work > alin )
        PrepareNextWorksheet();
    }
  }
  else
  { // один лист
    if ( alin == rec_work ) wsh.Rows(n-1).Delete(); // удаление лишней строки
  }

  return 0;
}


PrepareNextWorksheet()
{ // подготовка к переходу на следующий Worksheet
  DelFoot(); // удаляем подножие
  lin = 0; // обнуляем счетчик напечатаных строк
  wsh.Rows(n-1).Delete(); // удаление лишней строки
  wsh.Cells(1,1).Select(); 

  return 0;
}


Header()      // печать шапки
{ 
  char arg[40],
       str[40];
  var Mes = CreateObject("KMonth");
  Mes.SetMonth(mtek);
  int iGod = Mes.GetYear();
  int iMes = Mes.GetMonth();

  sprintf(arg,"1,%d",mtek); R_DATA_EX(arg,str,20,0); Trim(str);
  string sMes = static_cast_to_string(str);  

  sprintf(str,"%s %d г.",sMes,iGod); FreeSpaceString(str,3,"");
  OemToChar(str,str);

  WriteToCell("D10",str);
  return 0;

}


Footer()      // печать подножия
{ 
 // char Ruk[len]; // GetEnterpriseVar("РУКПП",Ruk,len-1); // Руководитель // Trim(Ruk);
 // WriteToCell("V10",OemToAnsi(Ruk));

    for ( zap = 0; zap < cr; zap++ )   //цикл по записям таблицы
    {                                  //для вычисления итога
      rec_ins = CTabl.Flag_Action_1(zap);
      if (cr_ins) if (!rec_ins) continue; // если какие-то записи выделены, печатаем только их
      
      //Itog=Itog+static_cast_to_double(CTabl.Text(fld[idxSum],zap)); //CASHSUM
      Itog=Itog+static_cast_to_double(CTabl.TextS("ITRA",zap));
    }

  WriteToCell("G14",Itog);    //WriteToCell("E28",Itog);    //WriteToCell("G28",Itog);

  return 0;
}


DelHead()
{ // удаляем шапку
  for ( int i = 0; i < CntHead; i++ )
  {
    wsh.Rows(1).Delete();
    n--; // корректируем номер печатаемой строки
  }

  return 0;
}


DelFoot() 
{ // удаляем подножие
  for ( int i = 0; i < CntFoot; i++ )
    wsh.Rows(n).Delete();

  return 0;
}


int cwsh = 0; // число Worksheet'ов
int nlst = 0; // номер Worksheet'a в котором выполняется печать


NextWorksheet()
{ // переход на следующий Worksheet
  cwsh = wb.Worksheets.Count(); // количество Worksheet'ов
  wb.Worksheets(cwsh).Copy(wb.Worksheets(cwsh)); // создаем новый лист копированием шаблонного листа
  wsh = wb.ActiveSheet; // переменной wsh присваиваем ссылку на активный лист (тот который только что создали)
  nlst++;
  wsh.Name = OemToAnsi("л") + static_cast_to_string(nlst); // присваиваем имя листу

  // устанавливаем свойства страницы
  wsh.PageSetup.Zoom = false;
  wsh.PageSetup.FitToPagesTall = 1; // печатать не более одной страницы по высоте
  wsh.PageSetup.FitToPagesWide = 9; // печатать не более 9 страниц в ширину

  n = nStart; // устанавливаем номер печатаемой строки

  if ( nlst > 1 )
    DelHead(); // удаляем шапку

  return 0;
}



PrintTableToExcel()
{ // печать строки в Excel
  wsh.Rows(n).EntireRow.Insert();
  wsh.Rows(n-1).Select();
  xls.Selection.Copy(wsh.Rows(n));

  char c1[9], c2[9], c3[9], c4[9], c5[9], c6[9], c7[9];

  sprintf(c1,"A%d",n-1);   // № п/п       Order
  sprintf(c2,"B%d",n-1);   
  sprintf(c3,"C%d",n-1);   // № карты     FCBankKard  
  sprintf(c4,"D%d",n-1);   // FCf   
  sprintf(c5,"E%d",n-1);   // FCi     
  sprintf(c6,"F%d",n-1);   // FCo
  sprintf(c7,"G%d",n-1);   // Сумма       ITRA


  WriteToCell(c1,Trim(CTabl.TextS("Order",zap)));
  int npp=467;  WriteToCell(c2,npp);
  WriteToCell(c3,OemToAnsi(Trim(CTabl.TextS("P002",zap))));              //FCBankCard
  WriteToCell(c4,OemToAnsi(Trim(CTabl.TextS("NAM3",zap))));              //FCf
  WriteToCell(c5,OemToAnsi(Trim(CTabl.TextS("NAM1",zap))));              //FCi
  WriteToCell(c6,OemToAnsi(Trim(CTabl.TextS("NAM2",zap))));              //FCo
  WriteToCell(c7,OemToAnsi(Trim(CTabl.TextS("ITRA",zap))));

  alin++;
  lin++;
  n++;

  return 0;
}


int cr = 0,
    cfld = 0,
    cr_ins = 0,
    rec_ins = 0,
    rec_work = 0;

var CFile,    // объект класса для работы с текущим файлом печати
    CMsg = 0, // Процент выполненной работы
    CTabl;    // объект класса для работы таблицей  

int vp = 0; // 0-шапка, таблица и подножие на одном листе
            // 1-шапка и таблица на 1-м листе, таблица и подножие на 2-м листе
            // 2-шапка и таблица на 1-м листе, на 2-м и возможно далее только таблица, таблица и подножие на последнем листе

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

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

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

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

  if ( cr_ins ) rec_work = cr_ins;    // число записей которые должны быть обработаны
  else          rec_work = cr;

  tmpi = rec_work + CntHead + CntFoot;

  if ( tmpi > CntStr * 2 )
    vp = 2;

  if ( tmpi > CntStr && tmpi <= CntStr * 2 )
    vp = 1;

  if ( tmpi <= CntStr || rec_work <= 1 )
    vp = 0;

  return 0;
}



char Dir[len]; // Рабочий каталог амбы (обычно ZPL)
string nm;     // Имя Excel шаблона
var WorkDir,   // Рабочий каталог модуля
    xls,       // объект Excel.Application
    wb,        // объект workbook
    wsh;       // объект worksheet


SetupExcel()
{
  xls = CreateObject("Excel.Application");
  GetCurrentDirectory(len,Dir);
  nm = "tablbank\\novik_kbm.xlt";
  WorkDir = Dir + "\\";
  xls.Caption = OemToAnsi("Ведомость");
  xls.Workbooks.Add(WorkDir+nm);
  wb = xls.Workbooks(1);
  wsh = wb.Worksheets.Item(1);

  return 0;
}


Trim(&str)
{
  FreeSpaceString(str,3,""); 
  return static_cast_to_string(str);
}


WriteToCell(cel,s)
{
  wsh.Range(static_cast_to_string(cel)).Value = static_cast_to_string(s);
  return 0;
}



