int TypeRV = 1; // Как печатать РВ: 1 - в днях, 2 - в часах int VidReestr = 0; // Вид реестра: 0 - все суммы вместе, 1 - только осн, // 2 - только оплата первых дв.дней, 3 - все, но раздельно int VidItog = 1; // вид итога: 0 - только РВ и суммы, 1 - кол-во б/л int PrintDopl = 0; // Доплата до среднего за счет организации: 0 - не печатать (вообще), // 1 - печатать (но в общей сумме), 2 - печатать с выделением в отдельный столбец int OptimizedPrint = 1; // Оптимизация печати (замедляет печать): // 0 - не оптимизировать, 1 - оптимизировать (не печатать пустые столбцы б/л) int PrintZeroDay = 1; // Настройка для вида реестра == 2 и == 1 // 0 - не печатать б/л, где РВ оказалось нулевым // 1 - печатать int AddDopl = 0; // Настройка для вида реестра == 2 (только оплата первых дней): // 0 - не печатать доплату до среднего для периодов оплачиваемых соц.страхом // 1 - печатать int PrintOnlyTotals = 0; // Печать только итогов, или всего реестра: // 0 - печатаем все, 1 - печатаем только итоги int PrSnils=0; //Печатать столбец со СНИЛС 0- не печатать, 1 - печатать int PrintComment = 0; // Печать столбца с пояснением к б/л // 0 - не печатать, 1 - печатать int PrintDatBL = 0; // Печать столбца с датами б/л // 0 - не печатать, 1 - печатать int PrintSerNum = 0; // Печать столбца с серией и номером // 0 - не печатать, 1 - печатать int PrintStrStag = 0; // Печатать столбец со стажем на дату начала больничного // 0 - не печатать, 1 - печатать int TypeHour2Day = 0; // Перевод часов в дни: 1 - по табелю, 0 - часы/8 int PrintVm = 3; // Печать по видам дохода: 0 - сделать запрос // 1 - основной доход, 2 - вмененный, 3 - все вместе int TypePrVm = 1; // Как печатать вм.доход (если PrintVm=3): // 0 - "склеить" с основным доходом, 1 - отдельными // строками int ReestBLmind = 1; // Печать реестра для б/л по уходу 1 - печать, 0 - нет int PrExcel = 1; // 1 - текстовая форма, 2 - Excel int PrDopBL = 1; // Печать доп.БЛ из ЛС ( до 1.5 лет, дети-инвалиды, // един.пособие при рождении, ранние сроки берем.) int PrPilotFSS = GetCommonCnfInt("_PrPilot","reestrBL"); // Печатать больничные из пилотного проекта ПВСО или нет. int idxDopBL_Pos15 = 0, // по уходу за детьми до 1.5 лет idxDopBL_inv = 1, // по уходу за детьми-инвалидами idxDopBL_rog = 2, // пособие при рождении idxDopBL_ber = 3, // ранние сроки беременности idxDopBL_poh = 4, // пособия на похороны idxDopBL_SanKur= 5, // Санаторно-курортные MaxTypeDopBL = 6; // количество дополнительных "пособий" выбираемых не из "сохраненных" // больничных, а из отдельных видов Н-У (1.5 лет, един.пособие при рождении и т.п.) int BLFilter = 0; // 0x01 - с нарушением режима int ExtendedBlFirst=11; // тип для первого "доп.вида" пособия (которые не рассчитываются через расчет больничных) int ExtendedBlCount=4; // количество таких видов пособий int cntTypeBL = 11+ExtendedBlCount, // кол-во типов б/л + уход за ребенком до 1,5 лет // + уход за детьми-инвалидами // + един.пособие при рождении // + ранние сроки берем. // + пособие на погребение cntColBL = 9+ExtendedBlCount, // кол-во "столбцов" б/л WDatBL =10, // ширина столбца с датами Б/Л WSerNum =12, // ширина столбца с серией и номером WStrStag = 9, // ширина столбца со стажем WComm = 8, // ширина столбца с комментарием WRv = 6, // ширина столбца для РВ ARvH = 0, // точность для РВ в часах ARvD = 0, // точность для РВ в днях WSum =10; // ширина столбца для Суммы char DolgPodp[256], FioPodp[256]; // должность и ФИО подписанта NastrOrderCol() //=============================================================================== // Определяем группировку б/л по столбцам // а также заголовки для этих столбцов //=============================================================================== { TypeBLOrder[0] = 0; // обычный б/л TypeBLOrder[1] = 4; // По берем. и родам TypeBLOrder[2] = 2; // Травма TypeBLOrder[3] = 0; // Бытовая травма TypeBLOrder[4] = 1; // по уходу TypeBLOrder[5] = 0; // прерыв.берем. TypeBLOrder[6] = 3; // профессиональное заболевание TypeBLOrder[7] = 5; // Уход до 1.5 лет TypeBLOrder[8] = 6; // карантин TypeBLOrder[9] = 7; // санаторно-курортные TypeBLOrder[10]= 8; // протезирование TypeBLOrder[11]= 9; // Уход за детьми-инвалидами TypeBLOrder[12]= 10; // При рождение TypeBLOrder[13]= 11; // Ранние сроки беременности TypeBLOrder[14]= 12; // пособие на погребение HeadingBL[0] = "Общее заболевание"; HeadingBL[1] = "По уходу"; HeadingBL[2] = "Травма"; HeadingBL[3] = "Проф.заболевание"; HeadingBL[4] = "По берем. и родам"; HeadingBL[5] = "Уход до 1.5 лет"; HeadingBL[6] = "Карантин"; HeadingBL[7] = "Санат.курортные"; HeadingBL[8] = "Протезирование"; HeadingBL[9] = "Дети-инвалиды"; HeadingBL[10] = "При рождении"; HeadingBL[11]= "Ран.сроки берем"; HeadingBL[12]= "Пособие на погребение"; // HeadingBL[4] = "Прерыв.берем."; } PrintReestrBL(VidR,VidI,tRV,PrintD,OptPr,PrZeroD,AddD,OnlyTotals,PrComment,PrDat,PrSerN,H2D,PrVm,TPrVm) { var array_param[17]; array_param[0] = 16; //колличество параметров array_param[1] = VidR; array_param[2] = VidI; array_param[3] = tRV; array_param[4] = PrintD; array_param[5] = OptPr; array_param[6] = PrZeroD; array_param[7] = AddD; array_param[8] = OnlyTotals; array_param[9] = PrComment; array_param[10] = PrDat; array_param[11] = PrSerN; array_param[12] = H2D; array_param[13] = PrVm; array_param[14] = TPrVm; array_param[15] = PrExcel;// Глобальная array_param[16] = PrDopBL;// Глобальная PrReestrBL(array_param); return 0; } PrReestrBL(array_param) //=============================================================================== // основная функция печати //=============================================================================== { if ( ChoiceVidBL()==ESC ) return false; CTabl = CreateObject("CurPrnTbl"); CFile=CreateObject("CurPrnFile"); int cntRcr = CTabl.Count_Rcr(); if ( !cntRcr || (cntRcr==1 && CTabl.Check_Empty_Rcr(0)) ) return false; // Находим номера столбцов с датами начала б/л и с табельным номером. fBl = CTabl.Find_Name_Fld("LIST_BL"); fTn = CTabl.Find_Name_Fld("C_FIO"); if (fTn==-1 ) return false; // В глобальные переменные переносим переданные параметры, влияющие // на вид реестра int cntParam = array_param[0]; VidReestr = array_param[1]; VidItog = array_param[2]; TypeRV = array_param[3]; PrintDopl = array_param[4]; if ( VidReestr==1 ) PrintDopl=0; OptimizedPrint = array_param[5]; PrintZeroDay = array_param[6]; if ( VidReestr!=2 && VidReestr!=1 ) PrintZeroDay=1; AddDopl = array_param[7]; if ( VidReestr!=2 ) AddDopl=0; PrintOnlyTotals= array_param[8]; PrintComment = array_param[9]; PrintDatBL = array_param[10]; PrintSerNum = array_param[11]; TypeHour2Day = array_param[12]; PrintVm = array_param[13]; TypePrVm = array_param[14]; PrExcel = array_param[15]; //if ( PrExcel==1 || PrExcel==2 ) PrExcel--; PrDopBL = array_param[16]; PrintStrStag = GetCommonCnfInt("_PrStag","reestrBL"); if ( cntParam>16 ) RvMainSrc = array_param[17]; if ( cntParam>17 ) BLFilter = array_param[18]; if ( cntParam>18 ) CountRowList =atoi(array_param[19]); if ( cntParam>19 ) PrSnils =atoi(array_param[20]); DolgPodp = ""; FioPodp = ""; if ( cntParam>20 ) { DolgPodp = array_param[21]; FreeSpaceString(DolgPodp,3,""); FioPodp = array_param[22]; FreeSpaceString(FioPodp,3,""); } if ( RvMainSrc ) CntSrc = CountSource(); if ( CntSrc < 2 ) RvMainSrc = 0; // если источник один то данная настройка не нужна // Кол-во строк для итогов на странице NeedRowBottomPage = 5; if ( VidReestr==3 ) NeedRowBottomPage *= 2; // Настройка "внешнего вида" таблицы NastrSimvTabl(); // Настройка порядка и заголовков столбцов с б/л NastrOrderCol(); // Тип выборки (по мес.прин. или мес.нач.), а также месяц начала // и месяц окончания выборки определяем один раз по первой строке таблицы Type = TypeFull = atoi(CTabl.TextS("TYPE",0)); if ( Type & 0x02 ) Type &= ~0x02; MBeg = CTabl.TextS("MONTH_B",0); MEnd = CTabl.TextS("MONTH_E",0); // Определим какие столбцы б/л будем печатать (для этого нужны MBeg,MEnd) FillFlagPrintCol(); // Определяем какие столбцы таблицы и в каком порядке д.б. // напечатаны (кроме сумм по б/л) PrintedFld = CreateObject("MapLong"); FillPrintedFld(); // заводим переменную, которая будет показывать процент выполнения (ProgressBar) var CMsg = CreateObject("ProgressBar"); CMsg.Initial(0,100,5); CMsg.SetShowTime(static_cast_to_int(0)); // массивы для хранения итоговых сумм и РВ по листу и по ведомости double arItogP[cntColBL]; double arItogDP[cntColBL]; double arItogRP[cntColBL]; double arItogPO[cntColBL]; double arItogDPO[cntColBL]; double arItogRPO[cntColBL]; // массивы для хранения итоговых сумм и РВ по листу и по ведомости double arItogPvm[cntColBL]; // для вмененки double arItogDPvm[cntColBL]; double arItogRPvm[cntColBL]; double arItogPOvm[cntColBL]; double arItogDPOvm[cntColBL]; double arItogRPOvm[cntColBL]; ClearItogBL(arItogP); ClearItogBL(arItogRP); ClearItogBL(arItogPO); ClearItogBL(arItogRPO); ClearItogBL(arItogDP); ClearItogBL(arItogDPO); ClearItogBL(arItogPvm); // почистили для вмененки ClearItogBL(arItogRPvm); ClearItogBL(arItogPOvm); ClearItogBL(arItogRPOvm); ClearItogBL(arItogDPvm); ClearItogBL(arItogDPOvm); // Не забываем почистить глобальные массивы итогов по ведомости ClearItogBL(arItog); ClearItogBL(arItogD); ClearItogBL(arItogR); ClearItogBL(arItogO); ClearItogBL(arItogDO); ClearItogBL(arItogRO); ClearItogBL(arItogvm); ClearItogBL(arItogDvm); ClearItogBL(arItogRvm); ClearItogBL(arItogOvm); ClearItogBL(arItogDOvm); ClearItogBL(arItogROvm); // массивы для хранения кол-ва б/л по листу и по ведомости int arCntBLP[cntColBL],arCntBLP1[cntColBL]; ClearItogBL(arCntBLP); ClearItogBL(arCntBLP1); ClearItogBL(arCntBL); ClearItogBL(arCntBL1); // Номер страницы (кол-во страниц) Page = 0; NumOrder = 0; if ( PrExcel ) { CreateXLTforBL(); PrExcelTitleVed(); PrExcelTitlePage(); } try { // Идем по всем записям таблицы for ( int Rcr=0; RcrCFile.GetSizePage() && !PrExcel ) { PrintBottomU(); CFile.ListFeed(); Buf =""; i=0; print(Buf); PrintHeadU(); } i++; int KodChS = mapPer.GetCurKey(); string NameChS = KodChS; string DateBegBL = mapBL.GetValue(static_cast_to_string(KodChS)); if ( ListKin.Find(KodChS) ) { var Kin = ListKin.GetCurKin(); char Buf[256]; string FIO = Kin.GetF(); Buf = Kin.GetI(); Buf[1]=0; FIO += " "+Buf+"."; Buf = Kin.GetO(); Buf[1]=0; FIO += Buf+"."; int year,month,day; CalculateStag(Kin.GetBirthDay(),DatEndPer,year,month,day,0,""); char ys[10]; ys=""; if ( year<200 ) { int ed = year%10; int des = year%100; string god = (ed==1)?"год":"года"; sprintf(ys,"%-3d %s",year,(ed>0 && ed<5 && (des<10 || des>20))?god:"лет"); } sprintf(Buf,"%-.17s,%-.8s,%-.8s",FIO,Kin.GetNameKind(),ys); FreeSpaceString(Buf,2,""); NameChS = Buf; } long DnAll = mapPer.GetCurValue(); int CalDn = DnAll/1000; int Dn = DnAll%1000; int OffsYear = YearEnd-YearBeg; int TotalCountDay = 0; double TotalCountPaydRv = 0.; while ( OffsYear>=0 ) { int Year = YearEnd-OffsYear; sprintf(DateBegCalc,"01.01.%4d",Year); if ( Year!=YearEnd ) sprintf(DateEndCalc,"01.01.%4d",Year+1); else { // Функция CountPaidDayBL исключает при подсчета дату конца, поэтому // надо указать дату на 1 больше конца периода var Month = CreateObject("KMonth"); Month.SetMonth(MonthEndPer.GetAbs()+1); sprintf(DateEndCalc,"01.%7.7s",Month.GetStr()); } double PaydRv; // int YearCountDay = CountPaidDayBL(DateBegCalc,DateEndCalc,DateBegBL,1,PaydRv,Type,-1); // здесь сделал выборку дней по месяцу принадлежности!!! Основной смысл этой функции // для данной таблицы: получить информацию сколько дней данного периода/года оплачено, // а не сколько в данном периоде/году оплачено дней за любые другие периоды/годы! int YearCountDay = CountPaidDayBL(DateBegCalc,DateEndCalc,DateBegBL,1,PaydRv,0,-1); TotalCountDay += YearCountDay; TotalCountPaydRv += PaydRv; char ycd[256]; if ( YearBeg!=YearEnd ) sprintf(ycd,"%4d: %-3d/%-3d",Year,YearCountDay,static_cast_to_int(PaydRv)); else sprintf(ycd,"%-3d/%-3d",YearCountDay,static_cast_to_int(PaydRv)); if ( Year!=YearBeg ) { if ( YearCountDay ) { sprintf(s," │ │ │ %-32.32s│%13.13s дн.│ │"," ",ycd); if ( !PrExcel ) print(s); else PrRowMind(s); } if ( Year==YearEnd ) { sprintf(ycd,"Всего %-3d/%-3d",TotalCountDay,static_cast_to_int(TotalCountPaydRv)); sprintf(s," │ │ │ %-32.32s│%13.13s дн.│ │"," ",ycd); if ( !PrExcel ) print(s); else PrRowMind(s); } } else { if ( i==1 ) { if (!PrExcel) { sprintf(s," ├─────┼────────────────────┼─────────────────────────────────┼─────────────────┼────────────┤"); print(s); } sprintf(s," │%5d│%-20.20s│ %-32.32s│%13.13s дн.│ %-3d/%-3d дн.│",Tn,FIO,NameChS,ycd,CalDn,Dn); //print(s); if ( !PrExcel ) print(s); else PrRowMind(s); } else { sprintf(s," │ │ │ %-32.32s│%13.13s дн.│ %-3d/%-3d дн.│",NameChS,ycd,CalDn,Dn); //print(s); if ( !PrExcel ) print(s); else PrRowMind(s); } } OffsYear--; } } } if ( !PrExcel ) { PrintBottomU(); print(""); } else { DelRowItog(2); PrintItStr(""); } PrintPodpBL(); return; } FamilyMembersInfo_Fill(DatB,mapPer,mapBL) { int Dn = atoi(GetRvBL(DatB,-1,false)); if ( !Dn ) Dn = atoi(GetRvBL(DatB,-1,true)); var DatBBl=KDateFromStr(DatB); var DatEBl=KDateFromStr(to_string(GetInfoBL(DatB,"ДАТАК"))); long CalDn = 0; if ( Type ) // по начислению CalDn = DatEBl.Diff(DatBBl)+1; else // выборка по принадлежности { if ( DatBBl.GT(DatEndPer) || DatEBl.LT(DatBegPer) ) CalDn=0; else { if ( DatBBl.LT(DatBegPer) ) DatBBl.SetDate(DatBegPer.GetStr()); if ( DatEBl.GT(DatEndPer) ) DatEBl.SetDate(DatEndPer.GetStr()); CalDn = DatEBl.Diff(DatBBl)+1; } } var familyMemberCodes = SplitStr(GetInfoBL(DatB,"ЧЛСЕМ"),","); int familyMemberCount= GetUBound(familyMemberCodes)+1; for(int i=0;i1 ) PrintItog("Итого по листу ",arItogP,arItogRP,arItogDP,arItogPO,arItogRPO,arItogDPO, arItogPvm,arItogRPvm,arItogDPvm,arItogPOvm,arItogRPOvm,arItogDPOvm, arCntBLP,arCntBLP1); ClearItogP(arItogP,arItogRP,arItogDP,arItogPO,arItogRPO,arItogDPO, arItogPvm,arItogRPvm,arItogDPvm,arItogPOvm,arItogRPOvm,arItogDPOvm, arCntBLP,arCntBLP1); // Итого по ведомости PrintItog("Итого ",arItog,arItogR,arItogD,arItogO,arItogRO,arItogDO, arItogvm,arItogRvm,arItogDvm,arItogOvm,arItogROvm,arItogDOvm, arCntBL,arCntBL1); if ( !PrExcel ) { PrintLineTabl(3); print(""); } else DelRowItog(2); } if ( PrExcel ) { DelRowItog(8); PrintItStr(""); } // Определяем итоговые суммы по всем б/л сразу и печатаем double It = 0., ItR=0., ItO=0., ItRO=0., ItD=0., ItDO=0.; double ItVm = 0., ItRVm=0., ItOVm=0., ItROVm=0., ItDVm=0., ItDOVm=0.; int cntBL = 0,cntBL1 = 0; for ( int i=0; i=cntColBL ) continue; // Если б/л в днях, переведем время в часы и наоборот, // в зависимости от того, что нам надо выводить на печать if ( TypR!=TypeRV ) { if ( TypeRV==1 ) { Hour2Day(ORv,PRv,DatB,DnPred); } else { ORv *= 8; PRv *= 8; } } } // Если только начали печатать - выводим заголовок ведомости if ( !Page ) { if ( !PrExcel ) { PrintTitleVed(); PrintTitlePage(); } else { // PrExcelTitleVed(); // PrExcelTitlePage(); } } // Если осталось мало строк на листе - подводим итог страницы // (б/л не разбиваем на две страницы!) if ( (bFirst || bFirstVm) && ( ( !PrExcel && IsEndPage(NeedRowBottomPage) ) || ( PrExcel && IsEndPageExcel(NeedRowBottomPage) ) ) ) { // подводим итог для страницы PrintBottomPage(arItogP,arItogRP,arItogDP,arItogPO,arItogRPO,arItogDPO, arItogPvm,arItogRPvm,arItogDPvm,arItogPOvm,arItogRPOvm,arItogDPOvm, arCntBLP,arCntBLP1); // подсуммирование и очистка сумм и РВ по странице ClearItogP(arItogP,arItogRP,arItogDP,arItogPO,arItogRPO,arItogDPO, arItogPvm,arItogRPvm,arItogDPvm,arItogPOvm,arItogRPOvm,arItogDPOvm, arCntBLP,arCntBLP1); // начинаем новую страницу if ( !PrExcel ) PrintTitlePage(); else PrExcelTitlePage(); } // если печатаем только вмененку, то начинаем с третьей строки if ( PrintVm==2 && bFirst ) { Row = Row+1; bDel = true; continue; } // если печатаем только основной, то только две строки if ( PrintVm==1 && bFirstVm ) { Row = Row+1; continue; } // если нет вмененки, тогда последние две строки не нужны if ( (bFirstVm || bSecondVm) && !OSumVm && !PSumVm ) { continue;// выходим } // если есть только вмененка, тогда первые две строки не нужны if ( (bFirst || bSecond) && !OSum && !PSum ) { bDel= true; continue;// выходим } // Если печатаем и вмененку и основной доход, причем не раздельно // (соц.стр. и орган), то вторую и четвертую строку печатать нужно // только если нужно напечать даты или серию-номер б/л if ( PrintVm==3 && VidReestr!=3 ) { if ( bSecond && !(( PrintDatBL||PrintSerNum||PrintStrStag )&&!OSumVm )) continue; if ( bSecondVm && !(( PrintDatBL||PrintSerNum||PrintStrStag )&&(bDopPr<2)) ) continue; } // условие для того чтобы лишние пустые строки не печатались if ( (bSecond||bSecondVm) && // если строка 2 или 4 !( PrintDatBL||PrintSerNum||PrintStrStag ) && // если не печатаем даты и серию-номер б/л PrintVm!=3 && // печатаем либо основной доход, либо вмененный VidReestr!=3 // печатаем либо все вместе, либо только соц.стр, // либо только организ. ) continue; // в этом случае 2 или 4 строки пустые не печатаем их // подвести итоги выше в аналогичном if нельзя, т.к. в этом случае // неверно напечатаются итоги по листу, если будет переход на следующий лист if ( !bFlag ) // считаем итоги только один раз { // Не забываем про подсуммирование к итогам (но делаем это только один раз) double SSum = OSum - PSum; double SRv = ORv - PRv; double SSumD = OSumD - PSumD; double SSumVm = OSumVm - PSumVm; double SRvVm = ORvVm - PRvVm; double SSumDVm = OSumDVm - PSumDVm; if ( VidReestr!=2 ) { arItogP [OrderBl] += SSum; arItogRP[OrderBl] += SRv; arItogPvm [OrderBl] += SSumVm; arItogRPvm[OrderBl] += SRvVm; } if ( VidReestr!=0 && DnPred>0 ) { arItogPO [OrderBl] += PSum; arItogRPO[OrderBl] += PRv; } if ( VidReestr!=0 && DnPredVm>0 ) { arItogPOvm [OrderBl] += PSumVm; arItogRPOvm[OrderBl] += PRvVm; } if ( PrintDopl ) { arItogDP[OrderBl] += SSumD; arItogDPO[OrderBl] += PSumD; arItogDPvm[OrderBl] += SSumDVm; arItogDPOvm[OrderBl] += PSumDVm; } // увеличиваем счетчик данного типа б/л (делаем это для всех или // только для первичных б/л (причем если месяц расчета попал в период // выборки, т.е. чистые пересчеты не учитываем) //если вмененка то кол-во бл увеличиваем, только в случае когда //печатается только вмененка // удаленные б/л не считаем if ( !bDeletedBL && ((!bFirstVm && !bSecondVm)||(bDel)) ) { arCntBLP[OrderBl]++; if ( !bExistParentBL && !bRecalcBL ) arCntBLP1[OrderBl]++; } } // сначала у нас идут информационные столбцы из таблицы if ( PrintOnlyTotals ) { if ( !bFlag ) bFlag = true; // проход не первый, для того чтобы один раз подсчитать итоги sprintf(Buf,"%*.*s",CountCharInfoCol,CountCharInfoCol," "); } else if ( !PrExcel ) { int RowD; for ( bool Cur=PrintedFld.InitIterator(); Cur; Cur=PrintedFld.Next() ) { long Fld = PrintedFld.GetCurValue(); int WN = CTabl.Width_Name(Fld)/3, // делится на 3,т.к. у таблиц высота шапки 3 строки W = CTabl.Width_Fld(Fld); string Value = CTabl.Text(Fld,Rcr); // Для столбца с "номером по порядку" делаем свой учет, т.к. возможна печать // выделенных записей, тогда значениями в столбце "номер по порядку" пользоваться нельзя if ( Fld==fOrder ) { sprintf(Buf1,"%*ld",W,NumOrder); Value = Buf1; } RazbW.IInitialW(Value,WN,20," ,.;"); // Если вдруг оказалось что для информационного столбца требуется // больше строк для печати, чем было отведено для ЛС, то корректируем // кол-во строк для печати (но делаем это только при первом проходе) if ( !bFlag && RazbW.Count()>CountRowForLS ) CountRowForLS = RazbW.Count(); if ( !bFlag ) { bFlag = true; // проход не первый, для того чтобы один раз // для б/л печатать ТН и ФИО if ( bDel ) RowD = Row; } if ( !Row && RazbW.Count()>CountRowForLS ) CountRowForLS = RazbW.Count(); if ( bDel&& !bPrinted ) { // в случае вмененки нужно тоже напечатать 1-ую строку if ( Row-RowD=cnt && !CntDopTotal ) // Если все б/л напечатаны { if ( PrintDatBL ) { sprintf(Buf1,"%-*.*s",WDatBL,WDatBL," "); Buf += Buf1+VertLine; } if ( PrintSerNum ) { // Если б/л для печати нет печатаем пустой столбец "серия" sprintf(Buf1,"%-*.*s",WSerNum,WSerNum," "); Buf += Buf1+VertLine; } if ( PrintStrStag ) { // Если б/л для печати нет печатаем пустой столбец "стажа" sprintf(Buf1,"%-*.*s",WStrStag,WStrStag," "); Buf += Buf1+VertLine; } if ( PrintComment ) { sprintf(Buf1,"%-*.*s",WComm,WComm," "); Buf += Buf1+VertLine; } } else { // Дата начала б/л string DatB = Razb.Get(i); if ( bDopPr<2 ) { if ( PrintDatBL ) { string Dat = DatB; if( i>=cnt ) Dat = GetValueArrRez(jj,tip,0); if (bDopPr==1) { if( i>=cnt ) Dat = GetValueArrRez(jj,tip,1); else Dat = GetInfoBL(DatB,"ДАТАК"); } sprintf(Buf1,"%-*.*s",WDatBL,WDatBL,Dat); Buf += Buf1+VertLine; infBLforExcel.Add("DatBL",Dat); } if ( PrintSerNum ) { string SerN=""; // Если печатаем первую строку, то определяем серию, тип б/л // тип РВ, кол-во дней за счет предприятия а также общее РВ и общая сумма. // Если же это уже вторая строка, то определяется только серия или доп.информация if ( bDopPr==0 ) SerN = GetInfoBL(DatB,"НОМЕР"); else { // В современных больничных серий уже нет // поэтому выведем сюда дополнительную информацию Пилот/ЭЛН SerN = GetInfoBL(DatB,"СЕРИЯ"); if ( !Str_Cmp(SerN," "," ") ) { if ( bELN ) SerN += "ЭЛН"; if ( bPilotFSS ) { if ( SerN!="" ) SerN += ", "; SerN += "ПВСО"; } } } sprintf(Buf1,"%-*.*s",WSerNum,WSerNum,SerN); Buf += Buf1+VertLine; infBLforExcel.Add("SerNum",SerN); } if ( PrintStrStag ) { char strStag[256]; strStag = ""; if ( !bDopPr ) { // Страховой стаж выводим только для первой строки БЛ var blInfo = CreateObject("KInfoBL"); blInfo.Initial(static_cast_to_string(DatB)); //дата начала БЛ не указана -> печатаем "доп. пособия" if (Str_Cmp(DatB," ",". ")==0 && Str_Cmp(infBLforExcel.GetValue("DatBL"),""," .0")!=0) blInfo.Initial(static_cast_to_string(infBLforExcel.GetValue("DatBL"))); int Year = atoi(blInfo.GetStrParametrs("СТАЖ_Г")); int Month = atoi(blInfo.GetStrParametrs("СТАЖ_М")); sprintf(strStag,"%3d%c.%2dм.",Year,(Year && Year<5)?'г':'л',Month); FreeSpaceString(strStag,5,""); } sprintf(Buf1,"%*.*s",WStrStag,WStrStag,strStag); Buf += Buf1+VertLine; infBLforExcel.Add("StrStag",static_cast_to_string(strStag)); } bDopPr++; } else { if ( PrintDatBL ) { sprintf(Buf1,"%-*.*s",WDatBL,WDatBL," "); Buf += Buf1+VertLine; } if ( PrintSerNum ) { // Если б/л для печати нет печатаем пустой столбец "серия" sprintf(Buf1,"%-*.*s",WSerNum,WSerNum," "); Buf += Buf1+VertLine; } if ( PrintStrStag ) { sprintf(Buf1,"%-*.*s",WStrStag,WStrStag," "); Buf += Buf1+VertLine; } } if ( PrintComment ) { string Comm=" "; if ( bFirst ) { if ( bNRegim ) Comm = DatReg; if ( bRecalcBL ) Comm = "пересчет"; if ( bExistParentBL ) Comm = "продолж."; if ( i>=cnt && fl15 ) { Comm = GetValueArrRez(jj,tip,2)+"ребенок"; fl15 = false; } } else if ( bSecond ) { if ( bNRegim ) Comm = "дат.нар."; } else if ( bFirstVm || bSecondVm ) { if ( bFirstVm ) { if ( i>=cnt && fl15 ) { Comm = GetValueArrRez(jj,tip,2)+" реб вм"; fl15 = false; } else { if ( VidReestr!=3 ) Comm = "вмененка"; else Comm = "вм(орг)"; } } else if ( VidReestr==3 ) Comm = "вм(соц)"; } sprintf(Buf1,"%-*.*s",WComm,WComm,Comm); Buf += Buf1+VertLine; infBLforExcel.Add("Comm",Comm); } // Если печатаем соц.страх и организац. отдельно, // то надо определять сумму и РВ за счет организации double Rv = 0., Sum = 0., SumD = 0.; if ( bSecond||bSecondVm ) { // Во второй строке суммы печатаются только если печатаем предпр.и соц.страх // раздельно в одном реестре if ( VidReestr==3 && bSecond && PrintVm!=2 && TypePrVm ) { Rv = ORv - PRv, Sum = OSum-PSum; SumD = OSumD - PSumD; } // Вмененка, в четвертой строке, суммы соц.страха if ( PrintVm!=1 && bSecondVm && VidReestr==3 && TypePrVm) { Rv = ORvVm - PRvVm; Sum = OSumVm - PSumVm; SumD = OSumDVm - PSumDVm; } // Если печатаем ТОЛЬКО оплату за счет предприятия // то во второй строке выведем доплату до среднего // Если она печатается if ( VidReestr==2 && PrintDopl && AddDopl && OSumD ) { // Если доплата до среднего не в отдельном столбце, то // ее надо поместить в тот же столбец где сумма с учетом // ограничения среднего if (PrintDopl==1) Sum = OSumD - PSumD; else SumD = OSumD - PSumD; } if ( VidReestr==2 && PrintDopl && AddDopl && OSumDVm ) { // Если доплата до среднего не в отдельном столбце, то // ее надо поместить в тот же столбец где сумма с учетом // ограничения среднего if (PrintDopl==1) Sum = OSumDVm - PSumDVm; else SumD = OSumDVm - PSumDVm; } } else { switch ( VidReestr ) { case 1: // печатаем только соц.страх if ( bFirst && PrintVm!=2 && TypePrVm ) { Rv = ORv - PRv; Sum = OSum - PSum; SumD = OSumD - PSumD; } if ( bFirstVm && PrintVm!=1 && TypePrVm ) // печатаем вмененку (отдельно) { Rv = ORvVm - PRvVm; Sum = OSumVm - PSumVm; SumD = OSumDVm - PSumDVm; } break; case 3: // печатаем все вместе (но в разных строках) case 2: // печатаем только организ. if ( bFirst && PrintVm!=2 && TypePrVm ) { Rv = PRv, Sum = PSum; SumD = PSumD; } if ( bFirstVm && PrintVm!=1 && TypePrVm) // печатаем вмененку (раздельно) { Rv = PRvVm, Sum = PSumVm; SumD = PSumDVm; if ( VidReestr==2 && PrintDopl && AddDopl && OSumDVm && DnPredVm==0 ) { // Если доплата до среднего не в отдельном столбце, то // ее надо поместить в тот же столбец где сумма с учетом // ограничения среднего if (PrintDopl==1) Sum = OSumDVm - PSumDVm; else SumD = OSumDVm - PSumDVm; } } break; case 0: // печатаем все вместе default: if ( bFirst && PrintVm!=2 && TypePrVm ) { Rv = ORv, Sum = OSum; SumD = OSumD; } if ( bFirstVm && PrintVm!=1 && TypePrVm) // печатаем вмененку (раздельно) { Rv = ORvVm, Sum = OSumVm; SumD = OSumDVm; } break; } } // Если РВ или сумма не нулевые, то печатаем их. if ( Rv || Sum ) { char StrRv[21],StrSum[21]; int A = ARvD; // кол-во знаков после запятой для РВ string tr = "дн."; // в случае часов, делаем 2 знака после запятой. if ( TypeRV!=1 ) { A = ARvH; tr = "ч."; } if ( !Rv ) StrRv = " "; else { sprintf(StrRv,"%*.*f %s",WRv,A,Rv,tr); FreeSpaceString(StrRv,2," "); } if ( Sum ) sprintf(StrSum,"%10.2f",Sum); else StrSum = " "; // формируем строку по б/л sprintf(Buf1,"%*.*s%c%*.*s%c",WRv,WRv,StrRv,VertLine[0],WSum,WSum,StrSum,VertLine[0]); StrSumRv[OrderBl]=Buf1; StrSumRvEx[OrderBl] = StrRv+"/"+StrSum+"/"; } // доплата выделяется в отдельный столбец if ( PrintDopl==2 ) { char StrSum[21]; // Если сумму и РВ не печатали (т.к. пустые. Такое м.б. Если печатаем // реестр по суммам за счет предприятия и есть доплата до среднего для // периодов оплачиваемых соц.страхом), то печатаем пустые столбцы с РВ и суммой if ( !Rv && !Sum ) { sprintf(Buf1,"%*.*s%c%*.*s%c",WRv,WRv," ",VertLine[0],WSum,WSum," ",VertLine[0]); StrSumRv[OrderBl] = Buf1; } if ( SumD ) sprintf(StrSum,"%10.2f",SumD); else StrSum = " "; sprintf(Buf1,"%*.*s%c",WSum,WSum,StrSum,VertLine[0]); StrSumRv[OrderBl] += Buf1; StrSumRvEx[OrderBl] += StrSum; } } if ( !PrExcel ) { // Выводим "строки" по всем типам б/л в строку для печати for ( int ii=0; ii=cntTypeBL || VidBL<0 ) VidBL=0; TypR = atoi(GetInfoBL(DatB,"ТИПРВ")); DnPred = atoi(GetInfoBL(DatB,"ДНПРЕД")); cntPer = atoi(GetInfoBL(DatB,"КПЕР0")); cntPerVm = atoi(GetInfoBL(DatB,"КПЕР1")); DnPredVm = atoi(GetInfoBL(DatB,"ДНПР1")); // Общее РВ и общую сумм б/л не нужны только в том случае, // если надо печатать только оплату за счет организации // Нужны! Т.к. в этом случае может быть сумма доплаты до // среднего, которую тоже в этом реестре печатаем! // общее РВ // общая сумма // общая сумма, если нужна доплата до среднего ORv = GetRvBL(DatB,-1,false); double AllSum = GetSummaBL(DatB,"ВСЕ",false); OSum = (PrintDopl==1)?AllSum:GetSummaBL(DatB,"ОСНБЛ",false); if ( PrintDopl ) // нужна доплата до среднего { double OsnSum = (PrintDopl!=1)?OSum:GetSummaBL(DatB,"ОСНБЛ",false); OSumD = AllSum-OsnSum; } // cумма доплат за счет предприятия (только для вмененки) double SumPDoplVm = 0.; // если нужно печатать вмененку if ( (PrintVm!=1) && cntPerVm ) { ORvVm = GetRvBL(DatB,-1,true); double AllSumVm = GetSummaBL(DatB,"ВСЕ",true); SumPDoplVm = GetSummaBL(DatB,"ДОПЛБЛ",true); OSumVm = (PrintDopl==1)?AllSumVm:GetSummaBL(DatB,"ОСНБЛ",true); if ( PrintDopl ) // нужна доплата до среднего { double OsnSumVm = (PrintDopl!=1)?OSumVm:GetSummaBL(DatB,"ОСНБЛ",true); OSumDVm = AllSumVm-SumPDoplVm-OsnSumVm; if( OSumDVm<0.0001 ) OSumDVm = 0; } if ( PrintDopl!=1 ) OSumVm += SumPDoplVm; } // Если реестр собираем по месяцу начисления, то возможно // нам попался результат пересчета. В этом случае б/л // не надо будет учитывать в кол-ве б/л if ( Type ) { var MNach = CreateObject("KMonth"); MNach.SetDate(static_cast_to_string(GetInfoBL(DatB,"МНАЧ1"))); if ( MonthBegPer.GetAbs()>MNach.GetAbs() || MonthEndPer.GetAbs()0 ) { var d1 = CreateObject("KDate"); var d2 = CreateObject("KDate"); int cntDn = 0; for ( int i=0; i0 ) { var d1 = CreateObject("KDate"); var d2 = CreateObject("KDate"); int cntDn = 0; for ( int i=0; i0 ) { PSumVm = SumPDoplVm; if ( PrintDopl==1 ) PSumVm += PSumDVm; DnPredVm = ORvVm; } return; } GetAllSummBL(DATBEG,&SUM_R,&SUM_OSN,&SUM_SS,&SUM_DOPL,VM,PerBL) { int VidBL = 0, // вид б/л TypR = 0, // вид РВ cntPer = 0, // кол-во периодов оплаты DnPred = 0, // кол-во дней за счет предприятия cntPerVm = 0, // для вмененки DnPredVm = 0; // кол-во дней за счет предприятия char DatReg[256]; bool bNRegim=false, bExistParentBL=false, bRecalcBL=false; double ORv = 0., OSum=0., OSumD = 0., PRv = 0., PSum=0., PSumD = 0.; // РВ и сумма по б/л double ORvVm = 0., OSumVm=0., OSumDVm = 0., PRvVm = 0., PSumVm=0., PSumDVm = 0.; // РВ и сумма по б/л // явно задаем параметры TypeFull=Type = 0; // Тип выборки (по 1 - по месяцу принадлежности, // 0 - по месяцу начисления) PrintDopl = 2;// Доплата до среднего за счет организации - отдельно PrintVm = 3;// Печать вмененку //if ( VM ) PrintVm = 2;// Печать вмененку // else PrintVm = 1; VidReestr = 3;// Оплата за счет соц.страха и работодателя - отдельно string DatBBl = static_cast_to_string(DATBEG); string DatEBl = static_cast_to_string(GetInfoBL(DATBEG,"ДАТАК")); string DatChd = ""; //Месяцы начала и конца периода выборки MBeg = DatBBl; MEnd = DatEBl; //Для первичного БЛ определяем суммы double sum_r = 0.00, sum_osn = 0.00, sum_ss = 0.00, sum_dopl = 0.00; var Razb = CreateObject("ParamFuncRW"); Razb.IInitial(static_cast_to_string(PerBL),"|",30); bool flPerv = true; int j = 0, cnt = 0; while( flPerv ) { flPerv = false; // Общий блок определющий параметры БЛ CommBlokGetParamBL(DatBBl,Type,VidBL,DatReg,bNRegim,TypR, bExistParentBL,bRecalcBL, DnPred,cntPer,DnPredVm,cntPerVm, ORv,OSum,OSumD,ORvVm,OSumVm,OSumDVm, PRv,PSum,PSumD,PRvVm,PSumVm,PSumDVm); if(!atoi(VM)) { sum_r += PSum; sum_osn += OSum; sum_ss = sum_osn - sum_r; sum_dopl += OSumD; } else { sum_r += PSumVm; sum_osn += OSumVm; sum_ss = sum_osn - sum_r; sum_dopl += OSumDVm; } // Если есть даты продолжения, то для продолжения БЛ тоже // необходимо все суммы подсчитать for ( int i = j+2; i< Razb.Count(); i++,i++ ) { flPerv = IsExistParentBL(Razb.Get(i),DnPred); if ( flPerv ) { DatBBl = Razb.Get(i); DatEBl = static_cast_to_string(GetInfoBL(DatBBl,"ДАТАК")); MBeg = DatBBl; MEnd = DatEBl; j = i; break; } } // антизацикливатель ++cnt; if ( cnt>1000 ) break; } round(sum_ss); SUM_R = sum_r; SUM_OSN = sum_osn; SUM_SS = sum_ss; SUM_DOPL = sum_dopl; return; } // Глобальные переменные, спущенные сюда, чтобы не мозолить глаза пользователю var CFile; // объект для печати var CTabl; // печатаемая таблица var PrintedFld; // Упорядоченный список печатаемых полей string MBeg,MEnd; // Месяцы начала и конца периода выборки \ определяются один int Type,TypeFull; // Тип выборки (по мес.прин. или мес.нач.)/ раз по первой строке таблицы var MonthBegPer,MonthEndPer; // переменные, которые нужны для определения: пересчет б/л или нет int fBl=0, // номер поля с датами начала б/л fOrder=-1, // номер поля с "номером по порядку" fTn=0; // номер поля с ТН int Page = 0; // номер страницы long NumOrder = 0; // номер по порядку int NeedRowBottomPage = 5; // кол-во строк для "итогов" по странице int CountCharInfoCol = 0; // Ширина "динамической" части таблицы (т.е. то что можно // регулировать из настроечной таблицы флажками печати) int WTable = 0; // ширина всей таблицы = CountCharInfoCol + ширина столбцов с РВ и суммами int WCentr = 0; // ширина для центровки (если ширина таблицы больше ширины листа, то // ширина центровки определяется исходя из ширины листа int WCentrCol = 0; // ширина центровки заголовка для столбца с б/л int TypeBLOrder[cntTypeBL]; // массив определяющий в каком столбце д.б. напечатан б/л // заданного типа (индекс = тип б/л) string HeadingBL[cntColBL]; // массив определяющий заголовки для столбцов б/л // (индекс = номер колонки б/л, начиная с 0) int FlagPrintCol[cntColBL]; // признак печати столбца б/л int LastPrintedCol = cntColBL-1; // последний печатаемый столбец char TopLine[5]; // Переменные, хранящие символы, для char MiddleLine[5]; // "рисования" таблицы char BottomLine[5]; // char VertLine[2]; // char GorLine[2]; // double arItog[cntColBL]; // итоговые суммы по ведомости по соц.страху (или общие) double arItogR[cntColBL]; // итоговое РВ по ведомости по соц.страху (или общее) double arItogD[cntColBL]; // итоговые суммы по ведомости доплата до среднего double arItogO[cntColBL]; // итоговые суммы по ведомости по организации double arItogRO[cntColBL]; // итоговое РВ по ведомости по организации double arItogDO[cntColBL]; // итоговые суммы по ведомости доплата до среднего (первые дни) int arCntBL[cntColBL]; // итоговое кол-во б/л по ведомости int arCntBL1[cntColBL]; // итоговое кол-во б/л (первичных) // аналогичные массивы для вмененки double arItogvm[cntColBL]; // итоговые суммы по ведомости по соц.страху (или общие) double arItogRvm[cntColBL]; // итоговое РВ по ведомости по соц.страху (или общее) double arItogDvm[cntColBL]; // итоговые суммы по ведомости доплата до среднего double arItogOvm[cntColBL]; // итоговые суммы по ведомости по организации double arItogROvm[cntColBL]; // итоговое РВ по ведомости по организации double arItogDOvm[cntColBL]; // итоговые суммы по ведомости доплата до среднего (первые дни) int CntSrc = 0; int gCheckSelectedVidBL=0; int gMaxCntVidBL=ExtendedBlFirst; char gSelectedVidBL[gMaxCntVidBL]; char gSelectedVidBLDop[MaxTypeDopBL]; ClearSelectedVidBL() { gCheckSelectedVidBL=0; for ( int idx=0; idx=0 && idx=100 ) { idx -= 100; if ( idx>=0 && idx=0 && VidBL=0 && idxDop=0 && VidBL