БЛАНКСШАБЛОНОМ "Выборка БК из плана счетов";

2-- Переменные
скцРАБ:Object; скцТАБ:Object;
btnПоиск:Object; btnClose:Object; btnСхрнт:Object; cb_OnlyUsedAcc:Object; cb_CheckДохAcc:Object; cb_SelectNewБК:Object;

btnRemove1:Object;
btnRemove2:Object;

var Фокус    :String="";
var AR       :String="+";
var DR       :String="-";
FolderRes    :String;

Func ВзятьКоммент(БК:String) :String;
 if Match(БК, "???.0000.0000000.000")    : ^"Код главы";
 |  Match(БК, "???.????.???????.???")    : ^"Классификация расходов бюджета";
 |  Match(БК, "???.0.00.00000.00.0000")  : ^"Код главы";
 |  Match(БК, "???.?.??.?????.??.????")  : ^"Классификация доходов бюджета";
 |  Match(БК, "???.00.00.00.00.00.0000") : ^"Код главы";
 |  Match(БК, "???.??.??.??.??.??.????") : ^"Классификация источников дефицита";
 fi;
 ^"";
end;

var OnlyUsedAcc :Logical=[False];
var CheckДохAcc :Logical=[False];
var SelectNewБК :Logical=[False];
var Order_NewБК :Integer=[0];
var Order_NewБК_:Integer=Order_NewБК;
var ДАТОПЕР     :Date;
var oldDate     :Date;     -- для запоминания и возвратов

var Позиции     :Integer;

var Buf[]    :String;
var tmp_ЭК[] :String;
var use_БК[] :String;
var key_FS[] :String;

var NNN_БК[] :Integer=$;
var SRT_БК[] :String;
var SRT_FS[] :String;
var КОД_БК[] :String;
var КОД_ЭК[] :String;
var КОД_ВД[] :String;
var NAMEБК[] :String=ВзятьКоммент(КОД_БК[$]);
var ИСКЛБК[] :Logical;
var НОВ_БК[] :Logical;

2-- Процедуры и функции
Proc Очистить;
 ClearVariable(Buf);
 ClearVariable(tmp_ЭК);
 ClearVariable(use_БК);
 ClearVariable(key_FS);
 ClearVariable(Позиции);
 ClearVariable(NNN_БК);
 ClearVariable(SRT_БК);
 ClearVariable(SRT_FS);
 ClearVariable(КОД_БК);
 ClearVariable(КОД_ЭК);
 ClearVariable(КОД_ВД);
 ClearVariable(NAMEБК);
 ClearVariable(ИСКЛБК);
 ClearVariable(НОВ_БК);
end;

Func ChoosePatch(prevValue:String) :String;
var Путь :String;
var kk :Integer;
 kk=ChooseFolder(Путь, "Выберите путь для сохранения результатов поиска...");
 if kk=cmCancel: Message("Отказ от выбора пути для сохранения результатов поиска.", mtInformation); ^prevValue; fi;
 ^Путь;
end;

Proc УдалитьПустыеСтроки;
var Iter :Integer;
 Iter=1;
 while Iter<Позиции do if КОД_БК[Iter]="" and КОД_ЭК[Iter]="": Try DeleteFrame(Позиции, Iter); Except end; else Iter=Iter+1; fi; od;
end;

Proc НачальнаяСтрочка;
var nn :Integer;
 if Позиции<1: Try nn=InsertFrame(Позиции, 1); Except end; fi;
end;

Proc ДобавитьСтрочку(Iter:Integer);
var nn :Integer;
 Try nn=InsertFrame(Позиции, Iter+1); Except end;
 Template.Frame=Iter;
end;

Proc Удалить_Строчку(Iter:Integer);
 if EnqOkCancel("Вы уверены что хотите удалить данную строчку?", mtConfirmation)=cmOk:
   Try DeleteFrame(Позиции, Iter); if Позиции>0: Iter=if(Iter>1, Iter-1, 1); Template.Frame=Iter; else НачальнаяСтрочка; fi; Except end;
 fi;
end;

Func ОтменитьИзмененияУсловийОтчета :Logical;
var FF :Logical;
var qq :Integer;
 FF=False;
 if Позиции>1 or (Позиции=1 and КОД_БК[1]<>"" and КОД_ЭК[1]<>"" and КОД_ВД[1]<>""):
   if EnqOkCancel("Условия отбора данных для отчета изменились!^MОчистить отчет?", mtConfirmation)=cmOk:
     Очистить;
     НачальнаяСтрочка;
   else
     FF=True;
   fi;
 fi;
 ^FF;
end;

Func БК_Выбор(StoreБК:String): String;
var Value, tmp :String;
 if Match(StoreБК, "???.????.???????.???")    : tmp="ФКР." +StoreБК;
 |  Match(StoreБК, "???.?.??.?????.??.????")  : tmp="КД."  +StoreБК;
 |  Match(StoreБК, "???.??.??.??.??.??.????") : tmp="КИФД."+StoreБК;
 fi;
 Value=AnaElection("ФКР.???.????.???????.???|КД.???.?.??.?????.??.????|КИФД.???.??.??.??.??.??.????", False, False, tmp);
 if Value="": ^StoreБК; fi;
 ^Trim(SubStr(Value, Pos(".", Value)+1, 255));
end;

Func ЭК_Выбор(StoreЭК:String; Iter:Integer): String;
var Value :String;
 Value="";
 if КОД_БК[Iter]="": Message("Введите БК", mtError); Template.Field="КОД_БК"; Template.Frame=Iter; ^StoreЭК; fi;
 if Match(КОД_БК[Iter], "???.????.???????.???")    : Value=AnaElection("("+РАБ.БЮДЖЕТ2005.МаскаРасхКОСГУ    + "|КОСГУ.000)&КОСГУ.???", False, False, "КОСГУ."+StoreЭК);
 |  Match(КОД_БК[Iter], "???.?.??.?????.??.????")  : Value=AnaElection("("+РАБ.БЮДЖЕТ2005.МаскаДоходКОСГУ   + "|КОСГУ.000)&КОСГУ.???", False, False, "КОСГУ."+StoreЭК);
 |  Match(КОД_БК[Iter], "???.??.??.??.??.??.????") : Value=AnaElection("("+РАБ.БЮДЖЕТ2005.МаскаДефицитКОСГУ + "|КОСГУ.000)&КОСГУ.???", False, False, "КОСГУ."+StoreЭК);
 fi;
 if Value="": ^StoreЭК; fi;
 ^SubStr(Value, 7, 3);
end;

Func ВД_Выбор(StoreВД:String): String;
var RO, num, ii :Integer;
 RO=OpenWorkArea("РПО_БЮДЖ_КЛАСС", "CODE", "NAME_VOC='СЧ' and Match(CODE, '?')");
 Try
   num=Records(RO);
   if num>0:
     ClearVariable(Buf);
     for ii=1 to num do Buf[ii]=GetFieldS(RO, ii, "CODE")+"--"+GetFieldS(RO, ii, "TXT"); od;
     num=AlternateTree("Вид финансового обеспечения...", Buf, -1, Int(StoreВД), 12, "--", "", "Комментарий", -1, False);
     if num>0: ^(SubStr(Buf[num], 1, Pos("--", Buf[num])-1)); fi;
   fi;
 Finally
   CloseWorkArea(RO);
 end;
 ^StoreВД;
end;

Func ВыбратьРежимГруппировкиНовыхБК(ТекущийРежим:Integer) :Integer;
var num:Integer;
 ClearVariable(Buf);
 Buf[01]="... в  КОНЦЕ таблицы";
 Buf[02]="... в НАЧАЛЕ таблицы";
 Buf[03]="... по алфавиту (новые и старые БК вперемешку)";
 num=Alternate("Группировать новые БК...", Buf, -1, ТекущийРежим+1, 12);
 if not num>0: ^ТекущийРежим; else ^(num-1); fi;
end;

Proc ВыбратьРежимГруппировкиНовыхБК_Начать;
var NewOrder :Integer;
var SaveOK :Logical;
 SaveOK=False;
 NewOrder = ВыбратьРежимГруппировкиНовыхБК(Order_NewБК);
 if NewOrder<>Order_NewБК: if not ОтменитьИзмененияУсловийОтчета: SaveOK=True; fi; fi;
 if SaveOK: Order_NewБК=NewOrder; fi;
end;

Func ВзятьСимволСортировки(OrdСорт:Integer; даНовое:Logical) :String;
 if OrdСорт=0: ^if(даНовое, "1", "0"); -- БК в КОНЦЕ таблицы
 |  OrdСорт=1: ^if(даНовое, "0", "1"); -- БК в НАЧАЛЕ таблицы
 else ^"0";
 fi;
end;

Func TimeToHMSstring(valTime :Integer) :String;
var ihh, imm, icc :Integer;
var shh, smm, scc :String;
 shh=''; smm=''; scc='';
 ihh=Int(Trunc(valTime/3600));
 imm=Int(Trunc((valTime-ihh*3600)/60));
 icc=valTime-ihh*3600-imm*60;
 shh=Str(ihh); shh=RepStr('0', 2-Length(shh))+shh;
 smm=Str(imm); smm=RepStr('0', 2-Length(smm))+smm;
 scc=Str(icc); scc=RepStr('0', 2-Length(scc))+scc;
 ^(shh+':'+smm+':'+scc);
end;

Proc ПоискКБК_Начать;
var Acc, savТИП, savВФД, savКБК, curТИП, curВФД, curКБК, curСЧ8, curЭКД, Value, tmp :String;
var RO, R1, num, ii, count_acc, xx, jj, pp, nu2, i2, ab :Integer;
var Work, испДо, испПо, newБК :Logical;
 Hint("");
 ClearTrace(True);
 if SelectNewБК:
   if not ДАТОПЕР>1.1.2000: Message("Дата начала действия новой класификации^Mдолжна быть позже 01.01.2000.", mtError); Template.Field="ДАТОПЕР"; fi;
   if Order_NewБК<0 or Order_NewБК>2: Order_NewБК=0; fi;
 fi;
 if EnqOkCancel("Данные набранные 'вручную' будут утеряны.^MПродолжить?", mtWarning)=cmOk:
   ab=Time;
   Очистить;
   ShowProgress(0, "Подготовка...");
   RO=OpenWorkArea("РПО_БЮДЖ_КЛАСС", "CODE", "NAME_VOC='СЧ' and Match(CODE, '???.??.???') and not Match(CODE, 'ЗАБ.*') and S03<>''");
   R1=OpenWorkArea("РПО_БЮДЖ_КЛАСС", "CODE", "");
   Try
     if not Records(RO)>0: Message("Ошибка!^MВозможно картотека бюджетной классификации (РПО_БЮДЖ_КЛАСС) пустая.", mtError); Exit; fi;
     Refresh(False);
     num=0;
     for Account Acc="???.????.???????.???.?.???.??.???|???.?.??.?????.??.????.?.???.??.???|???.??.??.??.??.??.????.?.???.??.???" do num=num+1; od;
     ShowProgress(num, "Анализ...");
     savКБК="";
     savВФД="";
     savТИП="";
     jj=0;
     count_acc=0;
     for Account Acc="???.????.???????.???.?.???.??.???|???.?.??.?????.??.????.?.???.??.???|???.??.??.??.??.??.????.?.???.??.???", Sort do -- обязательно упорядоченно
       jj=jj+1;
       ProgressPos(jj);
       Work=False; испДо=False; испПо=False; newБК=False;
       if AccIsBalance(Acc): if OnlyUsedAcc: if AccountUsed(Acc): Work=True; fi; else Work=True; fi; fi;
       if Work:
         if SelectNewБК:
           испДо=AccountUsed(Acc, 1.1.100, ДАТОПЕР);
           испПо=AccountUsed(Acc, ДАТОПЕР, AddMon(ДАТОПЕР, 240));
           if испДо=False and испПо=True : newБК=True; fi;
         fi;
         --
         curКБК=""; curВФД=""; curСЧ8=""; curТИП="";
         if Match(Acc, "???.????.???????.???.?.???.??.???")    : curТИП="1"; curКБК=SubStr(Acc, 01, 20); curВФД=SubStr(Acc, 22, 01); curСЧ8=SubStr(Acc, 24, 10);
         |  Match(Acc, "???.?.??.?????.??.????.?.???.??.???")  : curТИП="2"; curКБК=SubStr(Acc, 01, 22); curВФД=SubStr(Acc, 24, 01); curСЧ8=SubStr(Acc, 26, 10);
         |  Match(Acc, "???.??.??.??.??.??.????.?.???.??.???") : curТИП="3"; curКБК=SubStr(Acc, 01, 23); curВФД=SubStr(Acc, 25, 01); curСЧ8=SubStr(Acc, 27, 10);
                      --123456789012345678901234567890123456
         fi;
         if curСЧ8<>"" and curТИП<>"":
           count_acc=count_acc+1;
           num=Search(RO, 1, curСЧ8);
           if num>0:
             if savКБК<>curКБК:
                -- для классификаций КД и ИФ код ЭК "000" игнорируется (так как счета со стандартными счетами обычно прописаны в структуре учета)
                if Match(savКБК, "???.????.???????.???"):
                  -- если не нашли для счета четко определенного КОСГУ (ЭК "000") и данная БК еще "не задействованна"
                  -- (на данном этапе мы подошли к следующему коду БК), то применяем КОСГУ 226 как наиболее распространенную
                  if SearchInArray(tmp_ЭК, "000", True, 1)>0 and SearchInArray(use_БК, savКБК, True, 1)<0:
                    Value="0#"+savТИП+"#"+savВФД+"#"+savКБК+"#226";
                    pp=SearchInArray(SRT_БК, Value, True, 1);
                    if not pp>0:
                      xx=InsertInArraySort(SRT_БК, Value);
                      InsertInArray(SRT_FS, xx, "0#"+savТИП+"#"+savВФД); -- тип классификации (КР КД ИФ) # вид финансового обеспечения
                      InsertInArray(КОД_БК, xx, savКБК);
                      InsertInArray(КОД_ЭК, xx, "226");
                      InsertInArray(КОД_ВД, xx, savВФД);
                      InsertInArray(ИСКЛБК, xx, if(count_acc<3, True, False));
                      AddInArray(key_FS, True, False, "0#"+savТИП+"#"+savВФД);
                    else
                      if SelectNewБК: if НОВ_БК[pp] and not newБК: НОВ_БК[pp]=False; fi; fi;
                    fi;
                  fi;
                |  Match(savКБК, "???.?.??.?????.??.????"):
                  if CheckДохAcc:
                    -- проверка на соответствие применяемого КОСГУ в счете для стандартных классификаций КД
                    tmp="000"+SubStr(savКБК, 5, 1)+SubStr(savКБК, 7, 2)+SubStr(savКБК, 10, 5)+SubStr(savКБК, 16, 2)+SubStr(savКБК, 19, 4)+"???";
                    SetFilter(R1, "Match(CODE, '"+tmp+"')");
                    nu2=Records(R1);
                    if nu2>0:
                      for i2=1 to nu2 do
                        tmp=SubStr(GetFieldS(R1, i2, "CODE"), 18, 3);
                        if Name_A("КОСГУ."+tmp)<>" " and tmp<>"000":
                          Value="0#"+savТИП+"#"+savВФД+"#"+savКБК+"#"+tmp;
                          pp=SearchInArray(SRT_БК, Value, True, 1);
                          if not pp>0:
                            xx=InsertInArraySort(SRT_БК, Value);
                            InsertInArray(SRT_FS, xx, "0#"+savТИП+"#"+savВФД);
                            InsertInArray(КОД_БК, xx, savКБК);
                            InsertInArray(КОД_ЭК, xx, tmp);
                            InsertInArray(КОД_ВД, xx, savВФД);
                            InsertInArray(ИСКЛБК, xx, False);
                            AddInArray(key_FS, True, False, "0#"+savТИП+"#"+savВФД);
                          else
                            if SelectNewБК: if НОВ_БК[pp] and not newБК: НОВ_БК[pp]=False; fi; fi;
                          fi;
                        fi;
                      od;
                    fi;
                  fi;
                fi;
                savКБК=curКБК;
                savВФД=curВФД;
                savТИП=curТИП;
                count_acc=0;
                ClearVariable(tmp_ЭК);
             fi;
             curЭКД=Trim(GetFieldS(RO, num, "S03")); -- строка КОСГУ связанных со счетом
             if Length(curЭКД)=3 and curЭКД<>"000": -- есть явно связанное КОСГУ
               Value="0#"+curТИП+"#"+curВФД+"#"+curКБК+"#"+curЭКД;
               pp=SearchInArray(SRT_БК, Value, True, 1);
               if not pp>0:
                 xx=InsertInArraySort(SRT_БК, Value);
                 InsertInArray(SRT_FS, xx, "0#"+curТИП+"#"+curВФД);
                 InsertInArray(КОД_БК, xx, curКБК);
                 InsertInArray(КОД_ЭК, xx, curЭКД);
                 InsertInArray(КОД_ВД, xx, curВФД);
                 InsertInArray(ИСКЛБК, xx, False);
                 InsertInArray(НОВ_БК, xx, newБК);
                 AddInArray(key_FS, True, False, "0#"+curТИП+"#"+curВФД);
               else
                 if SelectNewБК: if НОВ_БК[pp] and not newБК: НОВ_БК[pp]=False; fi; fi;
               fi;
               if SearchInArray(tmp_ЭК, curЭКД, True, 1)>0 or SearchInArray(tmp_ЭК, "000", True, 1)>0: ClearVariable(tmp_ЭК); fi;
               AddInArray(use_БК, True, False, curКБК);
             else -- КОСГУ целый набор
               for ii=1 to WordsCount(curЭКД, ",") do AddInArray(tmp_ЭК, True, False, ExtractWord(ii, curЭКД, ",")); od;
             fi;
           fi; --num>0:
         fi;
       fi;
     od;
     if SelectNewБК:
       num=LengthOfArray(SRT_БК);
       if num>0:
         ShowProgress(num, "Проверка...");
         for ii=1 to num do
           ProgressPos(ii);
           Value=ВзятьСимволСортировки(Order_NewБК, НОВ_БК[ii])+SubStr(SRT_БК[ii], 2, Length(SRT_БК[ii])-1);
           SRT_БК[ii]=Value;
           SRT_FS[ii]=if(НОВ_БК[ii], "1", "0")+SubStr(SRT_FS[ii], 2, Length(SRT_FS[ii])-1);
           if НОВ_БК[ii]: AddInArray(key_FS, True, False, SRT_FS[ii]); fi;
         od;
         Позиции=LengthOfArray(SRT_БК);
         SortSection("скцРАБ", "SRT_БК", True, False);
       fi;
     else
       Позиции=LengthOfArray(SRT_БК);
     fi;
   Finally
     CloseWorkArea(R1);
     CloseWorkArea(RO);
     CloseProgress;
     НачальнаяСтрочка;
   end;
   Trace(TimeToHMSstring(Time-ab));
 fi;
end;

Proc ПересортироватьТаблицу(chngIter:Integer);
var Value :String;
 Value=ВзятьСимволСортировки(Order_NewБК, НОВ_БК[chngIter])+SubStr(SRT_БК[chngIter], 2, Length(SRT_БК[chngIter])-1);
 SRT_БК[chngIter]=Value;
 SRT_FS[chngIter]=if(НОВ_БК[chngIter], "1", "0")+SubStr(SRT_FS[chngIter], 2, Length(SRT_FS[chngIter])-1);
 if НОВ_БК[chngIter]: AddInArray(key_FS, True, False, SRT_FS[chngIter]); fi;
 Позиции=LengthOfArray(SRT_БК);
 SortSection("скцРАБ", "SRT_БК", True, False);
end;

Func ПроверкаНаЗаполнение :Logical;
var ii :Integer;
 if Позиции>0 and КОД_БК[1]<>"":
   for ii=1 to Позиции do
     if Trim(КОД_БК[ii])="": Message("Не выбрано КБК"   , mtError); Template.Field="КОД_БК"; Template.Frame=ii; ^False;
     |  Trim(КОД_ЭК[ii])="": Message("Не выбрано КОСГУ" , mtError); Template.Field="КОД_ЭК"; Template.Frame=ii; ^False;
     |  Trim(КОД_ВД[ii])="": Message("Не выбрано ВД"    , mtError); Template.Field="КОД_ВД"; Template.Frame=ii; ^False;
     fi;
   od;
 else Message("Список БК пуст", mtError); ^False;
 fi;
 ^True;
end;

Proc ЗакрытьФайлПоОшибке(numberFile:Integer; FlagCreate:Logical; RESnameFile:String);
 if FlagCreate:
   TextFileClose(numberFile);
   Message("Ошибка записи в файл '"+RESnameFile+"'!", mtError);
 else
   Message("Ошибка создания файла '"+RESnameFile+"'!", mtError);
 fi;
end;

Func СформироватьИмяФайла(KEY:String) :String;
var ResName, НОВ, ТИП, ВФД, tmp1 :String;
 НОВ=ExtractWord(1, KEY, "#");
 ТИП=ExtractWord(2, KEY, "#");
 ВФД=ExtractWord(3, KEY, "#");
 if ТИП="1": tmp1="  ФКР";
 |  ТИП="2": tmp1="   КД";
 |  ТИП="3": tmp1=" КИФД";
 else  tmp1="";
 fi;
 ResName="Список БК"+tmp1+" по "+ВФД+if(НОВ="1", " новые", "")+".txt";
 ^ResName;
end;

Proc ПоискКБК_Сохранить;
var ii, num, jj, FS :Integer;
var FlagCreate :Logical;
var nameFile :String;
 --
 if Trim(FolderRes)="":  Message("Не выбрана папка для сохранения файла(ов) результата поиска!", mtWarning); Template.Field="FolderRes"; Exit; fi;
 УдалитьПустыеСтроки;
 if not ПроверкаНаЗаполнение: Exit; fi;
 num=LengthOfArray(key_FS);
 if not num>0: Message("Не найден список созданных имен файлов для выгрузки", mtError); Exit; fi;
 --
 if SelectNewБК: SortSection("скцРАБ", "SRT_FS", True, False); fi;
 ShowProgress(Позиции, "Запись в файл(ы)...");
 Try
   jj=1;
   for ii=1 to num do
     nameFile=FolderRes+СформироватьИмяФайла(key_FS[ii]);
     if nameFile<>"":
       Try
         Try if ExistFile(nameFile): DeleteFile(nameFile); fi; Except end;
         FlagCreate=False;
         FS=TextFileCreate(nameFile);
         FlagCreate=True;
         while key_FS[ii]=SRT_FS[jj] do
           ProgressPos(jj);
           if not ИСКЛБК[jj]: TextFileWriteLn(FS, КОД_БК[jj]+"|"+КОД_ЭК[jj]); fi;
           jj=jj+1;
         end; --while
       Except
         ЗакрытьФайлПоОшибке(FS, FlagCreate, nameFile);
         Raise;
       end;
       TextFileClose(FS);
     fi;
   od;
 Finally
   CloseProgress;
   if SelectNewБК: SortSection("скцРАБ", "SRT_БК", True, False); fi;
 end;
 Message("Операция заверешена");
end;

Proc ВнешнийВид_НовыеОтдельно(ТолькоИспользуемые:Logical);
 if not ТолькоИспользуемые: SelectNewБК=False; ДАТОПЕР=1.1.100; Order_NewБК=0; fi;
 cb_SelectNewБК.Enabled = ТолькоИспользуемые;
end;

Proc RemoveItem(БК_НФА:Logical);
var num, ii :Integer;
var DeleteOk :Logical;
 if Позиции>1 or (Позиции=1 and КОД_БК[1]<>"" and КОД_ЭК[1]<>"" and КОД_ВД[1]<>""):
   ShowProgress(Позиции, "Удаляем БК с "+if(БК_НФА, "", "НЕ")+" НФА...");
   Try
     ii=0;
     num=Позиции;
     while num>0 do
       ii=ii+1;
       ProgressPos(ii);
       DeleteOk=False;
       if (БК_НФА and Match(КОД_ЭК[num], "3?0")) or (not БК_НФА and not Match(КОД_ЭК[num], "3?0")): DeleteOk=True; fi;
       if DeleteOk:
         DeleteFromArray(SRT_БК, num);
         DeleteFromArray(SRT_FS, num);
         DeleteFromArray(КОД_БК, num);
         DeleteFromArray(КОД_ЭК, num);
         DeleteFromArray(КОД_ВД, num);
         DeleteFromArray(NAMEБК, num);
         DeleteFromArray(ИСКЛБК, num);
         DeleteFromArray(НОВ_БК, num);
       fi;
       num=num-1;
     od;
   Finally
     CloseProgress;
     Позиции=LengthOfArray(SRT_БК);
   end;
 fi;
end;

2-- События объектов
Proc btnOnClick(Sender:String); -- объекты при нажатии
 if Sender="btnClose"   : Close;
 |  Sender="btnПоиск"   : ПоискКБК_Начать;
 |  Sender="btnСхрнт"   : ПоискКБК_Сохранить; НачальнаяСтрочка;
 |  Sender="btnRemove1" : RemoveItem(True);  -- Убрать КБК с    НФА
 |  Sender="btnRemove2" : RemoveItem(False); -- Убрать КБК с НЕ НФА
 fi;
end;

Proc Флаги_onChange(Sender:String);
var Flag, Old, Work :Logical;
var nameVar :String;
var ОбъектИмя :Object;
 Work=False;
 if FindObject(Sender, ОбъектИмя): Work=True; fi;
 if Work:
   nameVar=SubStr(Sender, 4, Length(Sender)-3); -- вычисляем имя переменной - 3=cb_
   Flag=GetVariableL(nameVar); -- текущий статус;
   Old = not Flag; -- предыдущий статус
   if ОтменитьИзмененияУсловийОтчета: Flag=Old; fi;
   PutVariableL(nameVar, Flag);
   ОбъектИмя.State=Flag;
   if nameVar="OnlyUsedAcc": ВнешнийВид_НовыеОтдельно(Flag);
   |  nameVar="SelectNewБК": if Flag: if not ДАТОПЕР>1.1.1900: ДАТОПЕР=Dat(1, 1, Year(ToDay)); fi; fi;
   fi;
 fi;
end;

2-- События клеток
Func Field_onEnter(Field:String; Iter:Integer): Logical; -- на входе в клетку
 if Field="AR"           : ДобавитьСтрочку(Iter); ^False;
 |  Field="DR"           : Удалить_Строчку(Iter); ^False;
 |  Field="FolderRes"    : FolderRes = ChoosePatch(FolderRes); ^False;
 |  Field="ДАТОПЕР"      : oldDate=ДАТОПЕР;
 |  Field="Order_NewБК_" : ВыбратьРежимГруппировкиНовыхБК_Начать; ^False;
 |  Field="КОД_БК"       : КОД_БК[Iter]=БК_Выбор(КОД_БК[Iter]);       ^False;
 |  Field="КОД_ЭК"       : КОД_ЭК[Iter]=ЭК_Выбор(КОД_ЭК[Iter], Iter); ^False;
 |  Field="КОД_ВД"       : КОД_ВД[Iter]=ВД_Выбор(КОД_ВД[Iter]);       ^False;
 |  Field="ИСКЛБК"       : ИСКЛБК[Iter] = not ИСКЛБК[Iter]; ^False;
 |  Field="НОВ_БК"       : НОВ_БК[Iter] = not НОВ_БК[Iter]; ПересортироватьТаблицу(Iter); ^False;
 fi;
 ^True;
end;

Proc Field_onExit(Field:String; Iter:Integer); -- на выходе из клетки
 if Field="ДАТОПЕР": if ДАТОПЕР<>oldDate: if ОтменитьИзмененияУсловийОтчета: ДАТОПЕР=oldDate; fi; fi; fi;
end;

Func ВыборДаты(srcDate:Date) :Date;
var dd :Date;
 if srcDate>1.1.100: dd=Calendar(srcDate); else dd=Calendar(ToDay); fi;
 if not(dd<=1.1.100): ^dd; else ^srcDate; fi;
end;

Func GetDate :Date;  -- считываем в заданном поле дату
var name :String;
 name=AsString(Template.Field);
 if name="ДАТОПЕР": ^ДАТОПЕР; fi;
end;

Proc SetDate(Value:Date); -- устанавливаем в заданном поле дату; Value - значение даты, которое необходимо присвоить
var name :String;
 name=AsString(Template.Field);
 if name="ДАТОПЕР": ДАТОПЕР=Value; fi;
end;

Func Дата_onLookup(Sect:String; Row:Integer; Col:Integer; Cur:String) :String;
var dd, ddSave : Date;
 Template.HideEditor(False);
 ddSave=GetDate;
 dd=ВыборДаты(ddSave);
 if dd<>ddSave: if ОтменитьИзмененияУсловийОтчета: dd=ddSave; fi; fi;
 SetDate(dd);
 ^"";
end;

2-- События шаблона
Proc Template_OnOpen(Create:Logical); -- при открытии шаблона
 Очистить;
 НачальнаяСтрочка;
 OnlyUsedAcc=False;
 ВнешнийВид_НовыеОтдельно(OnlyUsedAcc);
end;

Proc Template_OnClose(Destroy:Logical); -- при закрытии шаблона
 Очистить;
end;

КОНЕЦ -- конец бланка