//////////////////////////////////////////////////////////////////////////////////////////// // Общие функции печати расчетных квитков //////////////////////////////////////////////////////////////////////////////////////////// // cntCheck - число квитков для данного ЛС // ptRow - число строк Н-У для отдельного квитка // cntOst - число строк остатка в квитке // cntDol - число строк долга в квитке // cntNac - число строк начислений в квитке // cntUdr - число строк удержаний в квитке // cNac - число строк начислений для части квитка // cUdr - число строк удержаний для части квитка // sumNac - итого начислено по квитку // sumUdr - итого удержано по квитку // sumPartNac - итого начислено по части квитка // sumPartUdr - итого удержано по части квитка // Функции печати квитка // --------------------- // MainCheck() - главная функция // Header() - печать шапки по ЛС // PrintChecks() - печать квитков (для одного ЛС может быть несколько квитков) // PrintCheck(n) - печать одного квитка // PrintPartCheck(n) - печать одной части квитка (в квитке может быть несколько частей // в случае если выполняется сортировка по какому-либо признаку) // PrintOstDolg() - печать строк остатка и долга по квитку // ItgNacPart(n) - формирует строку итога по начислениям для части квитка // ItgUdrPart(n) - формирует строку итога по удержаниям для части квитка // PrintVedChek(n) - печать суммы в ведомость по квитку // Footer() - печать подножия по ЛС int len = 256; // длина строки char Fio[len]; // ФИО int iTn; int NumStr = 0; // номер печатаемой строки для Excel char str[len], // вспомогательные строки arg[len], ts1[len], ts2[len], cell[len]; char strpod[len]; // строка подчеркивания char empty[len]; // пустая строка int obr_ls = 0, //ОБРАБОТАНО_ЛС; vib_ls = 0, //ВЫБРАНО_ЛС; obr_kv = 0, //ОБРАБОТАНО_КВИТКОВ; vib_kv = 0, //BСЕГО_КВИТКОВ; month_kv = 0;//МЕСЯЦ_КВИТКА; PrintKvitok(tipKv) { int cif = 0; bool bExNullKvitok = false; SetvAttr(); Kvitok(tipKv); // Вызов функций подготовки данных для печати квитка по данному ЛС if ( tipKv == 108 ) { //нулевые квитки не печатаем cif = GetCheckIF(); if ( !NullKvitokCif(cif) ) return 0; } //нулевые квитки не печатаем try //обработчик на случай отсутствия IsNullKvitok() в пользовательском comcheck.S { if(!bPrintNullKvitok && IsNullKvitok()) { // в случае Excel для нулевых квитков все равно нужно открыть или закрыть книгу if ( Excel ) bExNullKvitok = true; else return -2; } } catch(...) {;} if ( Excel ) { if( !obr_kv && !checkExestKv(tipKv) ) PrepareExcel(tipKv); PrepareTabl(tipKv); } if ( !bExNullKvitok ) { Header(tipKv); // Печать шапки по данному ЛС PrintChecks(tipKv,cif); // Печать квитков по данному ЛС Footer(tipKv); // Печать подножия по данному ЛС } if ( Excel ) EndExcelKv(); return 0; } //###################################################################################################### SetvAttr() { int saSrc = 0, saPod = 0, saCom = 0, saSub = 0; for ( int i = 0; i < OrdSort; i++ ) { if ( BALANCE[i] == ItSRC ) saSrc = 1; if ( BALANCE[i] == ItPOD ) saPod = 1; if ( BALANCE[i] == ItCOM ) saCom = 1; if ( BALANCE[i] == ItSUB ) saSub = 1; } if ( lsrc && !saSrc ) vAttr = 1; if ( lpod && !saPod ) vAttr = 1; if ( lcom && !saCom ) vAttr = 1; if ( lsub && !saSub ) vAttr = 1; return 0; } //###################################################################################################### Header(tipKv) // Печать шапки по данному ЛС { char Org[len], // Организация Podr[len], // Подразделение Fam[len], Ima[len], Otc[len]; string s = ""; for ( int i = 0; i < sh * 2 + 1; i++ ) s = s + "-"; sprintf(strpod,"%s",s); //если функция есть - пользователь хочет что то напечатать в начале шапки if ( ScriptCheckName("UserBeginPrintCheckHeader") ) UserBeginPrintCheckHeader(tipKv); 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); if ( !nameOrg ) GetEnterpriseVar("ИМЯП" ,Org,len-1); else GetEnterpriseVar("ИМЯП2",Org,len-1); Trim(Org); kch_from("f", Fam); Trim(Fam); kch_from("i", Ima); Trim(Ima); kch_from("o", Otc); Trim(Otc); int iPodr = kch_from_int("podr"); // Код подразделения int iKat = kch_from_int("kat"); // Код категории iTn = kch_from_int("tn"); // Табельный номер int pos = OtdPos(iPodr); sprintf(Podr,"%s", (pos!=EOF) ? OtdName(pos) : "неизвестное подразделение"); FreeSpaceString(Podr,3,""); if ( !KV_FIO ) sprintf(Fio,"%s %c.%c.",Fam,Ima[0],Otc[0]); else sprintf(Fio,"%s %s %s",Fam,Ima,Otc); int ln = sh * 2 + 1 - 17; // sh * 2 + 1 - длина строки квитка; 17 - длина строки с месяцем и годом sprintf(arg,"%s",Org); if ( !Excel ) { ts1 = CheckLenPrintStr(arg,ln); sprintf(str,"%s %-9.9s%d г.",ts1,sMes,iGod); print(str); } else { sprintf(str,"%-9.9s%d г.",sMes,iGod); sprintf(cell,"%s%d",GetColumn(0),NumStr); tWriteStringToCell(cell,OemToAnsi(arg)); sprintf(cell,"%s%d",GetColumn(7),NumStr); tWriteStringToCell(cell,OemToAnsi(str)); NumStr++; } if ( tipKv!=101 ) { if ( KV_PODR && Excel ) sprintf(str,"Подр-е: %s %d(%d): %s",Podr,iTn,iKat,Fio); else sprintf(str,"Подр-е:%d %d(%d): %s",iPodr,iTn,iKat,Fio); } else sprintf(str,"%*d(%*d): %s",l_tn,iTn,lkat,iKat,Fio); // Печатаем должность char Dolgn[256]; ln = sh * 2 + 1; // длина строки квитка if ( prDolgn ) { var Date = CreateObject("KDate"); Date.SetDateII(Mes.CountDay(),Mes.GetAbs()); GetKchDoljn(Dolgn, 256, Date, GetGeneralCombineLS()); FreeSpaceString(Dolgn,3,""); // Печатаем должность после ФИО if ( prDolgn==1 && strlen(Dolgn)>0 ) { sprintf(str,"%s (%s)",str,Dolgn); if ( !Excel ) str = CheckLenPrintStr(str,ln); } } if ( !Excel ) print(str); else { sprintf(cell,"A%d",NumStr); tWriteStringToCell(cell,OemToAnsi(str)); NumStr++; } // Печатаем должность в отдельной строке if ( prDolgn==2 && strlen(Dolgn)>0 ) { sprintf(str,"%s %s","Должность:",Dolgn); if ( !Excel ) { str = CheckLenPrintStr(str,ln); print(str); } else { tInsertRows(NumStr+1,1); tCopyRow(NumStr+1); sprintf(cell,"A%d",NumStr); tWriteStringToCell(cell,OemToAnsi(str)); NumStr++; } } //если функция есть - пользователь хочет что то напечатать в конце шапки if ( ScriptCheckName("UserEndPrintCheckHeader") ) UserEndPrintCheckHeader(tipKv); if ( !Excel ) print(strpod); return 0; } CheckLenPrintStr(arg,ln) { char str[256]; if ( strlen(arg) >= ln ) sprintf(str,"%-*.*s",ln,ln,arg); else { int lk = ln - strlen(arg); sprintf(str,"%s%*.*s",arg,lk,lk,""); } return str; } //###################################################################################################### PrintChecks(tipKv,cif) // Печать квитков по данному ЛС { int fPrnCheck = 0; // флаг печати квитка for ( int i = 0; i < cntCheck; i++ ) { if ( tipKv==108 && cif != -1 && CurSrcIntCodCheck(i) != cif ) continue; PrepareTableForCheck(i); fPrnCheck = FlgPrintCheck(); if ( !fPrnCheck && !bPrintNullPartKvitok ) { __CountSkipedChecks++; continue; } if ( Excel && fPrnCheck ) { tInsertRows(NumStr+6,6); tCopyRows(NumStr+6,6); } PrintCheck(tipKv,i,fPrnCheck); // печать одного квитка } if ( Excel ) tDeleteRows(NumStr,6); return 0; } //###################################################################################################### FlgPrintCheck() { if ( cntNac ) return 1; if ( cntUdr ) return 1; if ( cntOst ) return 1; if ( cntDol ) return 1; int flgSumVedCheck = 0; for ( int i = 0; i < cntPartCheck; i++ ) { if ( nabs(GetSumVedPart(i)) > eps ) { flgSumVedCheck = 1; break; } } if ( flgSumVedCheck ) return 1; return 0; } //###################################################################################################### PrintCheck(tipKv,n,fPrnCheck) // печать одного квитка // tipKv - тип квитка // n - номер квитка // fPrnCheck - флаг печати квитка { __CurrentCheckProp.Init(chSRC[n],chSUB[n],chPOD[n],chCOM[n]); if( tipKv==101 && cntCheck < 2 ) { int ln = sh * 2 + 1 - 16; // sh * 2 + 1 - длина строки квитка; 16 - длина строки с номером квитка sprintf(arg," Подр. %*d %s",lpod,CurPodrCheck(n),CurPodNameCheck(n)); ts1 = CheckLenPrintStr(arg,ln); if ( !Excel ) print(ts1); else { tInsertRows(NumStr+1,1); tCopyRow(NumStr+1); sprintf(cell,"A%d",NumStr); tWriteStringToCell(cell,OemToAnsi(ts1)); NumStr++; } } int idxNullPartKvitok = (bPrintNullPartKvitok)?0:cntNullPartsCheck; if ( cntCheck-idxNullPartKvitok > 1 ) { //разлелительную полосу печатаем только начиная со второго квитка (пропущенные/нулевые квитки не учитываем) if ( (n-__CountSkipedChecks)>0 && !Excel ) print(strpod); sprintf(str,"%s квиток %2d из %2d","",n+1-__CountSkipedChecks,cntCheck-idxNullPartKvitok); if ( !Excel ) print(str); else { if ( n && tipKv!=108 ) { tInsertRows(NumStr+1,1); tCopyRow(NumStr+1); NumStr++;} // Для разрыва страницы: сохранем строку - начало части квитка, если это не 1-ая часть и // если предыдущая часть входит на лист if ( n+1-__CountSkipedChecks!=1 && NumStr-rowBreak < ShCntRow ) firstStrPart = NumStr; tInsertRows(NumStr+1,1);tCopyRow(NumStr+1); sprintf(cell,"A%d",NumStr); tWriteStringToCell(cell,OemToAnsi(str)); NumStr++; } //если функция есть - пользователь хочет что то напечатать в начале шапки "части квитка" if ( ScriptCheckName("UserBeginPrintPartCheckHeader") ) UserBeginPrintPartCheckHeader(tipKv); for ( int i = 0; i < OrdDepth; i++ ) { if ( BALANCE[i] == ItSRC ) sprintf(str," Источник финанс. %s (%c)",CurSrcNameCheck(n),CurSrcExtCodCheck(n)); if ( BALANCE[i] == ItPOD ) sprintf(str," Подразделение: %s (%d)",CurPodNameCheck(n),CurPodrCheck(n)); // if ( BALANCE[i] == ItCOM ) sprintf(str," Совместительство: %s (%s)",CurComNameCheck(n),CurComExtCodCheck(n)); //** if ( BALANCE[i] == ItCOM ) { if(GetGeneralCombineLS()!=ExtCombineToInt(CurComExtCodCheck(n))) sprintf(str," Совместительство: %s (%s)",CurComNameCheck(n),CurComExtCodCheck(n)); else sprintf(str,"%s (%s)",CurComNameCheck(n),CurComExtCodCheck(n)); } //** if ( BALANCE[i] == ItSUB ) sprintf(str," Объект: %s (%s)",CurSubNameCheck(n),CurSubExtCodCheck(n)); if ( !Excel ) print(str); else { tInsertRows(NumStr+1,1);tCopyRow(NumStr+1); sprintf(cell,"A%d",NumStr); tWriteStringToCell(cell,OemToAnsi(str)); NumStr++; } } if ( prnTn && n ) { sprintf(str," %d %s",iTn,Fio); if ( !Excel ) { print(str); if ( tipKv==102 ) print(strpod); } else { tInsertRows(NumStr+1,1);tCopyRow(NumStr+1); sprintf(cell,"A%d",NumStr); tWriteStringToCell(cell,OemToAnsi(str)); NumStr++; } } //если функция есть - пользователь хочет что то напечатать в конце шапки "части квитка" if ( ScriptCheckName("UserEndPrintPartCheckHeader") ) UserEndPrintPartCheckHeader(tipKv); } if ( !fPrnCheck ) { sprintf(str," по данному квитку сумм нет"); if ( !Excel ) { print(str); print(strpod); } else { tInsertRows(NumStr+1,2); sprintf(cell,"A%d",NumStr); tWriteStringToCell(cell,OemToAnsi(str)); NumStr++; } } else { if ( ( tipKv==101 || tipKv==103 || tipKv==108 ) && !Excel ) print(strpod); if ( Excel ) { tDeleteRows(NumStr,1); NumStr++; } PrintOstDolg(tipKv); for ( int i = 0; i < cntPartCheck; i++ ) { PrepareTableForPartCheck(i); PrintPartCheck(tipKv,i); // печать одной части квитка if ( fitPartCheck && ( nabs(sumPartNac)>eps || nabs(sumPartUdr)>eps ) ) PrintItogPartCheck(tipKv,i); // печать итога по части квитка } // Печатаем ПЕНИ if ( GroupPeni ) PrintGroupPeni(tipKv); if ( !Excel ) { print(strpod); arg = " ВCЕГО начислено "; int ln = sh - strlen(arg) - 1 - lsum; sprintf(ts1,"%s%*.*s%*.2f ",arg,ln,ln,"",lsum,sumNac); arg = " удержано "; ln = sh - strlen(arg) - 1 - lsum; sprintf(ts2,"%s%*.*s%*.2f ",arg,ln,ln,"",lsum,sumUdr); sprintf(str,"%-*.*s|%-*.*s",sh,sh,ts1,sh,sh,ts2); print(str); print(strpod); } else { // удалить две строки tDeleteRows(NumStr,2); sprintf(arg,"%.2f",sumNac); sprintf(cell,"%s%d",GetColumn(3),NumStr); tWriteStringToCell(cell,OemToAnsi(arg)); sprintf(arg,"%.2f",sumUdr); sprintf(cell,"%s%d",GetColumn(7),NumStr); tWriteStringToCell(cell,OemToAnsi(arg)); NumStr++; } } PrintVedChek(tipKv,n); if ( !Excel ) print(""); return 0; } //###################################################################################################### PrintGroupPeni(tipKv) { if ( MapRowsPeni.Size() ) { if ( !Excel ) print(strpod); else { sprintf(cell,"%s%d:%s%d",GetColumn(0),NumStr,GetColumn(8),NumStr); tBordersCell(cell,0,0,1,0,1); } double itogoPeni=0.; for (bool Cur=MapRowsPeni.InitIterator();Cur;Cur=MapRowsPeni.Next()) { int row = MapRowsPeni.GetCurKey(); GetStrNac(row); itogoPeni += sum; if ( vAttr ) getiProp(InternCodE); if ( !Excel ) { formStringSum(ts1); sprintf(str,"%-*.*s|",sh,sh,ts1); print(str); } else { StringExcel(1); NumStr++; tInsertRows(NumStr+1,1); tCopyRow(NumStr+1); } } //выводим итого ПЕНИ if (MapRowsPeni.Size()>1) { if ( !Excel ) { arg = " итого "; int ln = sh - strlen(arg) - 1 - lsum; sprintf(ts1,"%s%*.*s%*.2f |",arg,ln,ln,"",lsum,itogoPeni); print(ts1); } else { sprintf(cell,"A%d",NumStr); tWriteStringToCell(cell,OemToAnsi("итого")); sprintf(arg,"%.2f",itogoPeni); sprintf(cell,"%s%d",GetColumn(3),NumStr); //I tWriteStringToCell(cell,OemToAnsi(arg)); NumStr++; tInsertRows(NumStr+1,1); tCopyRow(NumStr+1); } } } return ""; } //###################################################################################################### PrintPartCheck(tipKv,n) // печать одной части квитка // tipKv - тип квитка // n - номер части квитка { int cnt = ( cNac > cUdr ) ? cNac : cUdr; // массив для межрасчетных выплат int ArrAvans[cnt+1]; int cntAvans = 0; // количество межрасчетных выплат double itogAvans = 0.; bool flPrintAvans = false; int EmptyStringBeforeAvans = 1; int countPayDatePrinted = 0; var payDate = CreateObject("KDate"); int row = 0; int shiftPeni = 0; // Смещение на пени для одной части квитка // Цикл по строкам части квитка for ( row = 0; row < cnt; row++ ) { int currentRow = row; //номер строки квитка с учетом возможных сдвигов ( пени, межрасчеты и т.п.) // === Строка начислений === // учитываем "сдвиг" на попавшиеся ранее виды пени currentRow = row + shiftPeni; if ( GroupPeni && currentRow < cNac ) shiftPeni += GetShiftPeni(row,currentRow,sumPartNac); GetDataAndMakeStringForPrint(tipKv,n,currentRow,1); // === Строка удержаний === // учитываем "сдвиг" на попавшиеся ранее межрасчетные выплаты currentRow = row + cntAvans - countPayDatePrinted; if ( printAvans && currentRow < cUdr ) GetShiftAvans(row,cnt,currentRow,ArrAvans,cntAvans,itogAvans, EmptyStringBeforeAvans,countPayDatePrinted); GetDataAndMakeStringForPrint(tipKv,n,currentRow,2); // Если с учетом пропущенных межрасчетных выплат мы уже просмотрели все удержания if ( printAvans && cUdr && currentRow >= cUdr && cntAvans ) PrintAvans(tipKv,n,row,currentRow,cnt,ArrAvans,cntAvans,itogAvans,flPrintAvans, EmptyStringBeforeAvans,countPayDatePrinted,payDate); // В случае, если все НУ уже закончились, а происходит только "сдвиг" на пени, пустую строку не выводим if ( !shiftPeni || currentRow < cNac-shiftPeni || currentRow < cUdr || flPrintAvans ) { if (!Excel) { sprintf(str,"%s|%s",ts1,ts2); print(str); } else { NumStr++; tInsertRows(NumStr+1,1); tCopyRow(NumStr+1); } } } } //###################################################################################################### // находим вид ПЕНИ и корректирем "сдвиг" GetShiftPeni(row,¤tRow,&sumPartNac) { int shiftPeni = 0; do { GetStrNac(currentRow); //нашли вид ПЕНИ if (kod==CodVidaPeni) { sumPartNac -= sum; //корректируем итог по части квитка на сумму ПЕНИ MapRowsPeni.Add(currentRow,currentRow); //добавляем номер строки в МЭП currentRow = row + MapRowsPeni.Size(); shiftPeni++; } } while ( kod==CodVidaPeni && currentRow< cNac ); return shiftPeni; } // пропускаем межрасчетные выплаты (запоминаем номер строки для них) GetShiftAvans(&row,&cnt,¤tRow,&ArrAvans,&cntAvans,&itogAvans,&EmptyStringBeforeAvans,&countPayDatePrinted) { char Simv = 0; do //пропускаем межрасчетные выплаты( запоминаем номер строки для них) { GetStrUdr(currentRow); Simv = Sim_For_Extern_Cod(kod,1009); // Если попалась межрасчетная выплата, запоминаем ее на будущее if ( Simv=='В' || Simv=='А' ) { // умышленно информацию размещаю с 1-го элемента, т.к. "нулевым" условно будет идти надпись // "Межрасчетные выплаты". ArrAvans[++cntAvans] = currentRow; itogAvans += sum; currentRow = row + cntAvans - countPayDatePrinted; // Одновременно увеличиваем общий счетчик на 1, если он совпадал с количеством видов удержаний // этот "+1" нам понадобиться чтобы вывести надпись "Межрасчетные выплаты", // еще "+1" нам понадобиться чтобы вывести итоги по выплатам в межрасчетный период. if ( cnt < cUdr + EmptyStringBeforeAvans + 2 ) cnt = cUdr + EmptyStringBeforeAvans + 2; } } while ( ( Simv=='В' || Simv=='А' ) && currentRowcntAvans+1 || idxAvans<0 ) { if ( idxAvans>cntAvans+1 ) flPrintAvans = false; // строки межрасчетов закончились sprintf(ts2,"%s",empty); } else if ( idxAvans == cntAvans+1 ) { // Выводим итоги по выплатам в межрасчетный период if ( !Excel ) { arg = " итого выплачено "; int ln = sh - strlen(arg) - 1 - lsum; sprintf(ts2,"%s%*.*s%*.2f",arg,ln,ln,"",lsum,itogAvans); } else { sprintf(arg,"%.2f",itogAvans); sprintf(cell,"%s%d",GetColumn(4),NumStr); tWriteStringToCell(cell,OemToAnsi("итого выплачено ")); sprintf(cell,"%s%d",GetColumn(7),NumStr); tWriteStringToCell(cell,OemToAnsi(arg)); } } else { if ( !idxAvans ) { if ( !Excel ) sprintf(ts2," %-.*s",lmes+lkod+lsub+lnaz+l_rv+lsum+1,"Межрасчетные выплаты:"); else { sprintf(cell,"%s%d",GetColumn(5),NumStr); tWriteStringToCell(cell,OemToAnsi("Межрасчетные выплаты:")); } } else { currentRow=ArrAvans[idxAvans]; GetDataAndMakeStringForPrint(tipKv,n,currentRow,2); if ( printPayDateInNextRow && GetDateAvans(payDate) ) { ++countPayDatePrinted; //увеличиваем макс. значение счетчика, чтобы распечатались все удержания и даты выплат if ( cnt < cUdr + EmptyStringBeforeAvans + 2 + countPayDatePrinted ) cnt = cUdr + EmptyStringBeforeAvans + 2 + countPayDatePrinted; } } } } return ""; } //###################################################################################################### GetDateAvans(&payDate) // Получение даты выплаты для межрасчетных выплат { // Пробуем получить "плановую" дату выплаты из поля начисленной суммы string pDate = GetDateVP(Intern_To_ExternE(InternCodE),month_Abs,month_kv); // Пробуем получить дату из кассовых выплат if( strlen(pDate)==0 || !KDateFromStr(pDate).IsValid() ) pDate = GetPayDateCurrentRow(); payDate = KDateFromStr(pDate); if ( payDate.IsValid() ) return 1; return 0; } GetPayDateCurrentRow() { // если межрасчеты объединены - дату не печатать, иначе есть больная вероятность не угадать с датой выплаты (у склеиных сумм дата выплаты может быть разная) ( todo: проверять была ли склейка межрасчетов или обьединяли другие выплаты ) // для аванса ИД сейчас не разносится, но при этом "зарплатная ведомость" ид разносит -> в квитке у аванса печатется "левая" дата выплаты if ( atoi(InternCodE)==201 || 'А' == Sim_For_Extern_Cod(kod,1009) || KV_MOD1!=0 ) return ""; var sumElem = FindSumElem(InternCodE,month_Abs,month_kv); if (!VarHasValue(sumElem) || sumElem.PaysCount()<1) return ""; //лучше брать не первую выплату а последнюю, т.к. на виде касса теоретически может быть несколько выплат. //если вид завели сначала руками и приняли в зарплатную ведомость, а потом занулили и разнесли на него следующую ведомость int idVed=sumElem.GetPay(sumElem.PaysCount()-1).IdVed; return GetKassVedInfo(idVed, 0);// what: 0 - дата, 1 - номер, 2 - название } //###################################################################################################### PrintItogPartCheck(tipKv,n) { // печать итога по части квитка sprintf(ts1,"%-*.*s",sh,sh,ItgNUPart(tipKv,n,sumPartNac,1)); sprintf(ts2,"%-*.*s",sh,sh,ItgNUPart(tipKv,n,sumPartUdr,2)); if ( !Excel ) { sprintf(str,"%s|%s",ts1,ts2); print(str); } else { tInsertRows(NumStr+2,1); tCopyRow(NumStr+2); NumStr++; } return 0; } ItgNUPart(tipKv,n,sumPart,Part) // формирует строку итога по начислениям или удержаниям для части квитка { if (tipKv==101) arg = CreateNamePartKvitok(n,1); else arg = CreateNamePartKvitok(n,0); char ts[len]; if (tipKv==101) ts = " ИТОГО "; else ts = " итого "; if ( !Excel ) { int ln = sh - strlen(ts) - 1 - lsum; sprintf(str,"%s%-*.*s%*.2f ",ts,ln,ln,arg,lsum,sumPart); } else { sprintf(str,"%s%s",ts,arg); sprintf(arg,"%.2f ",sumPart); if ( Part==1 ) { sprintf(cell,"%s%d",GetColumn(0),NumStr); tWriteStringToCell(cell,OemToAnsi(str)); sprintf(cell,"%s%d",GetColumn(3),NumStr); tWriteStringToCell(cell,OemToAnsi(arg)); } else if ( Part==2 ) { sprintf(cell,"%s%d",GetColumn(4),NumStr); tWriteStringToCell(cell,OemToAnsi(str)); sprintf(cell,"%s%d",GetColumn(7),NumStr); tWriteStringToCell(cell,OemToAnsi(arg)); } } return static_cast_to_string(str); } CreateNamePartKvitok(n,needName) // Создает имя для части квитка { string ss[4]; for ( int i = 0; i < 4; i++ ) ss[i] = ""; int iss = 0; if ( OrdSort > OrdDepth ) { for ( int i = OrdDepth; i < OrdSort; i++ ) { if ( !needName ) { if ( BALANCE[i] == ItSRC ) { sprintf(arg,"(%c)",CurSrcExtCodPart(n)); ss[iss] = static_cast_to_string(arg); iss++; } if ( BALANCE[i] == ItPOD ) { sprintf(arg,"(%d)",CurPodrPart(n)); ss[iss] = static_cast_to_string(arg); iss++; } if ( BALANCE[i] == ItCOM ) { sprintf(arg,"(%s)",Trim(CurComExtCodPart(n))); ss[iss] = static_cast_to_string(arg); iss++; } if ( BALANCE[i] == ItSUB ) { sprintf(arg,"(%s)",Trim(CurSubExtCodPart(n))); ss[iss] = static_cast_to_string(arg); iss++; } } else { if ( BALANCE[i] == ItSRC ) { sprintf(arg,"%s (%c)",CurSrcNamePart(n),CurSrcExtCodPart(n)); ss[iss] = static_cast_to_string(arg); iss++; } if ( BALANCE[i] == ItPOD ) { sprintf(arg,"%s (%d)",CurPodNamePart(n),CurPodrPart(n)); ss[iss] = static_cast_to_string(arg); iss++; } if ( BALANCE[i] == ItCOM ) { sprintf(arg,"%s (%s)",CurComNamePart(n),Trim(CurComExtCodPart(n))); ss[iss] = static_cast_to_string(arg); iss++; } if ( BALANCE[i] == ItSUB ) { sprintf(arg,"%s (%s)",CurSubNamePart(n),Trim(CurSubExtCodPart(n))); ss[iss] = static_cast_to_string(arg); iss++; } } } } arg = ""; for ( int i = 0; i < iss; i++ ) { arg += ss[i] + " "; } return arg; } //###################################################################################################### PrintOstDolg(tipKv) // Печать строк остатка и долга по квитку { int cnt = ( cntOst > cntDol ) ? cntOst : cntDol; sprintf(empty,"%*.*s",sh,sh,""); if ( !Excel ) { formStringTitle(ts1,"начисл."); formStringTitle(ts2,"удерж."); sprintf(str,"%*.*s|%*.*s",sh,sh,ts1, sh,sh,ts2); print(str); } for ( int row = 0; row < cnt; row++ ) { if ( row < cntOst ) { GetStrOst(row); if ( vAttr ) getiProp(InternCodE); if ( !Excel ) formStringOD(ts1); else StringExcel(1); } else sprintf(ts1,"%s",empty); if ( row < cntDol ) { GetStrDol(row); if ( vAttr ) getiProp(InternCodE); if ( !Excel ) formStringOD(ts2); else StringExcel(2); } else sprintf(ts2,"%s",empty); if ( !Excel ) { sprintf(str,"%s|%s",ts1,ts2); print(str); } else { NumStr++; tInsertRows(NumStr+1,1); tCopyRow(NumStr+1); } } if ( cnt ) { if (!Excel) print(strpod); else { sprintf(cell,"%s%d:%s%d",GetColumn(0),NumStr-1,GetColumn(8),NumStr-1); tBordersCell(cell,0,0,0,1,1); } } return 0; } //###################################################################################################### PrintVedChek(tipKv,n) // печать суммы в ведомость по квитку { if ( fVedCheck ) { int ln = sh * 2 + 1; if ( cntCheck > 1 && tipKv==101 ) sprintf(arg," в ведомость за месяц по подр. %5d %s", CurPodrCheck(n), CurPodNameCheck(n)); else sprintf(arg," в ведомость за месяц"); if ( !Excel ) { sprintf(str,"%-*.*s",ln,ln,arg); print(str); } else { sprintf(cell,"A%d",NumStr); NumStr++; tWriteStringToCell(cell,OemToAnsi(arg)); tInsertRows(NumStr+1,1); tCopyRow(NumStr+1); } } if ( fVedCheck ) { for ( int i = 0; i < cntPartCheck; i++ ) { arg = CreateNamePartKvitok(i,1); if ( strlen(arg)==0 ) { if ( cntPartCheck>1 ) sprintf(arg,"%s (%d)","Часть",i+1); else arg = "итого"; } PrintSumVedForAllChek(tipKv,arg,GetSumVedPart(i),GetSumOstPart(i),GetSumDolPart(i)); } } else { int idxNullPartKvitok = (bPrintNullPartKvitok)?0:cntNullPartsCheck; //печатаем сумму в ведомость только для последнего квитка if (n!=cntCheck-idxNullPartKvitok-1) { if ( Excel ) tDeleteRows(NumStr,1); return; } PrintSumVedForAllChek(tipKv,"",checkSumVed,checkSumOst,checkSumDol); } if ( Excel ) tDeleteRows(NumStr,1); return 0; } //###################################################################################################### PrintSumVedForAllChek(tipKv,nameVed,SumVed,to,td) { if ( !Excel ) { arg = " в вед. за месяц "; if ( nameVed!="" ) arg = " " + nameVed; int ln = sh - strlen(arg) - 1 - lsum; sprintf(ts1,"%s%*.*s%*.2f",arg,ln,ln,"",lsum,SumVed); ts2 = ""; if ( to >= td && nabs(to) > eps ) { arg = " остаток "; int ln = sh - strlen(arg) - 1 - lsum; sprintf(ts2,"%s%*.*s%*.2f",arg,ln,ln,"",lsum,to); } if ( td >= to && nabs(td) > eps ) { arg = " долг "; int ln = sh - strlen(arg) - 1 - lsum; sprintf(ts2,"%s%*.*s%*.2f",arg,ln,ln,"",lsum,td); } sprintf(str,"%-*.*s %-*.*s",sh,sh,ts1,sh,sh,ts2); print(str); } else { arg = " в вед. за месяц "; if ( nameVed!="" ) arg = nameVed; sprintf(ts1,"%.2f",SumVed); sprintf(cell,"%s%d",GetColumn(0),NumStr); tWriteStringToCell(cell,OemToAnsi(arg)); sprintf(cell,"%s%d",GetColumn(3),NumStr); tHorizontalAlignment(cell,3); tWriteStringToCell(cell,ts1); if ( to >= td && nabs(to) > eps ) { arg = " остаток "; sprintf(ts2,"%.2f",to); } if ( td >= to && nabs(td) > eps ) { arg = " долг "; sprintf(ts2,"%.2f",td); } if ( nabs(to) > eps || nabs(td) > eps ) { sprintf(cell,"%s%d",GetColumn(4),NumStr); tWriteStringToCell(cell,OemToAnsi(arg)); sprintf(cell,"%s%d",GetColumn(7),NumStr); tHorizontalAlignment(cell,3); tWriteStringToCell(cell,ts2); } NumStr++; tInsertRows(NumStr+1,1); tCopyRow(NumStr+1); } return 0; } //###################################################################################################### Footer(tipKv) // печать подножия { if ( Excel ) NumStr++; var CL=CreateObject("CombineList"); var m_kv = CreateObject("KMonth"); m_kv.SetMonth(month_kv); char d1[256], d2[256], Buf[256]; sprintf(d1,"%02d.%02d.%04d",1,m_kv.GetMonth(),m_kv.GetYear()); sprintf(d2,"%02d.%02d.%04d",m_kv.CountDay(),m_kv.GetMonth(),m_kv.GetYear()); var dateBeg = KDateFromStr(d1); var dateEnd = KDateFromStr(d2); // Печать табеля for ( int i = 0; i < cntCom; i++ ) { var TmpCurCom = CreateObject("TmpCurCombine"); TmpCurCom.Init(GetComIntCod(i)); sprintf(ts1,"%-*.*s",countday,countday,calm); // смотрим дату поступления на работу GetKchValue("data_rb",Buf,10,dateBeg); var dat_rb = KDateFromStr(Buf); if ( !dat_rb.IsValid() ) dat_rb.SetDateII(1,MIN_MONTH_VALUE); // смотрим дату увольнения GetKchValue("data_uv",Buf,10,dateBeg); var dat_uv = KDateFromStr(Buf); if ( !dat_uv.IsValid() ) dat_uv.SetDateII(31,MAX_MONTH_VALUE); if ( TabForDlg==0 || // по всем должностям ( TabForDlg==1 && GetComIntCod(i) == CL.GetBaseID()) || // по основной должности ( TabForDlg==2 && !dat_uv.LE(dateBeg) && !dat_rb.GE(dateEnd) ))// по действующим должностям { if ( cntCom == 1 ) sprintf(str," Табель: %s", ts1); else sprintf(str," Табель (%s): %s",GetComExtCod(i),ts1); if ( !Excel ) print(str); else { tInsertRows(NumStr+1,1); tCopyRow(NumStr+1); sprintf(cell,"A%d",NumStr); tWriteStringToCell(cell,OemToAnsi(str)); NumStr++; } } } //печатаем информацию о НДФЛ PrintNdflInfo(tipKv,NumStr); if ( !Excel && tipKv==102 ) print(""); return 0; } //###################################################################################################### formStringTitle(&ts,strnu) { // формирование строки заголовка sprintf(ts,"%*s %*s %-*.*s%s%-*.*s%s%-*.*s%s%-*.*s%s%-*.*s%*.*s %*.*s%*.*s", lmes,"М", // календарный месяц lkod,"код", // внешний код вида начисления lsrc,lsrc,"И", (lsrc)?" ":"",// внешний код источника финансирования lpod,lpod,"подр.",(lpod)?" ":"",// внешний код подразделения lcom,lcom,"сов.", (lcom)?" ":"",// внешний код совместительства lsub,lsub,"об-кт",(lsub)?" ":"",// внешний код объекта lnaz,lnaz,strnu, // название вида начисления l_rv,l_rv,"рв", // рабочее время lsum,lsum,"сумма", // сумма lmni,lmni,""); // мнимость return 0; } //###################################################################################################### formStringSum(&ts) { sprintf(str,"%c",src); sprintf(arg,"%d",pod); char tmp_rv[256],tmp_nazv[256]; tmp_rv = rv; tmp_nazv = nazv; var d = CreateObject("KDate"); if ( printPayDate && 'В' == Sim_For_Extern_Cod(kod,1009) && !printPayDateInNextRow && GetDateAvans(d) ) { if ( printPayDateInsteadCodeName ) sprintf(tmp_nazv,"(%02d.%02d)",d.GetDay(),d.GetMonth()); else if ( printPayDateInsteadRv ) sprintf(tmp_rv,"(%02d.%02d)",d.GetDay(),d.GetMonth()); } sprintf(ts,"%*d %*d %-*.*s%s%-*.*s%s%-*.*s%s%-*.*s%s%-*.*s%*.*s %*.2f%c", lmes,m, // календарный месяц lkod,kod, // внешний код вида начисления lsrc,lsrc,str,(lsrc)?" ":"", // внешний код источника финансирования lpod,lpod,arg,(lpod)?" ":"", // внешний код подразделения lcom,lcom,com,(lcom)?" ":"", // внешний код совместительства lsub,lsub,sub,(lsub)?" ":"", // внешний код объекта lnaz,lnaz,tmp_nazv, // название вида начисления l_rv,l_rv,tmp_rv, // рабочее время lsum,sum, // сумма mnim); // мнимость return 0; } //###################################################################################################### formStringOD(&ts) { // формирование строки остатка-долга sprintf(str,"%c",src); sprintf(arg,"%d",pod); sprintf(ts,"%*d %*d %-*.*s%s%-*.*s%s%-*.*s%s%-*.*s%s%-*.*s%*.*s %*.2f%c", lmes,m, // календарный месяц lkod,kod, // внешний код остатка lsrc,lsrc,str,(lsrc)?" ":"", // внешний код источника финансирования lpod,lpod,arg,(lpod)?" ":"", // внешний код подразделения lcom,lcom,com,(lcom)?" ":"", // внешний код совместительства lsub,lsub,sub,(lsub)?" ":"", // внешний код объекта lnaz,lnaz,nazv, // название вида начисления l_rv,l_rv,rv, // рабочее время lsum,sum, // сумма mnim); // мнимость return 0; } //###################################################################################################### GetDataAndMakeStringForPrint(tipKv,n,_row,part) { switch( part ) { case 1: { //начисления "закончились" if ( _row >= cNac ) sprintf(ts1,"%s",empty); else { GetStrNac(_row); if ( vAttr ) getiProp(InternCodE); MakeStringForPrint(tipKv,1); } break; } case 2: { //удержания "закончились" if ( _row >= cUdr ) sprintf(ts2,"%s",empty); else { GetStrUdr(_row); if ( vAttr ) getiProp(InternCodE); MakeStringForPrint(tipKv,2); } break; } } } MakeStringForPrint(tipKv,part) { switch( part ) { case 1: { if ( !Excel ) formStringSum(ts1); else StringExcel(part); break; } case 2: { if ( !Excel ) formStringSum(ts2); else StringExcel(part); break; } } } //###################################################################################################### getiProp(codenu) { iProp.Initial(GetPropOfCod(codenu)); isrc = iProp.GetSrc(); src = IntSrcToExt(isrc); ipod = iProp.GetPodr(); pod = ipod; icom = iProp.GetCombine(); com = iCombList.GetExtCod(icom); isub = iProp.GetSubject(); sub = iSubjList.GetExtCod(isub); return 0; } //###################################################################################################### // Вспомогательные функции // ----------------------- // внешние коды, исползуются в печати части квитка // CurSrcExtCodPart(n) - источник // CurPodrPart(n) - подразделение // CurComExtCodPart(n) - совместительство // CurSubExtCodPart(n) - объект // внешние коды, исползуются в печати квитка // CurSrcExtCodCheck(n) - источник // CurPodrCheck(n) - подразделение // CurComExtCodCheck(n) - совместительство // CurSubExtCodCheck(n) - объект // внутренние коды, исползуются в печати квитка // CurSrcIntCodCheck(n) - источник // CurPodIntCodCheck(n) - подразделение // CurComIntCodCheck(n) - совместительство // CurSubIntCodCheck(n) - объект // названия, исползуются в печати части квитка // CurSrcNamePart(n) - источник // CurPodNamePart(n) - подразделение // CurComNamePart(n) - совместительство // CurSubNamePart(n) - объект // названия, исползуются в печати квитка // CurSrcNameCheck(n) - источник // CurPodNameCheck(n) - подразделение // CurComNameCheck(n) - совместительство // CurSubNameCheck(n) - объект // GetNameSRC(src) - название источника по внутреннему коду // GetNamePOD(pod) - название подразделения по внутреннему коду // GetNameCOM(com) - название совместительства по внутреннему коду // GetNameSUB(sub) - название объекта по внутреннему коду // GetSumVedPart(n) - сумма в ведомость по части квитка // GetSumOstPart(n) - остаток следующего месяца по части квитка // GetSumDolPart(n) - долг следующего месяца по части квитка // GetComIntCod(i) - внутренний код совместительства из списка совместительств по которым есть ненулевые строки видов Н-У // GetComExtCod(i) - внешний код совместительства из списка совместительств по которым есть ненулевые строки видов Н-У