БЛАНКСШАБЛОНОМ "Поиск НФА";
-- Разработка бланка: ТБ.БЮДЖЕТ
-- Первый релиз: 03.03.2010
var SORT_MENU	:s='09';

-- Объекты
btnExit:Object;   cb_Забаланс:Object; секцArray:Object;
btnCalc:Object;   lblVersion :Object;

СекцШапка:Object;   СекцWorkЗТ:Object;
СекцУслов:Object;   СекцWorkДТ:Object;
СекцUСорт:Object;   СекцWorkИТ:Object;
СекцДатОт:Object;   СекцСортДТ:Object;

-- Переменные
flgЗабаланс	 :Logical;
Позиции 	 :Integer;
lenArray	 :Integer;
TimeCreationRep  :String;

var btnName_menu :String='Поиск НФА по наименованию или его части';
var infoVersion  :String="Версия отчета: 1.11.0318";
var Фокус	 :String;
var pfxУЧН	 :String="УЧН";
var Расшифр	 :String="&";

var Flag_onEnter :Logical;
ДАТОПЕР 	 :Date;2 0    -- дата отчета
var oldDate	 :Date;     -- для запоминания и возвратов
всегоСУМОСТ	 :Numeric;

ГдеИскать1	 :Integer;    var ГдеИскать1_	 :Integer=ГдеИскать1;
ГдеИскать2	 :Integer;    var ГдеИскать2_	 :Integer=ГдеИскать2;
ГдеИскать3	 :Integer;    var ГдеИскать3_	 :Integer=ГдеИскать3;
КакСоед1	 :Integer;    var КакСоед1_	 :Integer=КакСоед1;
КакСоед2	 :Integer;    var КакСоед2_	 :Integer=КакСоед2;
Образец1	 :String;
Образец2	 :String;
Образец3	 :String;
UserSortField	 :Integer;    var UserSortField_ :Integer=UserSortField;

var LST_UNQ[]	 :String;
var LST_KOL[]	 :Numeric;
var LST_SUM[]	 :Numeric;
var rНФА_LS[]	 :String;
var rНФА_ММ[]	 :String;

тКОДНФА[]	 :String;
тИМЯНФА[]	 :String;
тКОДМОЛ[]	 :String;
тИМЯМОЛ[]	 :String;
тКОДМХЭ[]	 :String;
тИМЯМХЭ[]	 :String;
тСУМОСТ[]	 :Numeric;
тКОЛОСТ[]	 :Numeric;
тНОМУЧН[]	 :String;
тНОМИНВ[]	 :String;
тКОДКБК[]	 :String;
тДАТЭКС[]	 :Date;
тКОДСЧТ[]	 :String;
тКОДИСТ[]	 :String;

var Buf[]	 :String;
var aAna[]	 :String;
var НПП[]	 :Integer=$;
var bindVOC[]	 :String;
var bindINT[]	 :Integer;

Proc ОчиститьLST;
 ClearVariable(LST_UNQ);
 ClearVariable(LST_KOL);
 ClearVariable(LST_SUM);
 ClearVariable(rНФА_LS);
 ClearVariable(rНФА_ММ);
end;


Proc Очистить;
 ClearVariable(Buf);
 ClearVariable(aAna);
 ClearVariable(НПП);
 ClearVariable(bindVOC);
 ClearVariable(bindINT);
 ОчиститьLST;
end;

Proc ОчиститьТаблицу;

 ClearVariable(Позиции);
 ClearVariable(НПП);

 ClearVariable(тКОДНФА);
 ClearVariable(тИМЯНФА);
 ClearVariable(тКОДМОЛ);
 ClearVariable(тИМЯМОЛ);
 ClearVariable(тКОДМХЭ);
 ClearVariable(тИМЯМХЭ);
 ClearVariable(тСУМОСТ);
 ClearVariable(тКОЛОСТ);
 ClearVariable(тНОМУЧН);
 ClearVariable(тНОМИНВ);
 ClearVariable(тКОДКБК);
 ClearVariable(тДАТЭКС);
 ClearVariable(тКОДСЧТ);
 ClearVariable(тКОДИСТ);

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 Объединить(Value1:String; Value2:String; Separator:String) :String;
var Ret :String;
 if Value1<>"" and Value2<>"": Ret=Value1+Separator+Value2;
 |  Value1= "" and Value2<>"": Ret=Value2;
 |  Value1<>"" and Value2="" : Ret=Value1;
 |  True: Ret="";
 fi;
 ^Ret;
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 ValidateВедомостьSection(СкрытьТаблицу:Logical);
var FF :Logical;
 if Позиции>0 and not СкрытьТаблицу: FF=True; else FF=False; fi;
 СекцWorkЗТ.Visible=FF;
 СекцWorkДТ.Visible=FF;
 СекцWorkИТ.Visible=FF;
end;

Proc ValidateОтчетSection;
 ValidateВедомостьSection(False);
end;

Proc ОчисткаОтчета;
 Очистить;
 ОчиститьТаблицу;
 TimeCreationRep="";
 ValidateОтчетSection;
end;

Proc ValidateSection(СкрытьУсловия:Logical);
var Flag :Logical;
 ShowProgress(1, "Работаем...");
 Try
   Flag = not СкрытьУсловия;
   --
   СекцШапка.Visible=Flag;
   СекцУслов.Visible=Flag;
   СекцUСорт.Visible=Flag;
   СекцДатОт.Visible=Flag;
   --
   btnCalc.Visible=Flag;
   --
   ValidateОтчетSection;
   --
 Finally
   CloseProgress;
 end;
end;

Func ОтменитьИзмененияУсловийОтчета :Logical;
var FF :Logical;
var qq :Integer;
 FF=False;
 if Позиции>0:
   qq=EnqOkCancel("Условия отбора данных для отчета изменились!^MОчистить отчет?", mtConfirmation);
   if qq=cmOk: ОчисткаОтчета;
   |  qq=cmCancel: FF=True;
   fi;
 fi;
 ^FF;
end;

Proc Инициализация;
 lblVersion.Caption=infoVersion;
 oldDate=ДАТОПЕР;
 ValidateSection(False);
end;

Proc ПересортировкаВедомости(countIter:Integer; полеСортировки:Integer);
var NameSortField :String;
 if countIter>0:
   if полеСортировки=01: NameSortField="тИМЯНФА";
   |  полеСортировки=02: NameSortField="тКОДМОЛ";
   |  полеСортировки=03: NameSortField="тИМЯМОЛ";
   |  полеСортировки=04: NameSortField="тКОДМХЭ";
   |  полеСортировки=05: NameSortField="тИМЯМХЭ";
   |  полеСортировки=06: NameSortField="тСУМОСТ";
   |  полеСортировки=07: NameSortField="тКОЛОСТ";
   |  полеСортировки=08: NameSortField="тНОМУЧН";
   |  полеСортировки=09: NameSortField="тНОМИНВ";
   |  полеСортировки=10: NameSortField="тКОДКБК";
   |  полеСортировки=11: NameSortField="тДАТЭКС";
   |  полеСортировки=12: NameSortField="тКОДСЧТ";
   |  полеСортировки=13: NameSortField="тКОДИСТ";
   else NameSortField="тКОДНФА";
   fi;
   Позиции=countIter;
   ShowProgress(1, "Сортировка данных отчета...");
   Try
     SortSection("СекцСортДТ", NameSortField, True, False);
     ClearVariable(НПП);
   Finally
     CloseProgress;
   end;
 fi;
end;

Proc ВыбратьUserПолеСортировки;
var num, prevState, curState :Integer;
 prevState=UserSortField;
 ClearVariable(Buf);
 Buf[01]="... коду НФА";
 Buf[02]="... наименованию НФА";
 Buf[03]="... коду МОЛ";
 Buf[04]="... Ф.И.О. МОЛ";
 Buf[05]="... коду местонахождения";
 Buf[06]="... наименованию местонахождения";
 Buf[07]="... балансовой сумме";
 Buf[08]="... количеству";
 Buf[09]="... учетному номеру НФА";
 Buf[10]="... инвентарному номеру НФА";
 Buf[11]="... коду КБК";
 Buf[12]="... дате ввода в эксплуатацию";
 Buf[13]="... счету синтетическому";
 Buf[14]="... источнику средств";
 num=Alternate("Сортировать по...", Buf, -1, prevState+1, 12);
 if num=0: Exit; fi;
 curState=num-1;
 if curState<>prevState: UserSortField=curState; ПересортировкаВедомости(LengthOfArray(тКОДНФА), curState); fi;
end;

Func ВыбратьОператорУсловия(PrevValue:Integer; onExit:Logical) :Integer;
var num, prevState, curState :Integer;
var SaveValue :Logical;
 SaveValue=False;
 prevState=PrevValue;
 if onExit:
   curState=0;
 else
   ClearVariable(Buf);
   Buf[1]="Отмена условия";
   Buf[2]="Строка-образец строго в начале строки";
   Buf[3]="Строка-образец в середине строки";
   Buf[4]="Строка-образец строго в конце строки";
   num=Alternate("Расположение строки-образеца", Buf, -1, prevState+1, 12);
   if num=0: ^PrevValue; fi;
   curState=num-1;
 fi;
 if curState<>prevState: if not ОтменитьИзмененияУсловийОтчета: SaveValue=True; fi; fi;
 if SaveValue: ^curState; else ^PrevValue; fi;
end;

Func ВыбратьОператорСоединения(PrevValue:Integer; onExit:Logical) :Integer;
var num, prevState, curState :Integer;
var SaveValue :Logical;
 SaveValue=False;
 prevState=PrevValue;
 if onExit:
   curState=0;
 else
   ClearVariable(Buf);
   Buf[1]="*--Отмена условия";
   Buf[2]="И--(выполнение одновременно обоих соединяемых условий)";
   Buf[3]="ИЛИ--(выполнение хотя бы одного из соединяемых условий)";
   Buf[4]="КРОМЕ--(строка-образец исключается из отбора)";
   num=AlternateTree("Выберите оператор соединения условий", Buf, -1, prevState+1, 12, "|", "Оператор", "Расшифровка оператора (пояснение)", -1, False);
   if num=0: ^PrevValue; fi;
   curState=num-1;
 fi;
 if curState<>prevState: if not ОтменитьИзмененияУсловийОтчета: SaveValue=True; fi; fi;
 if SaveValue: ^curState; else ^PrevValue; fi;
end;

Func СчетаНФА_вУчете(maskСЧТ:String; ddBP:Date; ddEP:Date) :Integer;
var Путь, Acc :String;
var num, kk :Integer;
var Отч1 :Report;
 ClearVariable(Buf);
 Путь=PlanVar("НФА")+"\ОТЧЕТЫ\НФАОТЧ2007.lst";
 if not ExistFile(Путь): ^-1; fi;
 Try
   Отч1=RepOpen(Путь+"|По_счетам_НФА_Бал_Заб", maskСЧТ, "", if(ddBP>1.1.1990, ddBP, 1.1.100), if(ddEP>1.1.1990, ddEP, ToDay));
   RepReset(Отч1);
   Try
     num=RepRowsCount(Отч1);
     kk=0;
     while RepNext(Отч1) do
       Acc=RepIdent(Отч1);
       if Match(Acc, "???.????.???????.???.?.???.??.???")    or
	  Match(Acc, "???.??.??.??.??.??.????.?.???.??.???") or
	  Match(Acc, "ЗАБ.??.???.??"):
	 kk=kk+1;
	 Buf[kk]=Объединить(SignsMask(Acc, True), SignsMask(Acc, False), "|");
       fi;
     end; -- while
   Finally
     Отч1=RepClose(Отч1);
   end;
 Except
   ^-1;
 end;
 ^LengthOfArray(Buf);
end;

Func СчетаНФА_поСтруктуре(maskСЧТ:String) :Integer;
var Acc :String;
var kk :Integer;
 ClearVariable(Buf);
 kk=0;
 for Account Acc=maskСЧТ, Sort do 
   kk=kk+1;
   Buf[kk]=Объединить(SignsMask(Acc, True), SignsMask(Acc, False), "|");
 od;
 ^LengthOfArray(Buf);
end;

Func СправочникиСтруктурыПоМаскеСчетовПрогресс(maskСЧТ:String; ddBP:Date; ddEP:Date; OnlyUseAcc:Logical; EnableProgress:Logical) :String;
var Voc, MaskVoc :String;
var xx, ii, num, jj, kk :Integer;
var qq :Numeric;
 Try qq=Saldo(maskСЧТ, 1.1.100); Except ^" "; end;
 ClearVariable(bindVOC); ClearVariable(bindINT);
 if EnableProgress: ShowProgress(0, "Подготовка..."); fi;
 MaskVoc="";
 Try
   xx=0;
   if OnlyUseAcc: xx=СчетаНФА_вУчете(maskСЧТ, ddBP, ddEP); fi;
   if not xx>0:   xx=СчетаНФА_поСтруктуре(maskСЧТ); fi;
   if xx>0:
     if EnableProgress: ShowProgress(xx, "Анализ привязки справочников к счетам..."); fi;
     for ii=1 to xx do
       if EnableProgress: ProgressPos(ii); fi;
       num=WordsCount(Buf[ii], "|");
       for jj=1 to num do
	 Voc=ExtractWord(jj, Buf[ii], "|");
	 kk=SearchInArray(bindVOC, Voc, True, 1);
	 if kk>0:
	   bindINT[kk]=bindINT[kk]+1;
	 else
	   kk=InsertInArraySort(bindVOC, Voc);
	   InsertInArray(bindINT, kk, 1);
	 fi;
       od;
     od;
     num=LengthOfArray(bindVOC);
     if num>0:
       if EnableProgress: ShowProgress(num, "Обработка полученных данных..."); fi;
       jj=num; -- удаляем с конца
       for ii=1 to num do
	 if EnableProgress: ProgressPos(ii); fi;
	 -- xx - количество рабочих счетов
	 if bindINT[jj]<>xx: DeleteFromArray(bindVOC, jj); else MaskVoc=Объединить(MaskVoc, bindVOC[jj], "|"); fi;
	 jj=jj-1;
       od;
     fi;
   fi; -- xx>0
 Finally
   if EnableProgress: CloseProgress; fi;
 end;
 ^MaskVoc;
end;

Func КорректныеСимволыНаименования(Value:String) :Logical;
var num, ii, intChars :Integer;
var Chars :String;
 num=Length(Value);
 if num>0:
   for ii=1 to num do
     Chars=SubStr(Value, ii, 1);
     intChars=Ascii(Chars);
     if intChars <  32 or
	intChars =  33 or -- !
	intChars =  38 or -- &
--	  intChars =  40 or -- ( тестировать
--	  intChars =  41 or -- ) тестировать
	intChars =  42 or -- *
--	  intChars =  47 or -- / тестировать
	intChars =  63 or -- ?
	intChars = 124 or -- |
	intChars = 126 or -- ~
	intChars > 255 :
	  Message("В строке для поиска введен запрещенный символ "+Chr(150)+" '"+Chars+"'!", mtError);
	  ^False;
     fi;
   od;
 fi;
 ^True;
end;

Func КорректныеУсловияПоиска :Logical;
 Образец1=Trim(Образец1);
 Образец2=Trim(Образец2);
 Образец3=Trim(Образец3);
 if Образец1<>"" and not ГдеИскать1>0:
   Message("Выберите, где искать образец строки для УСЛОВИЯ 1", mtWarning);
   Template.Field="ГдеИскать1_";
   ^False;
 fi;
 if Образец2<>"" and not ГдеИскать2>0:
   Message("Выберите, где искать образец строки для УСЛОВИЯ 2", mtWarning);
   Template.Field="ГдеИскать2_";
   ^False;
 fi;
 if Образец3<>"" and not ГдеИскать3>0:
   Message("Выберите, где искать образец строки для УСЛОВИЯ 3", mtWarning);
   Template.Field="ГдеИскать3_";
   ^False;
 fi;
 if Образец1<>"" and Образец2="" and Образец3<>"":
   ГдеИскать2=ГдеИскать3; ГдеИскать3=0;
     Образец2=Образец3;   Образец3="";
 fi;
 if Образец1<>"" and Образец2<>"" and not КакСоед1>0:
   Message("Не выбран оператор соединения УСЛОВИЯ 1 и УСЛОВИЯ 2", mtWarning);
   Template.Field="КакСоед1_";
   ^False;
 fi;
 if Образец2<>"" and Образец3<>"" and not КакСоед2>0:
   Message("Не выбран оператор соединения УСЛОВИЯ 2 и УСЛОВИЯ 3", mtWarning);
   Template.Field="КакСоед2_";
   ^False;
 fi;
 ^True;
end;

--Func USE_ИНВЕНТАРНЫЙ_НОМЕР(ACC:String; SUM:Numeric; QUA:Numeric; ddОТЧ:Date; FindУЧН:String; ctНФА100П:Numeric; ctНФА_ИНВ:Numeric) :Logical;
--var Цена :Numeric;
-- if Match(ACC, "*.?.101.??.???"):
--    if Match(ACC, "*.?.101.?7.???"):
--	 if ddОТЧ>=1.1.2009 and ctНФА100П>0.00:
--	   if SUM<>0.00 and QUA<>0.00:
--	     SUM=Abs(SUM);
--	     QUA=Abs(QUA);
--	     Цена=SUM/QUA;
--	     if Цена>ctНФА100П: ^True; fi;
--	   |  SUM=0 or QUA=0:
--	     if Match(FindУЧН, pfxУЧН+".*"): ^True; fi;
--	   fi;
--	 fi;
--    else
--	 if ctНФА_ИНВ>0.00:
--	   if SUM<>0.00 and QUA<>0:
--	     SUM=Abs(SUM);
--	     QUA=Abs(QUA);
--	     Цена=SUM/QUA;
--	     if Цена>ctНФА_ИНВ:
--	       ^True;
--	     else
--	       -- рассматриваем вариант конвертации
--	       --if Match(FindУЧН, pfxУЧН+".*"): if FindУЧН=pfxУЧН+".ДО3000" or (ddОТЧ>=1.1.2009 and Цена>1000 and Цена<=3000): ^False; else ^True; fi; fi;
--	       if Match(FindУЧН, pfxУЧН+".*"): ^True; fi;
--	     fi;
--	   | SUM=0 or QUA=0:
--	     if Match(FindУЧН, pfxУЧН+".*"): ^True; fi;
--	   fi;
--	 fi;
--    fi;
-- |  Match(ACC, "*.?.102.??.???"): ^True;
-- |  Match(ACC, "*.?.103.??.???"): ^True;
-- fi;
-- ^False;
--end;

Func USE_ИНВЕНТАРНЫЙ_НОМЕР(ACC:String; SUM:Numeric; KOL:Numeric; ddОТЧ:Date; FindУЧН:String; ctНФА100П:Numeric; ctНФА_ИНВ:Numeric) :Logical;
var Цена :Numeric;
 if Match(ACC, "*.?.101.??.???"):
    if Match(ACC, "*.?.101.?7.???"):
      if Match(FindУЧН, pfxУЧН+".*"): ^True; else if ctНФА100П>0.00 and SUM<>0.00 and KOL<>0.00: Цена=Abs(SUM)/Abs(KOL); if Цена>ctНФА100П: ^True; fi; fi; fi;
    else 
      if Match(FindУЧН, pfxУЧН+".*"): ^True; else if ctНФА_ИНВ>0.00 and SUM<>0.00 and KOL<>0.00: Цена=Abs(SUM)/Abs(KOL); if Цена>ctНФА_ИНВ: ^True; fi; fi; fi;
    fi;
 |  Match(ACC, "*.?.102.??.???"): ^True;
 |  Match(ACC, "*.?.103.??.???"): ^True;
 fi;
 ^False;
end;

Func ВзятьИсточникСредств(Value:String) :String;
 if Value="1": ^"бюджет";
 |  Value="2": ^"внебюджет";
 |  Value="З": ^"забаланс";
 else ^"";
 fi;
end;

Func ПоискДанных(MskAcc:String; ДатОтч:Date; ЕстьЗабаланс:Logical; valSearch1:String; valSearch2:String; valSearch3:String; Link_S1S2:String; Link_S2S3:String) :Logical;
var ВременныйФайл, aVal1, aVal2, aDeb, aCre, aComment, КОДСЧТ, КОДНФА, REFНФА, КОДУЧН, КОДМОЛ, КОДМХЭ, svrANA, tmp :String;
var Режим, okData, СЧДЕБ, БЕЗУЧН, useУЧН, Work, flg1, flg2, flg3, link1, link2 :Logical;
var aSum1, aSum2, SUM, QUA, KOL, constНФА100П, constНФА_ИНВ :Numeric;
var len, xx, ii, jj, pp, мм1 :Integer;
var aDate :Date;
 okData=False;
 Refresh(False);
 Режим=AutoRefresh;
 ToggleAutoRefresh(False);
 ShowProgress(0, "Подготовка данных...");
 Try
   ОчиститьLST;
   TimeCreationRep="Время создания отчета: "+DateToString(ToDay)+" "+TimeToHMSstring(Time);
   -- Константы НФА
   Try SUM=Com_Var("ОС_100" , ДатОтч); Except SUM=0.00; end;
   if not SUM>0: if ДатОтч>=1.1.2011: SUM=40000; else SUM=20000; fi; fi;
   constНФА100П=SUM;
   Try SUM=Com_Var("ОС_РАСХ" , ДатОтч); Except SUM=0.00; end;
   if not SUM>0: if ДатОтч>=1.1.2009: SUM=3000; else SUM=1000; fi; fi;
   constНФА_ИНВ=SUM;
   --
   ClearVariable(aAna);
   ВременныйФайл=PlanVar('CACHE')+"\"+GetGUID;
   if ExistFile(ВременныйФайл): DeleteFile(ВременныйФайл); fi;
   xx=TujRepBalAccount+TujRepNoNullBal+TujRepCombinedAna+if(ЕстьЗабаланс, TujRepZabalance, 0);
   мм1=0;
   len=TujReport(ВременныйФайл, 1.1.100, ДатОтч, MskAcc, "НФА.*", "ДНФА", "", "", xx, False);
   if len>0:
      OpenTextJur(ВременныйФайл);
      Try
	ShowProgress(len, "Выборка остатков НФА...");
	ii=0;
	while not GetTransFromTextJur(aDate, aSum1, aVal1, aSum2, aVal2, aDeb, aCre, aAna, aComment) do
	  ii=ii+1;
	  ProgressPos(ii);
	  Work=False;
	  -- Поиск аналитики
	  КОДНФА=""; REFНФА=""; КОДУЧН=""; КОДМОЛ=""; КОДМХЭ=""; QUA=0.00;
	  xx=LengthOfArray(aAna);
	  if xx>0:
	    for jj=1 to xx do
	      pp=Pos(":", aAna[jj]);
	      if pp>0:
		Try QUA=StringToNumeric(SubStr(aAna[jj], pp+1, Length(aAna[jj])-pp)); Except QUA=0.00; end;
		svrANA=SubStr(aAna[jj], 1, pp-1);
	      else
		svrANA=aAna[jj];
	      fi;
	      tmp=SubStr(svrANA, 1, 1);
	      if tmp="+" or tmp="-": svrANA=SubStr(svrANA, 2, 255); fi;
	      if Match(svrANA, "НФА.*"):
		КОДНФА=svrANA;
	      |  Match(svrANA, pfxУЧН+".*"):
		КОДУЧН=svrANA;
	      |  Match(svrANA, "МОЛ.*"):
		КОДМОЛ=svrANA;
	      |  Match(svrANA, "М.*"):
		КОДМХЭ=svrANA;
	      fi;
	    od;
	    if КОДНФА<>"":
	      REFНФА=Trim(Name_A(КОДНФА));
	      if REFНФА<>"":
		flg1=False; flg2=False; flg3=False;
		if valSearch1<>"": flg1=Match(REFНФА, valSearch1); else flg1=True; fi;
		if valSearch2<>"": flg2=Match(REFНФА, valSearch2); else flg2=True; fi;
		if valSearch3<>"": flg3=Match(REFНФА, valSearch3); else flg3=True; fi;
		if flg1 and flg2 and flg3:
		  link1=False; link2=False;
		  if Link_S1S2="and": if flg1 and     flg2: link1=True; else link1=False; fi;
		  |  Link_S1S2="orr": if flg1 or      flg2: link1=True; else link1=False; fi;
		  |  Link_S1S2="not": if flg1 and not flg2: link1=True; else link1=False; fi;
		  else link1=True;
		  fi;
		  if Link_S2S3="and": if flg2 and     flg3: link2=True; else link2=False; fi;
		  |  Link_S2S3="orr": if flg2 or      flg3: link2=True; else link2=False; fi;
		  |  Link_S2S3="not": if flg2 and not flg3: link2=True; else link2=False; fi;
		  else link2=True;
		  fi;
		  if link1 and link2: Work=True; fi;
		fi;
	      fi;
	    fi;
	  fi; --xx>0
	  if Work:
	    КОДСЧТ=""; REFНФА=""; SUM=0.00; KOL=0.00;
	    if aDeb="00" or aDeb="00Z": КОДСЧТ=aCre; СЧДЕБ=False; fi;
	    if aCre="00" or aCre="00Z": КОДСЧТ=aDeb; СЧДЕБ=True;  fi;
	    if Match(КОДСЧТ, "???.????.???????.???.?.101.??.???")   : КОДСЧТ=SubStr(КОДСЧТ, 1, 30)+"???";		  БЕЗУЧН=False;
	    |  Match(КОДСЧТ, "???.????.???????.???.?.102.??.???")   : КОДСЧТ=SubStr(КОДСЧТ, 1, 30)+"???";		  БЕЗУЧН=False;
	    |  Match(КОДСЧТ, "???.????.???????.???.?.105.??.???")   : КОДСЧТ=SubStr(КОДСЧТ, 1, 30)+"???";		  БЕЗУЧН=True;
	    |  Match(КОДСЧТ, "ЗАБ.??.10?.??")			    : if ЕстьЗабаланс: КОДСЧТ=КОДСЧТ; else КОДСЧТ=""; fi; БЕЗУЧН=True;
--	      |  Match(КОДСЧТ, "???.??.??.??.??.??.????.?.101.08.???"): КОДСЧТ=SubStr(КОДСЧТ, 1, 33)+"???";		    БЕЗУЧН=True;
	    else КОДСЧТ="";
	    fi;
	    if КОДСЧТ<>"":
	      if (aVal1="" or aVal1="РУБ") and aSum1<>0: if СЧДЕБ: SUM=aSum1; else SUM=-aSum1; fi;
	      |  (aVal2="" or aVal2="РУБ") and aSum2<>0: if СЧДЕБ: SUM=aSum2; else SUM=-aSum2; fi;
	      else SUM=0.00;
	      fi;
	      KOL=if(СЧДЕБ, QUA, -QUA);
	      -- Анализируем найденные признаки
	      if Trim(КОДМОЛ)="": КОДМОЛ="МОЛ.@@@"; fi;
	      if Trim(КОДМХЭ)="": КОДМХЭ="М.Э.@@@"; fi;
	      -- Анализ учетных номеров
	      useУЧН=USE_ИНВЕНТАРНЫЙ_НОМЕР(КОДСЧТ, SUM, KOL, ДатОтч, КОДУЧН, constНФА100П, constНФА_ИНВ);
	      if БЕЗУЧН or Trim(КОДУЧН)="" or not useУЧН: КОДУЧН="УЧН.@@@"; fi;
	      -- НФА
	      xx=SearchInArray(rНФА_LS, КОДНФА, True, 1);
	      if xx=-1:
		мм1=мм1+1;
		REFНФА=Format("%.10d", мм1);
		pp=InsertInArraySort(rНФА_LS, КОДНФА);
		InsertInArray(rНФА_ММ, pp, REFНФА);
	      else
		REFНФА=rНФА_ММ[xx];
	      fi;
	      -- Формируем идентификатор строки отчета
	      svrANA=REFНФА+"#"+КОДУЧН+"#"+КОДСЧТ+"#"+КОДМОЛ+"#"+КОДМХЭ;
		 --  10    + 1 + 30   + 1 + 40	 + 1 + 80   + 1 + 80
	      xx=SearchInArray(LST_UNQ, svrANA, True, 1);
	      if xx=-1:
		pp=InsertInArraySort(LST_UNQ, svrANA);
		InsertInArray(LST_KOL, pp, KOL);
		InsertInArray(LST_SUM, pp, SUM);
	      else
		LST_KOL[xx]=LST_KOL[xx]+KOL;
		LST_SUM[xx]=LST_SUM[xx]+SUM;
	      fi;
	    fi; -- КОДСЧТ<>""
	  fi;
	end; -- while
      Finally
	CloseTextJur;
      end; -- Try
      Try DeleteFile(ВременныйФайл); Except end;
   fi; -- len>0 (TujReport)
   len=LengthOfArray(LST_UNQ);
   if len>0:
     if мм1>0:
       lenArray=мм1;
       CloseProgress;
       ShowProgress(1, "Сортировка промежуточных данных...");
       SortSection(lenArray, "rНФА_ММ", True, False);
     fi;
     ShowProgress(len, "Формирование ведомости...");
     ОчиститьТаблицу;
     ValidateОтчетSection;
     xx=0;
     for ii=1 to len do
       КОДНФА=""; REFНФА=""; КОДУЧН=""; КОДМОЛ=""; КОДМХЭ=""; SUM=0.00; KOL=0.00;
       REFНФА = Trim(ExtractWord(1, LST_UNQ[ii], "#"));
       КОДУЧН = Trim(ExtractWord(2, LST_UNQ[ii], "#"));
       if КОДУЧН="УЧН.@@@": КОДУЧН=""; fi;
       КОДСЧТ = Trim(ExtractWord(3, LST_UNQ[ii], "#"));
       КОДМОЛ = Trim(ExtractWord(4, LST_UNQ[ii], "#"));
       КОДМХЭ = Trim(ExtractWord(5, LST_UNQ[ii], "#"));
       pp=Int(REFНФА);
       if pp>0: КОДНФА=rНФА_LS[pp]; else КОДНФА=""; fi;
       SUM=LST_SUM[ii];
       KOL=LST_KOL[ii];
       if ValidSign(КОДНФА): Work=True; else Work=False; fi;
       if Work and (SUM<>0.00 or KOL<>0.00):
	 xx=xx+1;
	 тКОДНФА[xx]=КОДНФА;
	 тИМЯНФА[xx]=Trim(Name_A(КОДНФА));
	 тКОДМОЛ[xx]=КОДМОЛ;
	 тИМЯМОЛ[xx]=Trim(Name_A(КОДМОЛ));
	 if тИМЯМОЛ[xx]="": if КОДМОЛ="МОЛ.@@@": тИМЯМОЛ[xx]="> нет кода МОЛ"; else тИМЯМОЛ[xx]=КОДМОЛ; fi; fi;
	 тКОДМХЭ[xx]=КОДМХЭ;
	 тИМЯМХЭ[xx]=Trim(Name_A(КОДМХЭ));
	 if тИМЯМХЭ[xx]="": if КОДМХЭ="М.Э.@@@": тИМЯМХЭ[xx]="> нет кода М";   else тИМЯМХЭ[xx]=КОДМХЭ; fi; fi;
	 тСУМОСТ[xx]=SUM;
	 тКОЛОСТ[xx]=KOL;
	 тНОМУЧН[xx]=КОДУЧН;
	 тНОМИНВ[xx]=Trim(Name_A("ИНВВЕД."+КОДНФА+"."+КОДУЧН));
	 if Match(КОДСЧТ, "???.????.???????.???.?.101.??.???")	 : тКОДИСТ[xx]=SubStr(КОДСЧТ, 22, 1); тКОДКБК[xx]=SubStr(КОДСЧТ, 1, 20); тКОДСЧТ[xx]=SubStr(КОДСЧТ, 24, 6);
	 |  Match(КОДСЧТ, "???.????.???????.???.?.102.??.???")	 : тКОДИСТ[xx]=SubStr(КОДСЧТ, 22, 1); тКОДКБК[xx]=SubStr(КОДСЧТ, 1, 20); тКОДСЧТ[xx]=SubStr(КОДСЧТ, 24, 6);
	 |  Match(КОДСЧТ, "???.????.???????.???.?.105.??.???")	 : тКОДИСТ[xx]=SubStr(КОДСЧТ, 22, 1); тКОДКБК[xx]=SubStr(КОДСЧТ, 1, 20); тКОДСЧТ[xx]=SubStr(КОДСЧТ, 24, 6);
	 |  Match(КОДСЧТ, "ЗАБ.??.10?.??")			 : тКОДИСТ[xx]="З";		      тКОДКБК[xx]="ЗАБАЛАНС";		 тКОДСЧТ[xx]=SubStr(КОДСЧТ,  8, 6);
	 --|  Match(КОДСЧТ, "???.??.??.??.??.??.????.?.101.08.???"): тКОДИСТ[xx]=SubStr(КОДСЧТ, 25, 1); тКОДКБК[xx]="Драгоценности";	   тКОДСЧТ[xx]=SubStr(КОДСЧТ, 27, 6);
	 fi;
	 тКОДИСТ[xx]=ВзятьИсточникСредств(тКОДИСТ[xx]);
	 тДАТЭКС[xx]=1.1.100;
	 if КОДУЧН<>"":
	   aDate=1.1.100+Int(Saldo("ЗАБ.НФА.ДЭКСПЛ{"+КОДНФА+"&"+КОДУЧН+"}", ДатОтч));
	   if aDate>1.1.1800: тДАТЭКС[xx]=aDate; fi;
	 fi;
       fi;
     od;
   else
     Message("По заданнам условиям отбора^Mданных для отбора не обнаружено!", mtInformation);
     ^False;
   fi;
   len=LengthOfArray(тКОДНФА);
   if len>0:
     okData=True;
   else
     Message("По заданнам условиям отбора^Mненулевых остатков не обнаружено!", mtInformation);
     okData=False;
   fi;
 Finally
   ToggleAutoRefresh(Режим);
   CloseProgress;
 end;
 ^okData;
end;

Proc ПостроениеОтчета;
var len :Integer;
 len=LengthOfArray(тКОДНФА);
 if len>0:
   Позиции=len;
   ПересортировкаВедомости(len, UserSortField);
   всегоСУМОСТ=SumOfArray(тСУМОСТ, Позиции);
 fi;
end;

Proc ПоискНаименованияНФА;
var BindANA, MaskAcc, vS1, vS2, vS3, l1l2, l2l3 :String;
var начало :Integer;
var OK :Logical;
 начало=Time;
 -- Проверка заполнения
 if not ДАТОПЕР>1.1.2000:
    Message("Не задана корректная дата!", mtWarning);
    Template.Field="ДАТОПЕР";
    Exit;
 fi;
 --
 if not КорректныеУсловияПоиска: Exit; fi;
 --
 MaskAcc="((*.101.*|*.102.*|*.105.*)&(???.????.???????.???.?.???.??.???"+if(flgЗабаланс, "|ЗАБ.??.???.??", "")+"))";
 BindANA=СправочникиСтруктурыПоМаскеСчетовПрогресс(MaskAcc, 1.1.100, ДАТОПЕР+1, True, True);
 if BindANA=" ": Exit; fi; -- если был Except
 if SearchInArray(bindVOC,     "НФА.*", True, 1)<1: Message("Справочник 'НФА' не привязан к счетам учета НФА!",        mtError); Exit; fi;
 if SearchInArray(bindVOC,     "МОЛ.*", True, 1)<1: Message("Справочник 'МОЛ' не привязан к счетам учета НФА!",        mtError); Exit; fi;
 if SearchInArray(bindVOC,	 "М.*", True, 1)<1: Message("Справочник 'М' не привязан к счетам учета НФА!",	       mtError); Exit; fi;
 --if SearchInArray(bindVOC, pfxУЧН+".*", True, 1)<1: Message("Справочник '"+pfxУЧН+"' не привязан к счетам учета НФА!", mtError); Exit; fi;
 --
 vS1=""; vS2=""; vS3=""; l1l2=""; l2l3="";
 if Образец1<>"" and ГдеИскать1>0: 
   if ГдеИскать1=1: vS1="*"+Образец1;
   |  ГдеИскать1=2: vS1="*"+Образец1+"*";
   |  ГдеИскать1=3: vS1=Образец1+"*";
   fi;
 fi;
 if Образец2<>"" and ГдеИскать2>0:
   if ГдеИскать2=1: vS2="*"+Образец2;
   |  ГдеИскать2=2: vS2="*"+Образец2+"*";
   |  ГдеИскать2=3: vS2=Образец2+"*";
   fi;
 fi;
 if Образец3<>"" and ГдеИскать3>0:
   if ГдеИскать3=1: vS3="*"+Образец3;
   |  ГдеИскать3=2: vS3="*"+Образец3+"*";
   |  ГдеИскать3=3: vS3=Образец3+"*";
   fi;
 fi;
 if Образец1<>"" and Образец2<>"" and КакСоед1>0: 
   if КакСоед1=1: l1l2="and";
   |  КакСоед1=2: l1l2="orr";
   |  КакСоед1=3: l1l2="not";
   fi;
 fi;
 if Образец2<>"" and Образец3<>"" and КакСоед2>0:
   if КакСоед2=1: l2l3="and";
   |  КакСоед2=2: l2l3="orr";
   |  КакСоед2=3: l2l3="not";
   fi;
 fi;
 --
 OK=ПоискДанных(MaskAcc, ДАТОПЕР+1, flgЗабаланс, vS1, vS2, vS3, l1l2, l2l3);
 -- Построение отчета
 if OK:
   ПостроениеОтчета;
   ValidateОтчетSection;
   if Позиции>0: Message("Расчет завершен!^MВремя работы - "+TimeToHMSstring(Time-начало), mtInformation); fi;
 fi;
end;

Proc ДетализацияПозиции(ДатОтч:Date; TabIter:Integer);
var ПутьVAR, ОтПУТЬ, ОтчИМЯ, MaskACC, MaskANA, VOC :String;
var num :Integer;
var Sum :Numeric;
 if ДатОтч>1.1.1900:
   ClearVariable(Buf);
   Buf[1]="Детализация по всей аналитике позиции (по проводкам)";
   Buf[2]="Детализация по аналитике НФА позиции  (по проводкам)";
   Buf[3]="Детализация по аналитике МОЛ позиции (по справочнику НФА)";
   Buf[4]="Детализация по аналитике М позиции (по справочнику НФА)";
   num=Alternate("Детализация...", Buf, -1, 1, 12);
   if num<1: Exit; fi;
   ПутьVAR=PlanVar("НФА")+"\ОТЧЕТЫ";
   VOC="";
   MaskACC="(*.101.*|*.102.*|*.105.*)&(???.????.???????.???.?.???.??.???"+if(flgЗабаланс, "|ЗАБ.??.???.??", "")+")";
   MaskANA="";
   if num=1:
     ОтПУТЬ=РАБ.БЮДЖЕТ2005.Контроль2Слэш(ПутьVAR+"\НФАОТЧ2007.lst");
     if not ExistFile(ОтПУТЬ): Message("Файл с отчетами отсутствует!", mtError); Exit; fi;
     ОтчИМЯ=РАБ.БЮДЖЕТ2005.Контроль2Слэш(ПутьVAR+"\НФАОТЧ2007.lst"+"|По_проводкам");
     if Trim(тКОДНФА[TabIter])<>"" and ValidSign(тКОДНФА[TabIter]): MaskANA=Объединить(MaskANA, "("+тКОДНФА[TabIter]+")", "&"); fi;
     if Trim(тНОМУЧН[TabIter])<>"" and ValidSign(тНОМУЧН[TabIter]): MaskANA=Объединить(MaskANA, "("+тНОМУЧН[TabIter]+")", "&"); fi;
     if Trim(тКОДМОЛ[TabIter])<>"" and ValidSign(тКОДМОЛ[TabIter]): MaskANA=Объединить(MaskANA, "("+тКОДМОЛ[TabIter]+")", "&"); fi;
     if Trim(тКОДМХЭ[TabIter])<>"" and ValidSign(тКОДМХЭ[TabIter]): MaskANA=Объединить(MaskANA, "("+тКОДМХЭ[TabIter]+")", "&"); fi;
   |  num=2:
     ОтПУТЬ=РАБ.БЮДЖЕТ2005.Контроль2Слэш(ПутьVAR+"\НФАОТЧ2007.lst");
     if not ExistFile(ОтПУТЬ): Message("Файл с отчетами отсутствует!", mtError); Exit; fi;
     ОтчИМЯ=РАБ.БЮДЖЕТ2005.Контроль2Слэш(ПутьVAR+"\НФАОТЧ2007.lst"+"|По_проводкам");
     if Trim(тКОДНФА[TabIter])<>"" and ValidSign(тКОДНФА[TabIter]): MaskANA=Объединить(MaskANA, "("+тКОДНФА[TabIter]+")", "&"); fi;
   |  num=3:
     ОтПУТЬ=РАБ.БЮДЖЕТ2005.Контроль2Слэш(ПутьVAR+"\Статья.lst");
     ОтчИМЯ=РАБ.БЮДЖЕТ2005.Контроль2Слэш(ПутьVAR+"\Статья.lst"+"|Отчет_по_аналитике");
     if Trim(тКОДМОЛ[TabIter])<>"" and ValidSign(тКОДМОЛ[TabIter]): MaskANA=Объединить(MaskANA, "("+тКОДМОЛ[TabIter]+")", "&"); fi;
     VOC="НФА";
     if ExistFile(ОтПУТЬ): DeleteFile(ОтПУТЬ); fi;
     if not РАБ.УПП.LIB.СоздатьФайлОтчетСтрокиПоПризнакам("Статья", ПутьVAR, "Отчет_по_аналитике", MaskACC, MaskANA, True, False, VOC):
       Message("Файл-отчет детализации отсутствует!", mtError);
       Exit;
     fi;
   |  num=4:
     ОтПУТЬ=РАБ.БЮДЖЕТ2005.Контроль2Слэш(ПутьVAR+"\Статья.lst");
     ОтчИМЯ=РАБ.БЮДЖЕТ2005.Контроль2Слэш(ПутьVAR+"\Статья.lst"+"|Отчет_по_аналитике");
     if Trim(тКОДМХЭ[TabIter])<>"" and ValidSign(тКОДМХЭ[TabIter]): MaskANA=Объединить(MaskANA, "("+тКОДМХЭ[TabIter]+")", "&"); fi;
     VOC="НФА";
     if ExistFile(ОтПУТЬ): DeleteFile(ОтПУТЬ); fi;
     if not РАБ.УПП.LIB.СоздатьФайлОтчетСтрокиПоПризнакам("Статья", ПутьVAR, "Отчет_по_аналитике", MaskACC, MaskANA, True, False, VOC):
       Message("Файл-отчет детализации отсутствует!", mtError);
       Exit;
     fi;
   else ОтчИМЯ="";
   fi;
   if ОтчИМЯ<>"":
     Try Sum=Saldo(MaskACC, 1.1.100); Except Message("Ошибка в условии отбора счетов!", mtError); Exit; end;
     Try Sum=Saldo("*{"+MaskANA+"}", 1.1.100); Except Message("Ошибка в условии отбора аналитики!^MВозможно слишком длинное выражение...", mtError); Exit; end;
     Report(ОтчИМЯ, 1.1.100, ДатОтч, MaskACC, MaskANA);
   else
     Message("Ошибка детализации!", mtError);
   fi;
 else
   Message("Ошибка отчета!", mtError);
 fi;
end;

2-- События клеток
Func Field_onEnter(Field:String; Iter:Integer): Logical; -- на входе в клетку
 Flag_onEnter=False;
 if Field="ДАТОПЕР"	   : oldDate=ДАТОПЕР;
 |  Field="ГдеИскать1_"    : ГдеИскать1=ВыбратьОператорУсловия(ГдеИскать1, False); ^False;
 |  Field="ГдеИскать2_"    : ГдеИскать2=ВыбратьОператорУсловия(ГдеИскать2, False); ^False;
 |  Field="ГдеИскать3_"    : ГдеИскать3=ВыбратьОператорУсловия(ГдеИскать3, False); ^False;
 |  Field="КакСоед1_"	   : КакСоед1=ВыбратьОператорСоединения(КакСоед1,  False); ^False;
 |  Field="КакСоед2_"	   : КакСоед2=ВыбратьОператорСоединения(КакСоед2,  False); ^False;
 |  Field="UserSortField_" : ВыбратьUserПолеСортировки; ^False;
 |  Field="Расшифр"	   : ДетализацияПозиции(ДАТОПЕР+1, Iter); ^False;
 fi;
 ^True;
end;

Proc Field_onExit(Field:String; Iter:Integer); -- на выходе из клетки
 if Field="ДАТОПЕР"	   : if ДАТОПЕР<>oldDate: if ОтменитьИзмененияУсловийОтчета: ДАТОПЕР=oldDate; fi; fi;
 |  Field="ГдеИскать1_"    : ГдеИскать1=ВыбратьОператорУсловия(ГдеИскать1, True);
 |  Field="ГдеИскать2_"    : ГдеИскать2=ВыбратьОператорУсловия(ГдеИскать2, True);
 |  Field="ГдеИскать3_"    : ГдеИскать3=ВыбратьОператорУсловия(ГдеИскать3, True);
 |  Field="КакСоед1_"	   : КакСоед1=ВыбратьОператорСоединения(КакСоед1,  True);
 |  Field="КакСоед2_"	   : КакСоед2=ВыбратьОператорСоединения(КакСоед2,  True);
 fi;
 ValidateОтчетSection;
 Flag_onEnter=False;
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;
   ValidateОтчетSection;
 fi;
 SetDate(dd);
 ^"";
end;

Func Field_OnValidateS(Field:String; Iter:Integer; Value:String) :Logical;
 if not КорректныеСимволыНаименования(Value): ^False; fi;
 ^True;
end;

Proc btnOnClick(Sender:String); -- объекты при нажатии
 if Sender="btnExit": Close;
 |  Sender="btnCalc": ПоискНаименованияНФА;
 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="flg"+SubStr(Sender, 4, Length(Sender)-3); -- вычисляем имя переменной - 3=cb_
   Flag=GetVariableL(nameVar); -- текущий статус;
   Old=not(Flag); -- предыдущий статус
   if ОтменитьИзмененияУсловийОтчета: Flag=Old; fi;
   PutVariableL(nameVar, Flag);
   ОбъектИмя.State=Flag;
   if Flag<>Old: 
     ValidateОтчетSection;
   fi;
 fi;
end;  

2-- События шаблона
Proc Template_OnOpen(Create:Logical); -- при открытии шаблона
 РАБ.НАСТР_ПЕЧАТЬ.Cfg(PlanVar("НФА")+"\Настройки\", "ТББ_STD_Album10_000.cfg"); -- стандартная настройка !(возможно надо будет заменить)
end;

Proc Template_AfterOpen(Create:Logical); -- после открытия шаблона
var num :Integer;
 Очистить;
 if Позиции>0:
   num=EnqOkCancel("Обнаружены данные предыдущего расчета!^MСформировать ведомость?", mtConfirmation);
   if num=cmOk:  ПостроениеОтчета; else ОчисткаОтчета; fi;
 else
   ОчисткаОтчета;
 fi;
 Инициализация;
 Template.Field="Фокус";
end;

Proc Template_OnClose(Destroy:Logical); -- при закрытии шаблона
var num :Integer;
 Очистить;
 if Позиции>0:
   num=Enquiry("Выберите действие...", "Очистить ведомость (быстрее будет открываться бланк)^Mили сохранить данные для дальнейшего просмотра?", "Очистить;Сохранить", mtConfirmation);
   if num=1: ОчисткаОтчета; fi;
 fi;
end;

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