--
--
--
БЛАНКСШАБЛОНОМ "Месячный отчет по амортизации";
-- Разработка бланка: ТБ.БЮДЖЕТ
-- Первый релиз: 01.10.2014
--
var btnName_menu :String='Месячный отчет по амортизации (инвентарный) версия ЛАЙТ';
var Sort_menu    :String='11';
-- КОНСТАНТЫ
var infoVersion  :String="Версия отчета: LITE.1.15.06.26 Бета";
var ValidDate    :Date=1.1.2000;
var Фокус        :String="";

-- ОБЪЕКТЫ
btnExit:Object;   btnCalc:Object;   btnWipe:Object;   lblVersion:Object;

cbx_OnlyTurnAmtExist:Object;

СекцWorkЗТ :Object;  -- Основная таблица (отчет) - строка заголовков
СекцWorkДТ :Object;  -- Основная таблица (отчет) - строки данных
СекцWorkИТ :Object;  -- Основная таблица (отчет) - строка итогов
var Позиции    :Integer; -- строки ведомости

-- ПЕРЕМЕННЫЕ

var Flag_onEnter :Logical;
TimeCreationRep  :String;

flg_OnlyTurnAmtExist :Logical=[True];

var ДатОпер        :Date;2 0    -- дата отчета
var ДатОпер_       :Date=ДатОпер;
УЧТГОД             :Integer;
var SAVГОД         :Integer;
УЧТМЕС             :Integer;
var МЕССТР         :String;
var МЕССТР_        :String=МЕССТР;
var ПериодОтчТекст :String;

УЧР_НАИМ         :String;
УЧР_ОКПО         :String;
УЧР_REC          :Record;
ПОД_ИМЯ          :String;
ПОД_КОД          :String;
ИспДол           :String;
ИспФИО           :String;
ИспREC           :Record;
ДатИсп           :Date;

var ВнВид_МОЛ    :Integer=[2];
var ВнВид_МХЭ    :Integer=[2];
var savModeSet   :String;

-- МАССИВЫ
var Buf[]         :String;
var BufTxt[]      :String;
var BufInt[]      :Integer;
var aAna[]        :String;

var repUNIQUE[]   :String;    -- инвентарные объекты (уникальные элементы)
var repСЧТАМТ[]   :String;    -- счет учета амортизации
var repКОДМХЭ[]   :String;    -- код местонахождения
var repБАЛСУМ[]   :Numeric;   -- балансовая сумма на отчетную дату
var repБАЛКОЛ[]   :Numeric;   -- количество на отчетную дату
var repАМТ_СУ[]   :Numeric;   -- амортизация снятая с учета
var repАМТ_НН[]   :Numeric;   -- амортизация начисленная по норме
var repАМТ_ВЭ[]   :Numeric;   -- амортизация начисленная при выдаче в эксплуатацию
var repАМТ_ПУ[]   :Numeric;   -- амортизация начисленная принятая к учету
var repАМТ_ПР[]   :Numeric;   -- амортизация начисленная прочее

var NN[]          :Numeric=$; -- номер по порядку
var тблКОДНФА[]   :String;    -- код НФА
var тблНМННФА[]   :String;    -- наименование НФА
var тблИНВНОМ[]   :String;    -- инвентарный номер
var тблУЧННОМ[]   :String;    -- учетный номер
var тблДАТУЧТ[]   :Date;      -- дата принятия к учету
var тблДАТЭКС[]   :Date;      -- дата ввода в эксплуатацию
var тблАМТ_СУ[]   :Numeric;   -- амортизация снятая с учета
var тблАМТ_НН[]   :Numeric;   -- амортизация начисленная - ежемесячно, по норме
var тблАМТ_НЭ[]   :Numeric;   -- амортизация начисленная - при выдаче в эксплуатацию
var тблАМТ_НУ[]   :Numeric;   -- амортизация начисленная - при принятии к учету
var тблАМТ_НП[]   :Numeric;   -- амортизация начисленная - прочее
var тблАМТ_НВ[]   :Numeric;   -- амортизация начисленная - всего
var тблНФА_БС[]   :Numeric;   -- НФА на конец периода - балансовая стоимость
var тблНФА_СА[]   :Numeric;   -- НФА на конец периода - амортизация
var тблНФА_ОС[]   :Numeric;   -- НФА на конец периода - остаточная стоимость
var тблНФА_БК[]   :Numeric;   -- НФА на конец периода - количество
var тблКОДМОЛ[]   :String;    -- МОЛ
var тблКОДМХЭ[]   :String;    -- Местонахождение
var тблНФАМОЛ[]   :String=РАБ.НФА.FUNC_LIB.FormatAna(тблКОДМОЛ[$], ВнВид_МОЛ, "наименования нет", "-"); -- МОЛ
var тблНФАМХЭ[]   :String=РАБ.НФА.FUNC_LIB.FormatAna(тблКОДМХЭ[$], ВнВид_МХЭ, "наименования нет", "-"); -- Местонахождение

var итгАМТ_СУ     :Numeric=SumOfArray(тблАМТ_СУ, Позиции); -- ИТОГО: амортизация снятая с учета
var итгАМТ_НН     :Numeric=SumOfArray(тблАМТ_НН, Позиции); -- ИТОГО: амортизация начисленная - ежемесячно, по норме
var итгАМТ_НЭ     :Numeric=SumOfArray(тблАМТ_НЭ, Позиции); -- ИТОГО: амортизация начисленная - при выдаче в эксплуатацию
var итгАМТ_НУ     :Numeric=SumOfArray(тблАМТ_НУ, Позиции); -- ИТОГО: амортизация начисленная - при принятии к учету
var итгАМТ_НП     :Numeric=SumOfArray(тблАМТ_НП, Позиции); -- ИТОГО: амортизация начисленная - прочее
var итгАМТ_НВ     :Numeric=SumOfArray(тблАМТ_НВ, Позиции); -- ИТОГО: амортизация начисленная - всего
var итгНФА_БС     :Numeric=SumOfArray(тблНФА_БС, Позиции); -- ИТОГО: НФА на конец периода - балансовая стоимость
var итгНФА_СА     :Numeric=SumOfArray(тблНФА_СА, Позиции); -- ИТОГО: НФА на конец периода - амортизация
var итгНФА_ОС     :Numeric=SumOfArray(тблНФА_ОС, Позиции); -- ИТОГО: НФА на конец периода - остаточная стоимость
var итгНФА_БК     :Numeric=SumOfArray(тблНФА_БК, Позиции); -- ИТОГО: НФА на конец периода - количество

2-- Общие процедуры и функции

Proc ОчисткаArr;
 ClearVariable(Buf);
 ClearVariable(aAna);
 ClearVariable(BufTxt);
 ClearVariable(BufInt);
end;

Proc ОчисткаRep;
 ClearVariable(repUNIQUE);
 ClearVariable(repСЧТАМТ);
 ClearVariable(repКОДМХЭ);
 ClearVariable(repБАЛСУМ);
 ClearVariable(repБАЛКОЛ);
 ClearVariable(repАМТ_СУ);
 ClearVariable(repАМТ_НН);
 ClearVariable(repАМТ_ВЭ);
 ClearVariable(repАМТ_ПУ);
 ClearVariable(repАМТ_ПР);
end;

Proc ОчисткаТаблицы;
 ClearTrace(True);
 TimeCreationRep="";
 ClearVariable(Позиции);
 ClearVariable(NN);
 ClearVariable(тблКОДНФА);
 ClearVariable(тблНМННФА);
 ClearVariable(тблИНВНОМ);
 ClearVariable(тблУЧННОМ);
 ClearVariable(тблДАТУЧТ);
 ClearVariable(тблДАТЭКС);
 ClearVariable(тблАМТ_СУ);
 ClearVariable(тблАМТ_НН);
 ClearVariable(тблАМТ_НЭ);
 ClearVariable(тблАМТ_НУ);
 ClearVariable(тблАМТ_НП);
 ClearVariable(тблАМТ_НВ);
 ClearVariable(тблНФА_БС);
 ClearVariable(тблНФА_СА);
 ClearVariable(тблНФА_ОС);
 ClearVariable(тблНФА_БК);
 ClearVariable(тблКОДМОЛ);
 ClearVariable(тблКОДМХЭ);
 ClearVariable(тблНФАМОЛ);
 ClearVariable(тблНФАМХЭ);
end;

Proc Очистить;
 ОчисткаArr;
 ОчисткаRep;
end;

Proc ВидимостьОтчетныхТаблиц_Validate(СкрытьТаблицу:Logical);
var FF :Logical;
 if Позиции>0 and not СкрытьТаблицу: FF=True; else FF=False; fi;
 СекцWorkЗТ.Visible=FF;
 СекцWorkДТ.Visible=FF;
 СекцWorkИТ.Visible=FF;
end;

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

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

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

Proc ReDrawДаты;
 if УЧТМЕС>0 and УЧТМЕС<13 and УЧТГОД>Year(ValidDate): 
   ДАТОПЕР = AddMon(Dat(1, УЧТМЕС, УЧТГОД), 1);
   МЕССТР  = Месяц(УЧТМЕС);
 else
   ДАТОПЕР=1.1.100;
   МЕССТР="";
 fi;
 ПериодОтчТекст = "СУММА АМОРТИЗАЦИИ ЗА "+if(МЕССТР<>"", Up(МЕССТР), "ПЕРИОД");
end;

Proc ValidateSectionAll;
 ReDrawДаты;
 ВидимостьОтчетныхТаблиц_Validate(False);
end;

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

Func ВыборОтчетногоПериода(номерПериода:Integer) :Integer;
var ii, newПериод :Integer;
 ClearVariable(Buf);
 for ii=1 to 12 do Buf[ii]=Месяц(ii); od;
 newПериод=Alternate('Период отчета...', Buf, 20, номерПериода, 12);
 if newПериод=0: ^номерПериода; fi;
 if newПериод<>номерПериода: if ОтменитьИзмененияУсловийОтчета: newПериод=номерПериода; fi; fi;
 ^newПериод;
end;

Proc ОтчетныйПериод_Get;
 УЧТМЕС = ВыборОтчетногоПериода(УЧТМЕС);
end;

Proc Инициализация;
 lblVersion.Caption=infoVersion;
 if УЧТГОД=0: 
   УЧТГОД=Year(ToDay);
   flg_OnlyTurnAmtExist=True;
   ВнВид_МОЛ=2;
   ВнВид_МХЭ=2;
 fi;
 SAVГОД=УЧТГОД;
 ValidateSectionAll;
end;

Proc ВзятьРеквизиты(saveREC:Record; Auto:Logical);
var RO, num :Integer;
var REC :Record;
 if Auto:
   if Trim(УЧР_НАИМ)="":
     RO=OpenWorkArea("КОНТРАГЕНТ", "", "НАШЕ");
     Try
       num=Records(RO);
       if num<1: REC=NIL;
       |  num=1: REC=GetRecordKey(RO, 1);
       |  num>1: REC=GetRecordKey(RO, 1);
                 SetFilter(RO, "НАШЕ and РПО_УМОЛЧАНИЕ");
                 if Records(RO)>0: REC=GetRecordKey(RO, 1); fi;
       fi;
       if REC=NIL and saveREC<>NIL: REC=saveREC; fi;
       if REC<>NIL:
         SetFilter(RO, "UKey="+RecordToString(REC));
         if Records(RO)=1:
           УЧР_НАИМ = GetFieldS(RO, 1, "КОРИМЯ");
           УЧР_ОКПО = GetFieldS(RO, 1, "ОКПО");
            УЧР_REC = REC;
         fi;
       fi;
     Finally
       CloseWorkArea(RO);
     end;
   fi;
 else
   REC=OpenCardFile("КОНТРАГЕНТ", "НАШЕ", saveREC, crdRecordOnly);
   if REC=NIL: Exit; fi;
   RO=OpenWorkArea("КОНТРАГЕНТ", "", "UKey="+RecordToString(REC));
   Try
     if Records(RO)=1:
       УЧР_НАИМ = GetFieldS(RO, 1, "КОРИМЯ");
       УЧР_ОКПО = GetFieldS(RO, 1, "ОКПО");
        УЧР_REC = REC;
     fi;
   Finally
     CloseWorkArea(RO);
   end;
 fi;
end;

Proc ПО_Выбор(prevVal:String);
var КОД, ИМЯ, Value :String;
 Value=AnaElection("П.*", False, False, prevVal);
 if Value="": Exit; fi;
 КОД=Value;
 Value=Name_A(КОД);
 ИМЯ=if(Value<>"" and Value<>" ", Value, КОД);
 ПОД_ИМЯ=ИМЯ;
 ПОД_КОД=КОД;
end;

Proc АМТ_МЕС_Отчет_ОчисткаПолей;
var Work :Logical;
 Work=False;
 if Позиции>0: if EnqOkCancel("Таблица отчета по амортизации будет очищена.^MПродолжить?", mtWarning)=cmOk: Work=True; fi; else Work=True; fi;
 if Work:
   ОчисткаТаблицы;
   ValidateSectionAll;
 fi;
end;

Func ВзятьДЭКСПЛ_КМНТ(КМНТ:String) :Date;
var ДЭКСПЛ :Date;
var pp :Integer;
 КМНТ=' '+КМНТ;
 pp=Pos(' ДЭКСПЛ=', КМНТ);
 if pp>0:
   КМНТ=Trim(SubStr(КМНТ, pp+8, 10));
   Try ДЭКСПЛ=StringToDate(КМНТ); Except ДЭКСПЛ=1.1.100; end;
 fi;
 ^ДЭКСПЛ;
end;

Func ВзятьДУЧЕТ_КМНТ(КМНТ:String):Date;
var ДУЧЕТ :Date;
var pp :Integer;
 КМНТ=' '+КМНТ;
 pp=Pos(' ДУЧЕТ=',  КМНТ);
 if pp>0:
   КМНТ=Trim(SubStr(КМНТ, pp+8, 10));
   if Match(КМНТ, '?.??.????'): КМНТ='1'+КМНТ; fi;
   Try ДУЧЕТ=StringToDate(КМНТ); Except ДУЧЕТ=1.1.100; end;
 fi;
 ^ДУЧЕТ;
end;

Func ВзятьДатуВводаЭксплуат_Сложный(Fnc_Date:Date; Crd_Date:Date; vКОДНФА:String; vКОДУЧН:String; vКОДСЧТ:String; vКОДМХЭ:String; ddEND:Date; vXconstНФА100П:Numeric) :Date;
var MskAna, СЧТКОД :String;
var dd_Null, Rep_Date :Date;
var Цена :Numeric;
var pp :Integer;
 dd_Null=1.1.1800;
 if Crd_Date > dd_Null and Fnc_Date > dd_Null : if Crd_Date<Fnc_Date: Rep_Date=Crd_Date; else Rep_Date=Fnc_Date; fi;
 |  Crd_Date > dd_Null and Fnc_Date = 1.1.100 : Rep_Date=Crd_Date;
 |  Crd_Date = 1.1.100 and Fnc_Date > dd_Null : Rep_Date=Fnc_Date;
 else Rep_Date=1.1.100;
 fi;
 if Rep_Date>dd_Null: ^Rep_Date; fi;
 --
 Rep_Date=1.1.100;
 MskAna=vКОДСЧТ+"/(*.?.???.??.???|00){"+vКОДНФА+"&"+vКОДУЧН+"}";
 for Transaction pp=MskAna, 1.1.100, ddEnd  do
   Rep_Date=ВзятьДЭКСПЛ_КМНТ(TransComment(pp));
   if Rep_Date>dd_Null: ^Rep_Date; fi;
   Try Цена=Abs(TransSum(pp, "РУБ"))/Abs(TransSum(pp, "КОЛ")); Except Цена=0.00; end;
   СЧТКОД=TransCre(pp);
   if Match(vКОДМХЭ, "М.Э.*") or (СЧТКОД="00" and TransCardFile(pp)="РПО_ОСТ_НФА"): Rep_Date=TransDate(pp); fi;
   if Rep_Date>dd_Null: ^Rep_Date; fi;
   if Rep_Date=1.1.100:
     if Match(СЧТКОД, "*.?.101.??.3?0") or -- внутренние перемещения
        Match(СЧТКОД, "*.?.106.??.3?0") or -- принятие к учету
        Match(СЧТКОД, "*.?.304.04.3?0") or -- централизованное снабжение
        Match(СЧТКОД, "*.?.401.10.14?") or
        Match(СЧТКОД, "*.?.401.10.15?") or
        Match(СЧТКОД, "*.?.401.10.180") or
        ((Match(СЧТКОД, "*.?.401.20.271") or Match(СЧТКОД, "*.?.109.??.271")) and Цена<=vXconstНФА100П):
          Rep_Date=TransDate(pp);
          if Rep_Date>dd_Null: ^Rep_Date; fi;
     fi;
   fi;
 end;
 ^Rep_Date;
end;

Func ВзятьДатуВводаЭксплуат_Сложный2(Fnc_Date:Date; Crd_Date:Date; vКОДНФА:String; vКОДУЧН:String; vКОДСЧТ:String; vКОДМХЭ:String; ddEND:Date) :Date;
var MskAna :String;
var dd_Null, Rep_Date :Date;
var pp :Integer;
 dd_Null=1.1.1800;
 if Crd_Date > dd_Null and Fnc_Date > dd_Null : if Crd_Date<Fnc_Date: Rep_Date=Crd_Date; else Rep_Date=Fnc_Date; fi;
 |  Crd_Date > dd_Null and Fnc_Date = 1.1.100 : Rep_Date=Crd_Date;
 |  Crd_Date = 1.1.100 and Fnc_Date > dd_Null : Rep_Date=Fnc_Date;
 else Rep_Date=1.1.100;
 fi;
 if Rep_Date>dd_Null: ^Rep_Date; fi;
 --
 Rep_Date=1.1.100;
 MskAna=vКОДСЧТ+"/(*.?.???.??.???|00){"+vКОДНФА+"&"+vКОДУЧН+"}";
 for Transaction pp=MskAna, 1.1.100, ddEnd  do
   Rep_Date=ВзятьДЭКСПЛ_КМНТ(TransComment(pp));
   if Rep_Date>dd_Null: ^Rep_Date; fi;
   if Match(vКОДМХЭ, "М.Э.*"): Rep_Date=TransDate(pp); fi;
   if Rep_Date>dd_Null: ^Rep_Date; fi;
 end;
 ^Rep_Date;
end;

Func ВзятьДатуПринятияУчету_Сложный(Fnc_Date:Date; Crd_Date:Date; vКОДНФА:String; vКОДУЧН:String; vКОДСЧТ:String; ddEND:Date) :Date;
var dd_Null, Rep_Date :Date;
var MskAna :String;
var pp :Integer;
 dd_Null=1.1.1800;
 if Crd_Date > dd_Null and Fnc_Date > dd_Null : if Crd_Date<Fnc_Date: Rep_Date=Crd_Date; else Rep_Date=Fnc_Date; fi;
 |  Crd_Date > dd_Null and Fnc_Date = 1.1.100 : Rep_Date=Crd_Date;
 |  Crd_Date = 1.1.100 and Fnc_Date > dd_Null : Rep_Date=Fnc_Date;
 else Rep_Date=1.1.100;
 fi;
 if Rep_Date>dd_Null: ^Rep_Date; fi;
 --
 Rep_Date=1.1.100;
 MskAna=vКОДСЧТ+"/(*.106.??.3?0|*.304.04.3?0|*.401.10.14?|*.401.10.15?|*.401.10.172|*.401.10.180|00)"+"{"+vКОДНФА+"&"+vКОДУЧН+"}";
 for Transaction pp=MskAna, 1.1.100, ddEnd  do
   Rep_Date=ВзятьДУЧЕТ_КМНТ(TransComment(pp));
   if Rep_Date>dd_Null: ^Rep_Date; fi;
   Rep_Date=TransDate(pp);
   if Rep_Date>dd_Null: ^Rep_Date; fi;
 end;
 ^Rep_Date;
end;

Func ВзятьДатуВводаЭксплуат_П_модиф(vR1:Integer; vIter:Integer; Сложный:Logical; rvКОДНФА:String; rvКОДУЧН:String; rvКОДСЧТ:String; rvКОДМХЭ:String; RddEND:Date; rXconstНФА100П:Numeric) :Date;
var dd_Null, Rep_Date, clcFnc_Date, clcCrd_Date :Date;
 dd_Null  = 1.1.1800;
 Rep_Date = 1.1.100;
 if Name_A(rvКОДНФА)=" " or Name_A(rvКОДУЧН)=" ": ^Rep_Date; fi;
 clcFnc_Date = 1.1.100+Int(Saldo("ЗАБ.НФА.ДЭКСПЛ{"+rvКОДНФА+"&"+rvКОДУЧН+"}", RddEND));
 if clcFnc_Date>dd_Null and Year(clcFnc_Date)<2100: ^clcFnc_Date; fi;
 if Сложный:
   clcCrd_Date = 1.1.100;
   if vIter>0 and Up(WorkAreaCardFile(vR1))="РПО_ИНВКАРТ_ОС": clcCrd_Date = GetFieldD(vR1, vIter, "ДАТ_ВЭКСП"); fi;
   --Rep_Date=ВзятьДатуВводаЭксплуат_Сложный(clcFnc_Date, clcCrd_Date, rvКОДНФА, rvКОДУЧН, rvКОДСЧТ, rvКОДМХЭ, RddEND, rXconstНФА100П);
   Rep_Date=ВзятьДатуВводаЭксплуат_Сложный2(clcFnc_Date, clcCrd_Date, rvКОДНФА, rvКОДУЧН, rvКОДСЧТ, rvКОДМХЭ, RddEND);
 else
   if clcFnc_Date>dd_Null and Year(clcFnc_Date)<2100: Rep_Date=clcFnc_Date; fi;
 fi;
 ^Rep_Date;
end;

Func ВзятьДатуПринятияУчету_П_модиф(vR1:Integer; vIter:Integer; Сложный:Logical; rvКОДНФА:String; rvКОДУЧН:String; rvКОДСЧТ:String; RddEND:Date) :Date;
var dd_Null, Rep_Date, clcFnc_Date, clcCrd_Date :Date;
 dd_Null=1.1.1800;
 Rep_Date=1.1.100;
 if Name_A(rvКОДНФА)=" " or Name_A(rvКОДУЧН)=" ": ^Rep_Date; fi;
 clcFnc_Date = 1.1.100+Int(Saldo("ЗАБ.НФА.ДУЧЕТ{"+rvКОДНФА+"&"+rvКОДУЧН+"}", RddEND));
 if clcFnc_Date>dd_Null and Year(clcFnc_Date)<2100: ^clcFnc_Date; fi;
 if Сложный:
   clcCrd_Date = 1.1.100;
   if vIter>0 and Up(WorkAreaCardFile(vR1))="РПО_ИНВКАРТ_ОС": clcCrd_Date = GetFieldD(vR1, vIter, "ОПРИХ_ДАТА"); fi;
   Rep_Date=ВзятьДатуПринятияУчету_Сложный(clcFnc_Date, clcCrd_Date, rvКОДНФА, rvКОДУЧН, rvКОДСЧТ, RddEND);
 else
   if clcFnc_Date>dd_Null and Year(clcFnc_Date)<2100: Rep_Date=clcFnc_Date; fi;
 fi;
 ^Rep_Date;
end;

Func ВыборВидаТаблицы(State:Integer) :Integer;
var nn :Integer;
 ClearVariable(Buf);
 Buf[1]="код + наименование";
 Buf[2]="только код";
 Buf[3]="только наименование";
 Buf[4]="наименование + код";
 nn=Alternate("Выберите способ отображения аналитики", Buf, -1, State+1, 12);
 if nn=0: ^State; fi;
 ^(nn-1);
end;

Func ПроверкаЗаполнения :Logical;
 if ДатОпер<ValidDate:
   Message('Не задана или некорректная дата периода для отчета.', mtWarning);
   Template.Field="МЕССТР_";
   ^False;
 fi;
 ^True;
end;

Proc Создать_СписокИнвентарныхОбъектов(aRepDat:Date);
var ВременныйФайл, СЧТБАЛ, СЧТАМТ, КОДНФА, КОДУЧН, КОДМХЭ, svrANA, svrSGN, aVal1, aVal2, aDeb, aCre, aComment :String;
var xx, len, ii, jj, pp :Integer;
var aSum1, aSum2, SUM, KOL, QUA :Numeric;
var СЧДЕБ :Logical;
var aDate :Date;

 ClearVariable(aAna);
 ОчисткаRep;
 ВременныйФайл=PlanVar('CACHE')+"\"+GetGUID;
 xx=TujRepNoNullBal+TujRepCombinedAna+TujRepBalAccount;
 len=TujReport(ВременныйФайл, 1.1.100, aRepDat, "(*.101.*|*.102.*)&???.????.???????.???.?.???.??.???", "НФА.*&УЧН.*", "ДНФА", "", "", xx, False);
 if len>0:
   ShowProgress(len, "Выборка инвентарных объектов учета на "+DateToString(aRepDat)+".");
   OpenTextJur(ВременныйФайл);
   Try
     ii=1;
     while not GetTransFromTextJur(aDate, aSum1, aVal1, aSum2, aVal2, aDeb, aCre, aAna, aComment) do
       ProgressPos(ii);
       ii=ii+1;
       СЧТБАЛ=""; СЧТАМТ=""; КОДНФА=""; КОДУЧН=""; КОДМХЭ=""; svrANA=""; svrSGN="";
       SUM=0.00; KOL=0.00; QUA=0.00;
       if aDeb="00": СЧТБАЛ=aCre; СЧДЕБ=False; fi;
       if aCre="00": СЧТБАЛ=aDeb; СЧДЕБ=True;  fi;
       if Match(СЧТБАЛ, "???.????.???????.???.?.10?.??.???"): СЧТБАЛ=SubStr(СЧТБАЛ, 1, 30)+"???"; 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;
         xx=LengthOfArray(aAna);
         if xx>0:
           for jj=1 to xx do
             pp=Pos(":", aAna[jj]);
             if pp>0:
               QUA=StringToNumeric(SubStr(aAna[jj], pp+1, Length(aAna[jj])-pp));
               svrANA=SubStr(aAna[jj], 1, pp-1);
             else
               svrANA=aAna[jj];
             fi;
             svrSGN=SubStr(svrANA, 1, 1);
             if svrSGN="+" or svrSGN="-": svrANA=SubStr(svrANA, 2, 255); fi;
             if Match(svrANA, "НФА.*"): КОДНФА=svrANA; KOL=if(СЧДЕБ, QUA, -QUA);
             |  Match(svrANA, "УЧН.*"): КОДУЧН=svrANA;
             |  Match(svrANA, "М.*"  ): КОДМХЭ=svrANA;
             fi;
           od; -- цикл по аналитике
         fi; --xx>0
         if СЧТБАЛ<>"" and КОДНФА<>"" and КОДУЧН<>"":
           svrANA=СЧТБАЛ+"#"+КОДНФА+"#"+КОДУЧН;
           xx=SearchInArray(repUNIQUE, svrANA, True, 1);
           if not xx>0:
             СЧТАМТ=РАБ.НФА.LIBREP.СчетАмортизацииПоСчетуНФА(СЧТБАЛ);
             if СЧТАМТ="": СЧТАМТ="АМТ.$$$"; fi;
             pp=InsertInArraySort(repUNIQUE, svrANA);
             InsertInArray(repСЧТАМТ, pp, СЧТАМТ);
             InsertInArray(repКОДМХЭ, pp, КОДМХЭ);
             InsertInArray(repБАЛСУМ, pp, SUM);
             InsertInArray(repБАЛКОЛ, pp, KOL);
             InsertInArray(repАМТ_СУ, pp, 0.00);
             InsertInArray(repАМТ_НН, pp, 0.00);
             InsertInArray(repАМТ_ВЭ, pp, 0.00);
             InsertInArray(repАМТ_ПУ, pp, 0.00);
             InsertInArray(repАМТ_ПР, pp, 0.00);
           else
             repБАЛСУМ[xx]=repБАЛСУМ[xx]+SUM;
             repБАЛКОЛ[xx]=repБАЛКОЛ[xx]+KOL;
             -- МХЭ нам нужно только для установления факта выдачи в эксплуатацию
             -- соотвественно сохраняется первое найденное значение и меняется только в случае когда оно из М.Х.* становится М.Э.*
             if КОДМХЭ<>"":
               if repКОДМХЭ[xx]<>"":
                 if not Match(repКОДМХЭ[xx], "М.Э.*"): repКОДМХЭ[xx]=КОДМХЭ; fi;
               else
                 repКОДМХЭ[xx]=КОДМХЭ;
               fi;
             fi;
           fi; -- объект найден
         fi; --if КОДНФА<>"" and КОДУЧН<>"" and КОДАМТ<>""
       fi; --if КОДСЧТ<>""
     end; -- while
   Finally
     CloseTextJur;
     CloseProgress;
   end; -- Try
   Try DeleteFile(ВременныйФайл); Except end;
 fi; -- len>0 (TujReport)
end;

Proc РаспределитьСуммыАмортизации(аНоваяСумма:Logical;
                                        aIter:Integer;
                                      аАмтДеб:Logical;
                                      аСчтДеб:String;
                                      аАмтКре:Logical;
                                      аСчтКре:String;
                                      aAmtJur:String;
                                      aOprNam:String;
                                      aSumAmt:Numeric);
var флг_АмортизацияНачисляется, флг_А_НН, флг_А_ВЭ, флг_А_ПУ, флг_А_ПР :Logical;
--АМТ_СУ   104 - 304 101
--АМТ_НН   401 106 109                  - 104
--АМТ_ВЭ   401 106 109                  - 104
--АМТ_ПУ   304.04 401.10.150 401.10.180 - 104
--АМТ_ПР                                - 104
 флг_АмортизацияНачисляется=if(аАмтКре and (Match(аСчтДеб, "*.?.401.20.271") or Match(аСчтДеб, "*.?.109.??.271") or Match(аСчтДеб, "*.?.106.??.???")), True, False);
 флг_А_НН=if(флг_АмортизацияНачисляется and aAmtJur="РПО_НАЧ_АМОРТ_TR", True, False);
 флг_А_ВЭ=if(флг_АмортизацияНачисляется and aAmtJur="РПО_ОПЕРАЦИИДНФА" and (Match(aOprNam, "ДНФА.ВНПР.ХЭ*") or aOprNam="ДНФА.ПРИХ.НИ_106_У_НФА"), True, False);
 флг_А_ПУ=if(аАмтКре and (Match(аСчтДеб, "*.?.304.04.3??") or Match(аСчтДеб, "*.?.401.10.15?") or Match(аСчтДеб, "*.?.401.10.180") or Match(аСчтДеб, "*.?.210.06.???")), True, False);
 флг_А_ПР=if(аАмтКре and not флг_А_НН and not флг_А_ВЭ and not флг_А_ПУ, True, False);
 if аНоваяСумма:
   InsertInArray(repАМТ_СУ, aIter, if(аАмтДеб , aSumAmt, 0.00));
   InsertInArray(repАМТ_НН, aIter, if(флг_А_НН, aSumAmt, 0.00));
   InsertInArray(repАМТ_ВЭ, aIter, if(флг_А_ВЭ, aSumAmt, 0.00));
   InsertInArray(repАМТ_ПУ, aIter, if(флг_А_ПУ, aSumAmt, 0.00));
   InsertInArray(repАМТ_ПР, aIter, if(флг_А_ПР, aSumAmt, 0.00));
 else
   if аАмтДеб  : repАМТ_СУ[aIter]=repАМТ_СУ[aIter]+aSumAmt; fi;
   if флг_А_НН : repАМТ_НН[aIter]=repАМТ_НН[aIter]+aSumAmt; fi;
   if флг_А_ВЭ : repАМТ_ВЭ[aIter]=repАМТ_ВЭ[aIter]+aSumAmt; fi;
   if флг_А_ПУ : repАМТ_ПУ[aIter]=repАМТ_ПУ[aIter]+aSumAmt; fi;
   if флг_А_ПР : repАМТ_ПР[aIter]=repАМТ_ПР[aIter]+aSumAmt; fi;
 fi;
end;

Proc Создать_СальдоАмортизации(aEndRep:Date);
var CRDwrk, svrANA, СЧТБАЛ, СЧТАМТ, СЧТДЕБ, СЧТКРЕ, КОДНФА, КОДУЧН, КОДДВЖ :String;
var Iter, len, ii, xx, pp:Integer;
var aBegRep :Date;
var SUM :Numeric;
var амтДЕБ, амтКРЕ :Logical;

 aBegRep=AddMon(aEndRep, -1);
 for Transaction Iter="???.????.???????.???.?.104.??.??? {НФА.*}", aBegRep, aEndRep do len=len+1; end;
 ii=0;
 ShowProgress(len, "Поиск сумм начислений и выбытия амортизации...");
 Try
   for Transaction Iter="???.????.???????.???.?.104.??.??? {НФА.*}", aBegRep, aEndRep do
     КОДНФА=""; КОДУЧН=""; КОДДВЖ="";
     ii=ii+1;
     ProgressPos(ii);
     СЧТДЕБ=TransDeb(Iter);
     СЧТКРЕ=TransCre(Iter);
        SUM=TransSum(Iter);
     амтДЕБ=Match(СЧТДЕБ, "*.?.104.??.???");
     амтКРЕ=Match(СЧТКРЕ, "*.?.104.??.???");
     CRDwrk=Up(TransCardFile(Iter));
     if     амтДЕБ and not амтКРЕ: СЧТБАЛ=РАБ.НФА.LIBREP.СчетНФАпоСчетуАмортизации(СЧТДЕБ); СЧТАМТ=СЧТДЕБ;
     |  not амтДЕБ and     амтКРЕ: СЧТБАЛ=РАБ.НФА.LIBREP.СчетНФАпоСчетуАмортизации(СЧТКРЕ); СЧТАМТ=СЧТКРЕ;
     |      амтДЕБ and     амтКРЕ: СЧТБАЛ=РАБ.НФА.LIBREP.СчетНФАпоСчетуАмортизации(СЧТДЕБ); СЧТАМТ=СЧТДЕБ;
     else СЧТБАЛ=""; СЧТАМТ="";
     fi;
     if КОДНФА="": КОДНФА=РАБ.НФА.FUNC_LIB.ПризнакИзСтрокиАналитикиПроводки(Iter, "НФА", True);  fi;
     if КОДНФА="": КОДНФА=РАБ.НФА.FUNC_LIB.ПризнакИзСтрокиАналитикиПроводки(Iter, "НФА", False); fi;
     if КОДУЧН="": КОДУЧН=РАБ.НФА.FUNC_LIB.ПризнакИзСтрокиАналитикиПроводки(Iter, "УЧН", True);  fi;
     if КОДУЧН="": КОДУЧН=РАБ.НФА.FUNC_LIB.ПризнакИзСтрокиАналитикиПроводки(Iter, "УЧН", False); fi;
     if КОДДВЖ="": КОДДВЖ=Up(РАБ.НФА.FUNC_LIB.ПризнакИзСтрокиАналитикиПроводки(Iter, "ДНФА", False)); fi;
     if КОДДВЖ="": КОДДВЖ=Up(РАБ.НФА.FUNC_LIB.ПризнакИзСтрокиАналитикиПроводки(Iter, "ДНФА", True));  fi;
     if СЧТБАЛ="": СЧТБАЛ="БАЛ.$$$"; fi;
     if КОДНФА="": КОДНФА="НФА.$$$"; fi;
     if КОДУЧН="": КОДУЧН="УЧН.$$$"; fi;
     if СЧТБАЛ<>"" and КОДНФА<>"" and КОДУЧН<>"":
       svrANA=СЧТБАЛ+"#"+КОДНФА+"#"+КОДУЧН;
       xx=SearchInArray(repUNIQUE, svrANA, True, 1);
       if not xx>0:
         pp=InsertInArraySort(repUNIQUE, svrANA);
         InsertInArray(repСЧТАМТ, pp, СЧТАМТ);
         InsertInArray(repКОДМХЭ, pp, "");
         InsertInArray(repБАЛСУМ, pp, 0.00);
         InsertInArray(repБАЛКОЛ, pp, 0.00);
         РаспределитьСуммыАмортизации(True , pp, амтДЕБ, СЧТДЕБ, амтКРЕ, СЧТКРЕ, CRDwrk, КОДДВЖ, SUM);
       else
         РаспределитьСуммыАмортизации(False, xx, амтДЕБ, СЧТДЕБ, амтКРЕ, СЧТКРЕ, CRDwrk, КОДДВЖ, SUM);
         if repСЧТАМТ[xx]="АМТ.$$$": repСЧТАМТ[xx]=СЧТАМТ; fi;
       fi; -- объект найден
     fi; --if КОДНФА<>"" and КОДУЧН<>"" and КОДАМТ<>""
   end; -- Transaction
 Finally
   CloseProgress;
 end;

end;

Func ПроходимОтбор(флгТолькоОборотыАмт:Logical; аБАЛСУМ:Numeric; аБАЛКОЛ:Numeric; аАМТ_СУ:Numeric; аАМТ_НН:Numeric; аАМТ_ВЭ:Numeric; аАМТ_ПУ:Numeric; аАМТ_ПР:Numeric) :Logical;
var SUM :Numeric;
 if флгТолькоОборотыАмт:
   SUM=Round(Abs(аАМТ_СУ)+Abs(аАМТ_НН)+Abs(аАМТ_ВЭ)+Abs(аАМТ_ПУ)+Abs(аАМТ_ПР), 2);
   ^if(SUM>0.00, True, False);
 else
   SUM=Round(Abs(аАМТ_СУ)+Abs(аАМТ_НН)+Abs(аАМТ_ВЭ)+Abs(аАМТ_ПУ)+Abs(аАМТ_ПР), 2);
   ^if(аБАЛСУМ<>0.00 or аБАЛКОЛ<>0.00 or SUM>0.00, True, False);
 fi;
 ^False;
end;

Proc АМТ_МЕС_Отчет_РасчетВыполнить;
var Mask101, Mask104, АМТСЧТ, БАЛСЧТ, КОДНФА, КОДУЧН, КОДМХЭ, КОДМОЛ :String;
var начало, ROнфа, ROинв, ppНФА, ppИНВ, num, ii, xx :Integer;
var aWork, флг_НеНачислятьАмортизацию, флг_БылЭксплуатации :Logical;
var SUMAMT, ConstНФА100П :Numeric;
var ddpu, ddve :Date;
var REC :Record;

 начало=Time;
 if not 2ПроверкаЗаполнения0: Exit; fi;
 Refresh(False);
 ОчисткаRep;
 aWork=True;
 Mask101="*.?.101.??.???|*.?.102.??.???";
 Mask104="*.?.104.??.???";
 if aWork:
   if Abs(Turn("+("+Mask101+") {~НФА.*}", 1.1.100, ДатОпер))>0 or Abs(Turn("-("+Mask101+") {~НФА.*}", 1.1.100, ДатОпер))>0:
      num=Enquiry("Выберите действие...", "Обнаружены проводки^Mна ("+Mask101+") счетах^Mнепомеченные справочником НФА!", "Проводки в отчет;Отмена;Игнорировать", mtError);
      if num=1: aWork=False; Report(PlanVar("НФА")+"\ОТЧЕТЫ\НФАОТЧ2007.lst"+"|Непомеченные_НФА", 1.1.100, ДатОпер, Mask101, "~НФА.*");
      |  num=3: aWork=True;
      else aWork=False;
      fi;
   fi;
 fi;
 if aWork:
   if Abs(Turn("+("+Mask104+") {~НФА.*}", 1.1.100, ДатОпер))>0 or Abs(Turn("-("+Mask104+") {~НФА.*}", 1.1.100, ДатОпер))>0:
      num=Enquiry("Выберите действие...", "Обнаружены проводки^Mна ("+Mask104+") счетах^Mнепомеченные справочником НФА!", "Проводки в отчет;Отмена;Игнорировать", mtError);
      if num=1: aWork=False; Report(PlanVar("НФА")+"\ОТЧЕТЫ\НФАОТЧ2007.lst"+"|Непомеченные_НФА", 1.1.100, ДатОпер, Mask104, "~НФА.*");
      |  num=3: aWork=True;
      else aWork=False;
      fi;
   fi;
 fi;
 if not aWork: Exit; fi;
 if РАБ.НФА.LIBREP.СправочникиСтруктурыПоМаскеСчетовПрогресс(Mask101, 1.1.100, ДатОпер, True, True)=" ": Exit; fi; -- если был Except
 if SearchInArray(РАБ.НФА.LIBREP.bindVOC, "НФА.*", True, 1)<1: Message("Справочник 'НФА' не привязан к 101, 102 счетам учета НФА.", mtError); Exit; fi;
 if SearchInArray(РАБ.НФА.LIBREP.bindVOC, "УЧН.*", True, 1)<1: Message("Справочник 'УЧН' не привязан к 101, 102 счетам учета НФА.", mtError); Exit; fi;
 if РАБ.НФА.LIBREP.СправочникиСтруктурыПоМаскеСчетовПрогресс(Mask104, 1.1.100, ДатОпер, True, True)=" ": Exit; fi; -- если был Except
 if SearchInArray(РАБ.НФА.LIBREP.bindVOC, "НФА.*", True, 1)<1: Message("Справочник 'НФА' не привязан к 104 счету учета НФА.", mtError); Exit; fi;
 if SearchInArray(РАБ.НФА.LIBREP.bindVOC, "УЧН.*", True, 1)<1: Message("Справочник 'УЧН' не привязан к 104 счету учета НФА.", mtError); Exit; fi;

 2Создать_СписокИнвентарныхОбъектов0(ДатОпер);
 if LengthOfArray(repUNIQUE)>0: 2Создать_СальдоАмортизации0(ДатОпер); fi;

 num=LengthOfArray(repUNIQUE);
 if not num>0:
   Message("Список инвентарных объектов не создан.^MВозможно картотека НФА пустая^Mили нет проведенных по учету проводок.", mtError);
   Exit;
 fi;

 ShowProgress(num, "Построение отчета...");
 ROнфа=OpenWorkArea("РПО_НФА", "", "");
 ROинв=OpenWorkArea("РПО_ИНВКАРТ_ОС", "", "");
 Try
   ОчисткаТаблицы;
   Try SUMAMT=Com_Var("ОС_100", ДатОпер-1); Except SUMAMT=0.00; end; if not SUMAMT>0.00: if (ДатОпер-1)>=1.1.2011: SUMAMT=40000; else SUMAMT=20000; fi; fi; ConstНФА100П=SUMAMT;
   TimeCreationRep="Время создания отчета: "+DateToString(ToDay)+" "+РАБ.НФА.LIBREP.TimeToHMSstring_Adv(Time, ":");
   xx=0;
   for ii=1 to num do
     ProgressPos(ii);
     if ПроходимОтбор(flg_OnlyTurnAmtExist, repБАЛСУМ[ii], repБАЛКОЛ[ii], repАМТ_СУ[ii], repАМТ_НН[ii], repАМТ_ВЭ[ii], repАМТ_ПУ[ii], repАМТ_ПР[ii]):
       БАЛСЧТ=""; АМТСЧТ=""; КОДНФА=""; КОДУЧН=""; КОДМХЭ=""; КОДМОЛ=""; REC=NIL; ppНФА=0; ppИНВ=0; флг_НеНачислятьАмортизацию=False; ddpu=1.1.100; ddve=1.1.100; SUMAMT=0.00;
       xx=xx+1;
       БАЛСЧТ=ExtractWord(1, repUNIQUE[ii], "#"); if БАЛСЧТ="БАЛ.$$$": БАЛСЧТ=""; fi;
       КОДНФА=ExtractWord(2, repUNIQUE[ii], "#"); if КОДНФА="НФА.$$$": КОДНФА=""; fi;
       КОДУЧН=ExtractWord(3, repUNIQUE[ii], "#"); if КОДУЧН="УЧН.$$$": КОДУЧН=""; fi;
       АМТСЧТ=repСЧТАМТ[ii];                      if АМТСЧТ="АМТ.$$$": АМТСЧТ=""; fi;
       флг_БылЭксплуатации = if(Match(repКОДМХЭ[ii], "М.Э.*"), True, False);

       if Name_A(КОДНФА)<>" ":
         REC=SignToRecord(КОДНФА, False);
         if REC<>NIL: ppНФА=GetRecordNumber(ROнфа, REC); fi;
         if Name_A(КОДУЧН)<>" ":
           REC=SignToRecord("ИНВВЕД."+КОДНФА+"."+КОДУЧН, False);
           if REC<>NIL: ppИНВ=GetRecordNumber(ROинв, REC); fi;
         fi;
       fi;
       if ppНФА>0: флг_НеНачислятьАмортизацию=GetFieldL(ROнфа, ppНФА, "АМОРТ0"); fi;

       ddpu=2ВзятьДатуПринятияУчету_П_модиф0(ROинв, ppИНВ, True, КОДНФА, КОДУЧН, БАЛСЧТ, ДатОпер);
       ddve=2ВзятьДатуВводаЭксплуат_П_модиф0(ROинв, ppИНВ, True, КОДНФА, КОДУЧН, БАЛСЧТ, КОДМХЭ, ДатОпер, ConstНФА100П);
       if not (ddpu>ValidDate) and (ddve>ValidDate): ddpu=ddve; fi;

       if КОДНФА<>"" and КОДУЧН<>"" and Name_A(КОДНФА)<>" " and Name_A(КОДУЧН)<>" ":
         if АМТСЧТ<>"" and Name_S(АМТСЧТ)<>" ":
           SUMAMT=Round(Abs(Saldo(АМТСЧТ+"{"+КОДНФА+"&"+КОДУЧН+"}", ДатОпер)), 2);
         fi;
         if БАЛСЧТ<>"":
           КОДМОЛ = РАБ.НФА.LIBREP.ПоследнийПризнакВПроводкахИзСправочника(БАЛСЧТ, КОДНФА+"&"+КОДУЧН, 1.1.100, ДатОпер, "МОЛ");
           КОДМХЭ = РАБ.НФА.LIBREP.ПоследнийПризнакВПроводкахИзСправочника(БАЛСЧТ, КОДНФА+"&"+КОДУЧН, 1.1.100, ДатОпер, "М");
         fi;
       fi;

       тблКОДНФА[xx] = КОДНФА;                                                   -- код НФА
       тблНМННФА[xx] = Trim(Name_A(КОДНФА));                                     -- наименование НФА
       тблИНВНОМ[xx] = Trim(Name_A("ИНВВЕД."+КОДНФА+"."+КОДУЧН));                -- инвентарный номер
       тблУЧННОМ[xx] = КОДУЧН;                                                   -- учетный номер
       тблКОДМОЛ[xx] = КОДМОЛ;                                                   -- МОЛ
       тблКОДМХЭ[xx] = КОДМХЭ;                                                   -- местонахождение
       тблДАТУЧТ[xx] = ddpu;                                                     -- дата принятия к учету
       тблДАТЭКС[xx] = ddve;                                                     -- дата ввода в эксплуатацию
       тблАМТ_СУ[xx] = repАМТ_СУ[ii];                                            -- амортизация снятая с учета
       тблАМТ_НН[xx] = repАМТ_НН[ii];                                            -- амортизация начисленная - ежемесячно, по норме
       тблАМТ_НЭ[xx] = repАМТ_ВЭ[ii];                                            -- амортизация начисленная - при выдаче в эксплуатацию
       тблАМТ_НУ[xx] = repАМТ_ПУ[ii];                                            -- амортизация начисленная - при принятии к учету
       тблАМТ_НП[xx] = repАМТ_ПР[ii];                                            -- амортизация начисленная - прочее
       тблАМТ_НВ[xx] = тблАМТ_НН[xx]+тблАМТ_НЭ[xx]+тблАМТ_НУ[xx]+тблАМТ_НП[xx];  -- амортизация начисленная - всего
       тблНФА_БС[xx] = repБАЛСУМ[ii];                                            -- НФА на конец периода - балансовая стоимость
       тблНФА_СА[xx] = SUMAMT;                                                   -- НФА на конец периода - амортизация
       тблНФА_ОС[xx] = тблНФА_БС[xx]-тблНФА_СА[xx];                              -- НФА на конец периода - остаточная стоимость
       тблНФА_БК[xx] = repБАЛКОЛ[ii];                                            -- НФА на конец периода - количество

     fi;
   od;
 Finally
   CloseWorkArea(ROинв);
   CloseWorkArea(ROнфа);
   CloseProgress;
   Позиции=LengthOfArray(тблКОДНФА);
   ValidateSectionAll;
   ClearVariable(NN);
 end;

 if Позиции>0: 
   Message("Расчет завершен!^MВремя работы - "+РАБ.НФА.LIBREP.TimeToHMSstring_Adv(Time-начало, ":"), mtInformation); 
 else
   if flg_OnlyTurnAmtExist:
     Message("Сумм амортизации за "+МЕССТР+" "+Str(УЧТГОД)+" не обнаружено!^MВремя работы - "+РАБ.НФА.LIBREP.TimeToHMSstring_Adv(Time-начало, ":"), mtInformation);
   fi;
 fi;

end;

2-- События клеток
Func Field_onEnter(nameField:String; iterFrame:Integer): Logical; -- на входе в клетку
 Flag_onEnter=False;
 if nameField="УЧТГОД"    : SAVГОД=УЧТГОД; Flag_onEnter=True;
 |  nameField="МЕССТР_"   : ОтчетныйПериод_Get; ValidateSectionAll; ^False;
 |  nameField="УЧР_НАИМ"  : ВзятьРеквизиты(УЧР_REC, False); ^False;
 |  nameField="УЧР_ОКПО"  : ВзятьРеквизиты(УЧР_REC, False); ^False;
 |  nameField="ПОД_ИМЯ"   : ПО_Выбор(ПОД_КОД); ^False;
 |  nameField="ПОД_КОД"   : ПО_Выбор(ПОД_КОД); ^False;
 |  nameField="ВНВИД_МОЛ" : ВнВид_МОЛ=ВыборВидаТаблицы(ВнВид_МОЛ); ^False;
 |  nameField="ВНВИД_МХЭ" : ВнВид_МХЭ=ВыборВидаТаблицы(ВнВид_МХЭ); ^False;
 fi;
 ^True;
end;

Proc Field_onExit(nameField:String; iterFrame:Integer); -- на выходе из клетки
 if nameField="УЧТГОД"    : if Flag_onEnter and УЧТГОД<>SAVГОД: if ОтменитьИзмененияУсловийОтчета: УЧТГОД=SAVГОД; fi; fi;
                            SAVГОД=УЧТГОД;
                            ValidateSectionAll;
 |  nameField="УЧР_НАИМ"  : if УЧР_НАИМ="" :  УЧР_ОКПО=""; fi;
 |  nameField="УЧР_ОКПО"  : if УЧР_ОКПО="" :  УЧР_НАИМ=""; fi;
 |  nameField="ПОД_ИМЯ"   : if ПОД_ИМЯ=""  :  ПОД_КОД="";  fi;
 |  nameField="ПОД_КОД"   : if ПОД_КОД=""  :  ПОД_ИМЯ="";  fi;
 |  nameField="ИспФИО"    : if ИспФИО="": ИспДол=""; ИспREC=NIL; fi;
 fi;
 Flag_onEnter=False;
end;

Func Field_OnValidateI(Field:String; Iter:Integer; Value:Integer): Logical;
 if Value<0: Message("Нельзя вводить отрицательное число.", mtError); ^False; fi;
 if Field="УЧТГОД":
   if Value<2000 or Value>2100: Message("Отчетный год задан вне допустимого диапазона.^M[2000-2100 гг.]", mtError); ^False; fi;
 fi;
 ^True;
end;

Func Дата_ПростойВыбор_onLookup(Sect:String; Row:Integer; Col:Integer; Cur:String) :String;
 Template.HideEditor(False);
 SetDate(ВыборДаты(GetDate));
 ^"";
end;

Func Год_onLookup(Sect:String; Row:Integer; Col:Integer; Cur:String) :String;
var ii :Integer;
 Template.HideEditor(False);
 ClearVariable(Buf);
 SAVГОД=УЧТГОД;
 for ii=1 to 5 do Buf[ii]=Str(Year(ToDay)+ii-4); od;
 ii=Alternate("Год расчета", Buf, 20, if(УЧТГОД>2000, 4-(Year(ToDay)-УЧТГОД), 4), 12);
 if ii=0: ^Cur; fi;
 УЧТГОД=Int(Buf[ii]);
 if УЧТГОД<>SAVГОД: if ОтменитьИзмененияУсловийОтчета: УЧТГОД=SAVГОД; fi; ValidateSectionAll; fi;
 SAVГОД=УЧТГОД;
 ^"";
end;

Func Сотрудники_onLookup(Sect:String; Row:Integer; Col:Integer; Cur:String): String;
var FieldName, СТРФИО, СТРДОЛ, tmp1, tmp2 :String;
var REC :Record;
 Template.HideEditor(False);
 if not AutoRefresh: RefreshAna; fi;
 FieldName=asString(Template.Field);
 REC=OpenCardFile("СОТРУДНИКИ", "", ИСПREC, crdRecordOnly);
 if REC=NIL: ^Cur; fi;
 tmp1=GetCardFieldS("СОТРУДНИКИ", REC, "ИНИЦИАЛЫ");
 tmp2=GetCardFieldS("СОТРУДНИКИ", REC, "ФАМИЛИЯ");
 СТРФИО=if(tmp2="", GetCardFieldS("СОТРУДНИКИ", REC, "ФИОТ"), tmp2+" "+if(tmp1<>"..", tmp1, ""));
 Try СТРДОЛ=GetCardFieldS("СОТРУДНИКИ", REC, "ДОЛЖНОСТЬ.ДОЛЖ"); Except СТРДОЛ=""; end;
 if FieldName="ИСПФИО": ИСПФИО=СТРФИО; ИСПДОЛ=СТРДОЛ; ИспREC=REC;
 |  FieldName="ИСПДОЛ": ИСПФИО=СТРФИО; ИСПДОЛ=СТРДОЛ; ИспREC=REC;
 fi;
 ^"";
end;

Func НазваниеКолонки(curMode:String) :String;
 if curMode="0": ^"Снятая с учета амортизация";
 |  curMode="1": ^"Амортизация начисленная ежемесячно, по норме";
 |  curMode="2": ^"Амортизация начисленная при выдаче в эксплуатацию";
 |  curMode="3": ^"Амортизация начисленная при принятии к учету";
 |  curMode="4": ^"Амортизация начисленная прочая";
 else ^"";
 fi;
end;

Func СуммаКолонки(curMode:String) :Numeric;
 if curMode="0": ^итгАМТ_СУ;
 |  curMode="1": ^итгАМТ_НН;
 |  curMode="2": ^итгАМТ_НЭ;
 |  curMode="3": ^итгАМТ_НУ;
 |  curMode="4": ^итгАМТ_НП;
 else ^0.00;
 fi;
end;

Func Read_СуммыДляПерехода(FlagUpdate:Logical; curModeSet:String) :Logical;
var num, ii :Integer;
var SUM :Numeric;
 if not FlagUpdate:
   if savModeSet="" or savModeSet<>curModeSet or BufTxt[1]="" or LengthOfArray(BufTxt)<>LengthOfArray(BufInt) or not LengthOfArray(BufInt)>0:
     FlagUpdate=True;
   fi;
 fi;
 if not FlagUpdate: ^True; fi;
 if СуммаКолонки(curModeSet)<>0.00:
   ClearVariable(BufTxt); ClearVariable(BufInt);
   ShowProgress(Позиции, "Построение ссылок перехода...");
   Try
     num=0;
     for ii=1 to Позиции do
       ProgressPos(ii);
       if curModeSet="0": SUM=тблАМТ_СУ[ii];
       |  curModeSet="1": SUM=тблАМТ_НН[ii];
       |  curModeSet="2": SUM=тблАМТ_НЭ[ii];
       |  curModeSet="3": SUM=тблАМТ_НУ[ii];
       |  curModeSet="4": SUM=тблАМТ_НП[ii];
       else SUM=0.00;
       fi;
       if SUM<>0.00:
         num=num+1;
         InsertInArray(BufTxt, num, Format("%17.2N", SUM)+"--"+тблНМННФА[ii]+" "+тблУЧННОМ[ii]);
         InsertInArray(BufInt, num, ii);
       fi;
     od;
     InsertInArray(BufTxt, 1, "* --Обновить список");
     InsertInArray(BufInt, 1, -1);
   Finally
     CloseProgress;
   end;
 else
   Message("По колонке '"+НазваниеКолонки(curModeSet)+"' движения не обнаружено.", mtError);
   ^False;
 fi;
 num=LengthOfArray(BufInt);
 ^(if(num=LengthOfArray(BufTxt) and num>0, True, False));
end;

Proc CellOnClick(aRow:Integer; aCol:Integer; DblClick:Logical); -- клетка при нажатии
var СекцИмя :Object;
var aMode :String;
var Work :Logical;
var nn :Integer;
 if DblClick:
   if Позиции>0 and FindObject(asString(Template.Name), СекцИмя):
     aMode=Up(asString(СекцИмя.Cell(aRow, aCol, CellContents, "")));
     if (aMode="0" or aMode="1" or aMode="2" or aMode="3" or aMode="4"):
       ClearTrace(True);
       nn=1;
       Work=Read_СуммыДляПерехода(False, aMode);
       if not Work: Exit; fi;
       while nn=1 do
         nn=AlternateTree("Выберите позицию...", BufTxt, -1, 0, 12, "|", "Сумма", "НФА", 12, False);
         if nn=0: Exit; fi;
         if nn=1:
           Work=Read_СуммыДляПерехода(True, aMode);
           if not Work: Exit; fi;
         fi;
       end; --while
       if aMode="0": Template.Field="тблАМТ_СУ";
       |  aMode="1": Template.Field="тблАМТ_НН";
       |  aMode="2": Template.Field="тблАМТ_НЭ";
       |  aMode="3": Template.Field="тблАМТ_НУ";
       |  aMode="4": Template.Field="тблАМТ_НП";
       fi;
       Template.Frame=BufInt[nn];
     fi;
   fi;
 fi;
end;

2-- События объектов
Proc btnOnClick(Sender:String); -- объекты при нажатии
 if Sender="btnExit" : Close;
 |  Sender="btnCalc" : АМТ_МЕС_Отчет_РасчетВыполнить;
 |  Sender="btnWipe" : АМТ_МЕС_Отчет_ОчисткаПолей;
 fi;
end;

Proc Флаги_onChange(Sender:String);
var ОбъектИмя :Object;
var flgNEW, flgOLD :Logical;
var nameVar :String;
 if FindObject(Sender, ОбъектИмя):
   nameVar="flg_"+SubStr(Sender, 5, Length(Sender)-4); -- вычисляем имя переменной - 4 = cbx_
   flgNEW = GetVariableL(nameVar); -- текущий статус;
   flgOLD = not flgNEW; -- предыдущий статус
   if ОтменитьИзмененияУсловийОтчета: flgNEW=flgOLD; fi;
   PutVariableL(nameVar, flgNEW);
   ОбъектИмя.State=flgNEW;
   if flgNEW<>flgOLD: -- доп.обработка
--     if Sender="" : ;
--     fi;
   fi;
   ValidateSectionAll;
 fi;
end;

2-- События шаблона
Proc Template_OnOpen(Create:Logical); -- при открытии шаблона
 РАБ.НФА.LIBREP.CopyCfgPrn("ТББ_STD_Album10_num_000.cfg", True);
end;

Proc Template_AfterOpen(Create:Logical); -- после открытия шаблона
 Очистить;
 Инициализация;
 savModeSet="";
 Template.Field="Фокус";
end;

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

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