//=================================================================== // Форма печати для свода по видам Н-У максимально приближенная // к той, которая была во внешних сводах (Excel) //=================================================================== int maxLenthLongNameNu=0; //длина максимальной строки названия НУ int nulSt1[256],nulSt2[256],nulSt3[256]; // Флаг для нулевых столбцов PrintSvodExcel(&Tabl,&ListTabl,&CountT,&MapPodr,&BreakPodr,&FirstMapPodrSize) //============================================================================== // Основная функция печати свода в Excel (аналог.текст) //============================================================================== { char Str[256],nnn[256]; string NameXlt = GetPathXLT("TABLSVD","extsvod.xlt"); tPrepereOfficeForWork(); // определяем работать на Excel или на Calc (определяем какой из офисов (MS Office или OpenOffice) установлен и какой предпочтительнее) tCreateXlsObjects(static_cast_to_string(NameXlt),"Свод по Н-У"); // создание основных объектов //tMakeXlsVisible(); int n_wsh = 1; tGetWshByIndex(1); // получаем ссылку на лист (worksheet) tWshSelect(); try { int ColStr = 1; int RowBegN = 0, RowEndN = 0, RowBegU = 0, RowEndU = 0, RowBegI = 0, RowEndI = 0; int cntPodr = MapPodr.Size(); int iPodr = 1; nList=1; for ( bool Cur=MapPodr.InitIterator(); Cur || !BreakPodr; Cur=MapPodr.Next(),++iPodr ) { ColStr = 1; // чтобы не было выделенний. tWshCellSelect(1,1); // копируем шаблон, название листа = фамилия + tn tCopyWshByIndex(n_wsh,"Лист"+static_cast_to_string(n_wsh)); tGetWshByIndex(n_wsh); n_wsh++; // увеличиваем счетчик листов tWshSelect(); long Podr = 0; if ( CountT ) ListTabl.SelectTable(0); // заголовок PrintHeaderFootExcel(ColStr,0); if (!BreakPodr) { bool Cur=MapPodr.InitIterator(); char DatTek[11], MCash[11],YCash[11]; R_SYS_DATA("6",DatTek,10,0); FreeSpaceString(DatTek,2," "); sprintf(nnn,"A%d", ColStr); ColStr++; tWriteStringToCell(nnn,DatTek); // пишем в ячейку tFontSizeCell(nnn,FontZag); if ( !Cur || MapPodr.Size()==FirstMapPodrSize ) { // общее название свода Str = Tabl.Heading(); OemToChar(Str,Str); sprintf(nnn,"A%d", ColStr); ColStr++; ColStr++; tWriteStringToCell(nnn,Str); // пишем в ячейку tFontSizeCell(nnn,FontZag); } else { R_SYS_DATA("8",MCash,10,0); R_SYS_DATA("9",YCash,10,0); sprintf(Str,"Свод за %02d.%04d по подразделениям:",atoi(MCash),atoi(YCash)); OemToChar(Str,Str); sprintf(nnn,"A%d", ColStr); ColStr++; tWriteStringToCell(nnn,Str); // пишем в ячейку tFontSizeCell(nnn,FontZag); for ( ; Cur; Cur=MapPodr.Next() ) { Str = MapPodr.GetCurValue(); OemToChar(Str,Str); sprintf(nnn,"A%d", ColStr); ColStr++; tWriteStringToCell(nnn,Str); // пишем в ячейку tFontSizeCell(nnn,FontZag); } ColStr++; } } else { char DatTek[11], MCash[11],YCash[11]; R_SYS_DATA("6",DatTek,10,0); FreeSpaceString(DatTek,2," "); sprintf(nnn,"A%d", ColStr); ColStr++; tWriteStringToCell(nnn,DatTek); // пишем в ячейку tFontSizeCell(nnn,FontZag); R_SYS_DATA("8",MCash,10,0); R_SYS_DATA("9",YCash,10,0); Podr=atol(MapPodr.GetCurKey()); sprintf(Str,"Свод за %02d.%04d по подразделению N%-s",atoi(MCash),atoi(YCash),MapPodr.GetCurValue()); OemToChar(Str,Str); sprintf(nnn,"A%d", ColStr); ColStr++; ColStr++; tWriteStringToCell(nnn,Str); // пишем в ячейку tFontSizeCell(nnn,FontZag); } int SavePrintDO = bPrintDO; int CFld1=0, CFld2 = 0, CFld3 = 0; if ( bPrintDO==2 ) FillArrayDO(); CFld1 = Tabl.Count_Fld(); InitArray(nulSt1,CFld1+1); RowBegN = ColStr + 1; // +1 - заголовок "начисления" PrintTablNExcel(Tabl,"Начисления",Podr,MapPodr,ColStr); RowEndN = ColStr - 1; bPrintDO = SavePrintDO; if ( CountT>1 ) { // Затем печатаются удержания ListTabl.SelectTable(1); CFld2 = Tabl.Count_Fld(); InitArray(nulSt2,CFld2+1); RowBegU = ColStr + 1; PrintTablUExcel(Tabl,"Удержания",Podr,MapPodr,ColStr); RowEndU = ColStr - 1; if( PrintLongNameNu==1 && maxLenthLongNameNu>7 ) { tColumnWidth2(idxStlbNameNu+1,maxLenthLongNameNu*0.8); } // Печатаем 3-ю таблицу только для последнего подразделения if ( bPrintItogTableLastPodr && BreakPodr && iPodr2 ) { ListTabl.SelectTable(2); CFld3 = Tabl.Count_Fld(); InitArray(nulSt3,CFld3+1); RowBegI = ColStr + 1; PrintTablRExcel(Tabl,"Итоги",Podr,MapPodr,ColStr); RowEndI = ColStr - 1; } } // подножие PrintHeaderFootExcel(ColStr,1); if ( PrNs ) // Если не печатать нулевые столбцы { int CFld = (CFld1>CFld2) ? CFld1 : CFld2 ; CFld = (CFld3>CFld ) ? CFld3 : CFld ; for ( int i = CFld+1; i>0 ;i-- ) { if ( nulSt1[i]==0 && nulSt2[i]==0 && nulSt3[i]==0 ) tDeleteColumns(i,1); else { if ( nulSt1[i]==0 ) tDeleteRange2(RowBegN,i,RowEndN,i,0); if ( nulSt2[i]==0 ) tDeleteRange2(RowBegU,i,RowEndU,i,0); if ( i>WItog && nulSt3[i]==0 ) tDeleteRange2(RowBegI,i,RowEndI,i,0); } } } if( Orient ) tWshOrientation(Orient); if ( !BreakPodr ) break; } // чтобы не было выделенной строки после всех манипуляций с копированием // выделим отдельную ячейку. tWshCellSelect(1,1); tGetWshByIndex(n_wsh); // получаем ссылку на лист (worksheet) tWshHide(); // делаем лист невидимым tGetWshByIndex(1); tWshSelect(); } catch(object err) { SayError(err); } catch(...) { SayUndefinedScriptError(); } tEndXlsWork(1); return 0; } PrintHeaderFootExcel(&ColStr,tip) //============================================================== // Печать заголовка (tip==0) и подножия (tip==1) //============================================================== { char nnn[256], str[256]; if( !tip && strlen(ListHeader)>0 ) str = ListHeader; else if( tip && strlen(ListFoot)>0 ) { str = ListFoot; ColStr++; } else return; sprintf(nnn,"A%d", ColStr); ColStr++; OemToChar(str,str); tWriteStringToCell(nnn,str); tFontSizeCell(nnn,FontZag); } PrintTablNExcel( &Tabl, &Heading, Podr, &MapPodr, &ColStr ) //============================================================== // Печать свода по начислениям // Внимание! В некоторых случаях производится модификация // таблицы (дополнительное объединение строк), поэтому // нельзя пользоваться методом Rewrite. //============================================================== { char Str[256], nnn[256]; if ( Tabl.Count_Fld()<2 ) return false; // Во внешних сводах была особенность: мнимые виды печатались первыми // Кроме того, виды выплаченные в других месяцах вообще печатались отдельным // разделом. Поэтому, первое, что мы сделаем - отсортируем записи в таблице. int CountR=Tabl.Count_Rcr(); // полное число записей if ( !CountR || (CountR==1 && Tabl.Check_Empty_Rcr(0)) ) return false; idxStlbNameNu=Tabl.Find_Name_Fld("Vid_nu"); // т.к. Tabl не создается заново, необходимо очищать флаги печати Tabl.InitFlagPrintFld("+",0); FillFld(Tabl,Podr!=0); if (Heading=="Начисления") FormatirXls(Tabl); // форматируем по таблице начислений // Если столбца с подразделением нет, то не зачем предпринимать дополнительные действия, // чтобы его не печатать. int tmpPodr = bPrintColPodr; if (fld[idxPodr]==-1) bPrintColPodr=true; // Если столбцов с кодом вида или с датой нет, то группировку по "Долгу организации" // не сделать if ( fld[idxKod]==-1 || fldData==-1 ) bPrintDO = 1; var MapKeyFld = CreateObject("MapLong"); var MapSumFld = CreateObject("MapLong"); var MapFond = CreateObject("MapString"); var MapItogSrc = CreateObject("MapString"); var MapItogObj = CreateObject("MapString"); bool bNeedMergeRcr = !Podr && !bPrintColPodr || fldData==-1 ; //если столбца дата нет, то не выделяем строки будущих месяцев ( помечены символом 'Б' в стобце FlagMnim) int cntF = Tabl.Count_Fld(); for ( int Fld=0; Fld1 && fld[idxSrc]!=-1 && MapSrc.Size()>1 ) FillMapItogSum(Tabl,Rcr,MapSumFld,MapItogSrc,Key,0); // заполняем итоги по объектам if ( sortObj>1 && fld[idxObj]!=-1 && MapObj.Size()>1 ) FillMapItogSum(Tabl,Rcr,MapSumFld,MapItogObj,Key,1); if ( IsPredSum(Key) ) { if ( !bPred ) { Str = "Суммы по некоторым видам, относящиеся к расчетному месяцу, но выданные в прошлых месяцах:"; OemToChar(Str,Str); sprintf(nnn,"A%d", ColStr); ColStr++; tWriteStringToCell(nnn,Str); // пишем в ячейку tFontSizeCell(nnn,FontZap); } bPred=true; } else if ( IsMnimSum(Key) ) { if ( !bMnim ) { if ( Heading=="Начисления" ) Str = "Суммы по мнимым видам (виды натуральной оплаты, материальной выгоды и т.п.):"; else Str = "Суммы по мнимым видам (Cтраховые взносы и т.п.):"; OemToChar(Str,Str); sprintf(nnn,"A%d", ColStr); ColStr++; tWriteStringToCell(nnn,Str); // пишем в ячейку tFontSizeCell(nnn,FontZap); } bMnim=true; } else if ( bMnim || bPred ) { tRowHeight(ColStr,8); ColStr++; bMnim=bPred=false; } if ( Heading=="Начисления" ) PrintRcrExcel(Tabl,0,Rcr,ColStr,0); else if ( Heading=="Удержания" ) PrintRcrExcel(Tabl,1,Rcr,ColStr,0); ColStr++; } Cur=Map.Next(); // Если напечатали все записи - печатаем итоги if ( !Cur ) { Tabl.Fill_Bottom_Text(); PrintRcrExcel(Tabl,0,"Итого",ColStr,2); ColStr++; if (NoZeroMnimItog(Tabl)) { PrintRcrExcel(Tabl,0,"Итого по мнимым видам",ColStr,3); ColStr++; PrintRcrExcel(Tabl,0,"Общий итог",ColStr,5); ColStr++; } } } PrintItogSumExcel(Tabl, MapItogObj, MapSumFld, ColStr, 1); PrintItogSumExcel(Tabl, MapItogSrc, MapSumFld, ColStr, 0); PrintItogSumFondExcel(Tabl, MapFond, MapSumFld, ColStr); // После того как напечатали таблицу необходимо сбросить // отметку напечатанных строк. for ( bool Cur=Map.InitIterator(); Cur; Cur=Map.Next() ) { long Rcr = Map.GetCurValue(); Tabl.Set_Ins_Record(Rcr,' '); } bPrintColPodr = tmpPodr; return true; } NoZeroMnimItog(&Tabl) { int CntFld = Tabl.Count_Fld(); for (int Fld=0; Fld0.001) return true; } return false; } CalcDelta940941(&Tabl,Fld) { double rez=0; for(int i=0;imaxLenthLongNameNu) maxLenthLongNameNu=strlen(Str); } } else if ( fl==1 ) { Str = DefineColumnName(Tabl,Fld); tRangeInteriorColor(ColStr,CFld,ColStr,CFld,14540253); } else if ( fl==2 ) { Str = Tabl.Get_Bottom_Text(Fld); tRangeInteriorColor(ColStr,CFld,ColStr,CFld,14540253); tRowFontBold(ColStr,true); } else if ( fl==3 ) { Str = Tabl.Get_Bottom_Text(Fld+CntFld); //nick>> if( nabs(atof(Str))>0.001)//сумма ненулевая { double delta=CalcDelta940941(Tabl,Fld);//получим сумму по видам 940 и 941 if(nabs(delta)>0.001) { //уменьшим итог на сумму delta Str=to_string(atof(Str)-delta); } } //<0.0001) ) { // флаг не нулевые столбцы if( STab==0 ) nulSt1[CFld] = 1; else if( STab==1 ) nulSt2[CFld] = 1; else if( STab==2 ) nulSt3[CFld] = 1; } } if ( WItog && STab==2 && CFld==1 ) { // для итоговой таблицы наименования могут занимать несколько ячеек CFld = WItog; tMergeCells2(ColStr,1,ColStr,WItog,1); } CFld++; } if ( bNull ) { // границы таблицы tBordersCell2(ColStr,1,ColStr,CFld-1,1,1,1,1,1); if ( fl==1 ) { // заголовки выравниваем по центру tHorizontalAlignment2(ColStr,1,ColStr,CFld-1,2); } if ( fl==2 || fl==3 || fl==4 || fl==5 || fl==6) { // печать наименования для строки Str = Rcr; OemToChar(Str,Str); if ((PrintLongNameNu!=1)&&( fl==2 || fl==3 )) tMergeCells2(ColStr,1,ColStr,2,1); //для итогов tWriteStringToCell2(ColStr,1,Str); tFontSizeCell2(ColStr,1,ColStr,1,FontZap); } } else { // ничего не напечатали ColStr--; } return true; } FormatirXls(&Tabl) { char Str[256], buf[256]; int CntFld = Tabl.Count_Fld(); int CFld = 1; int Width = 12; for (int Fld=0; Fld2 ) Width = 12; // если поле даты сместилось, то печатаем стандартным, иначе суммы в итогах не войдут tColumnWidth(CFld,Width); CFld++; } return true; } PrintTablUExcel( &Tabl, &Heading, Podr, &MapPodr, &ColStr ) //============================================================== // Печать свода по удержаниям //============================================================== { if ( Tabl.Count_Fld()<2 ) return false; ColStr++; return PrintTablNExcel( Tabl, Heading, Podr, MapPodr, ColStr ); } PrintTablRExcel( &Tabl, &Heading, Podr, &MapPodr, &ColStr ) //============================================================== // Печать прочей информации //============================================================== { idxStlbNameNu=-1; char Str[256], nnn[256]; if ( Tabl.Count_Fld()<2 ) return false; int CountR=Tabl.Count_Rcr(); // полное число записей if ( !CountR || (CountR==1 && Tabl.Check_Empty_Rcr(0)) ) return false; Tabl.InitFlagPrintFld("+",0); string NameF, NameS; int FldP = -1, FldS=-1; if ( Podr ) // нужна разбивка по подразделениям { char Str[21]; sprintf(Str,"Su__%-ld",Podr); FldP = Tabl.Find_Name_Fld(static_cast_to_string(Str)); if ( FldP!=-1 ) { NameF = DefineColumnName(Tabl,FldP); Tabl.SetName(FldP," По подразделению"); FldS = Tabl.Find_Name_Fld("Su_xop"); if ( FldS!=-1 ) { NameS=DefineColumnName(Tabl,FldS); Tabl.SetName(FldS," Всего "); } // уберем столбцы не относящиеся к нужному подразделению // начинаем с 1, т.к. в 0-ом - названия строчек for (int i=1; i