БланкСШаблоном "Проверка бухгалтерии"; 

-- Константы кодов ошибок
var цКОДОШИБКИ_НЕТ_ОШИБОК	   :I=0;
var цКОДОШИБКИ_ОКОНЧАНИЕ_730_830   :I=1;
var цКОДОШИБКИ_ОКОНЧАНИЕ_560_660   :I=2;
var цКОДОШИБКИ_ЗАКРЫТИЕ_302_206    :I=3;
var цКОДОШИБКИ_ИСПОЛЬЗОВАНИЕ_40101 :I=4;

var цОшибки :I;

секцОшибкиШапка    :Section;
секцОшибкиЗначения :Section;
секцОшибкиПодвал   :Section;

var цНомПП[]	 :I=$;
var цНомПр[]	 :I;
var сЖурналПр[]  :S;
var чСуммаПр[]	 :N;
var сДебетПр[]	 :S;
var сКредитПр[]  :S;
var сКомментПр[] :S;
var сОписОшибки[]:S;

var Jump[] :I=$;

var сСписокСчетов[] :S;

Proc ОчисткаОтчетов;
  while цОшибки>0 do DeleteFrame(цОшибки,цОшибки); od;
end;

-- Отображение/скрытие отчета по ошибкам
Proc ВидимостьОтчетаПоОшибкамВПроводках;
  var лОтобразить :l;
  лОтобразить=цОшибки>0;
  секцОшибкиШапка.Visible=лОтобразить;
  секцОшибкиЗначения.Visible=лОтобразить;
end;

-- Получение типа КБК по картотеке РПО_БЮДЖ_КЛАСС
Func ВзятьТипКБК (сКБК17 :String; сКОСГУ :String;  сВД :String):S;
  if Match(сКБК17+"."+сКОСГУ,"???.0000.0000000.000.000"): ^"КРZ";
    |Match(сКБК17,"???.0000.0000000.000") and сВД="1":	  ^"КРZ";
    |Match(сКБК17,"???.0000.0000000.000") and сВД="3":	  ^"КРZ";
    |Match(сКБК17,"???.????.???????.???"):		  ^"КРБ";
    |Match(сКБК17,"???.0.00.00000.00.0000"):		  ^"КДZ";
    |Match(сКБК17,"???.?.??.?????.??.????"):		  ^"КДБ";
    |Match(сКБК17,"???.00.00.00.00.00.0000"):		  ^"КИZ";
    |Match(сКБК17,"???.??.??.??.??.??.????"):		  ^"КИФ";
  fi;
end;

-- Формирование массива счетов
Proc ПолучениеСпискаСчетов (сУслОтбора :String);
  var цИнд :i;
  var сСчет26 :string;

  Hint('Построение списка счетов...');
  ClearVariable(сСписокСчетов);
  for account сСчет26=сУслОтбора do
    if СчетБалансовый(сСчет26):
      цИнд=цИнд+1;
      сСписокСчетов[цИнд]=сСчет26;
    fi;
  od;
  Hint('');
end;

-- Проверка допустимости КБК в счетах
Proc ПроверкаДопустимостиКБКСчетов;
  var цКолСчетов,цИнд,цИндСлов :integer;
  var цРО,цНомЗап,цСлов :Integer;
  var сСч8,сТипыКБК,сТип,сКБК17,сСчетПроверки :String;
  var лВерно :Logical;

  цКолСчетов=LengthOfArray(сСписокСчетов);
  цРО=OpenWorkArea("РПО_Бюдж_Класс","Code","Name_Voc='СЧ'");
  try
    ShowProgress(цКолСчетов,'Проверка допустимости КБК в счетах...');
    try
      for цИнд=1..цКолСчетов do
	сСчетПроверки=сСписокСчетов[цИнд];
	сСч8=Раб.Бюджет2005.ВзятьКодСчета(сСчетПроверки,"","СЧ8",false);
	сКБК17=Раб.Бюджет2005.ВзятьКодСчета(сСчетПроверки,"","КБК",false);
	цНомЗап=Search(цРО,1,сСч8);
	if цНомЗап>0:
	  сТипыКБК=Раб.Бюджет2005.Объединить(GetFieldS(цРО,цНомЗап,"S01"),GetFieldS(цРО,цНомЗап,"S02"),",");
	  цСлов=WordsCount(сТипыКБК,",");
	  лВерно=false;
	  for цИндСлов=1..цСлов do
	    сТип=ExtractWord(цИндСлов,сТипыКБК,",");
	    if not Length(сТип)=1:
	      if сТип="КРБ":  if Match(сКБК17,"???.????.???????.???"): лВерно=true; fi;
		|сТип="КРZ":  if Match(сКБК17,"???.0000.0000000.000"): лВерно=true; fi;
		|сТип="КДБ":  if Match(сКБК17,"???.?.??.?????.??.????"): лВерно=true; fi;
		|сТип="КДZ":  if Match(сКБК17,"???.0.00.00000.00.0000"): лВерно=true; fi;
		|сТип="КИФ":  if Match(сКБК17,"???.??.??.??.??.??.????"): лВерно=true; fi;
		|сТип="КИZ":  if Match(сКБК17,"???.00.00.00.00.00.0000"): лВерно=true; fi;
		--|true      :
	      fi;
	    fi;
	  od;
	  if not лВерно: Trace(сСчетПроверки+" - неверный КБК счета"); fi;
	fi;
	ProgressPos(цИнд);
      od;
    finally
      CloseProgress;
    end;
  finally
    CloseWorkArea(цРО);
  end;
end;

-- Процедура для проверки правильности формата счетов с точки зрения соответвия маске
Proc ПроверкаПравильностиФорматаСчета;
  var цКолСчетов,цИнд :integer;
  var сСчет9,сКБК,сСчетПроверки :string;

  цКолСчетов=LengthOfArray(сСписокСчетов);
  ShowProgress(цКолСчетов,'Проверка формата счетов...');
  try
    for цИнд=1..цКолСчетов do
      сСчетПроверки=сСписокСчетов[цИнд];
      сКБК=Раб.Бюджет2005.ВзятьКодСчета(сСчетПроверки,"","КБК",false);
      сСчет9=Раб.Бюджет2005.ВзятьКодСчета(сСчетПроверки,"","СЧ9",false);
      if not ((сСчетПроверки=сКБК+"."+сСчет9) and Match(сСчет9,"?.???.??.???")): Trace(сСчетПроверки+" - неверный формат счета"); fi;
      ProgressPos(цИнд);
    od;
  finally
    CloseProgress;
  end;
end;

-- Общая процедура провеки плана счетов
Proc ПроверкаПланаСчетов;
  ClearTrace;
  Refresh;
  ПолучениеСпискаСчетов("~(*.?.ЗАБ.??.*|ЗАБ.*|00|00Z|ЗАБАЛАНС|ЛИМ_ЗАДАН|ЛИМ_ИСПОЛ)");
  ПроверкаДопустимостиКБКСчетов;
  ПроверкаПравильностиФорматаСчета;
  Message('Проверка завершена');
end;

--
Func ПроверкаПроводки (сСчДеб :String; сСчКред:String): Integer;
  var сКОСГУДеб,сКОСГУКред,сСчетСинтДеб,сСчетСинтКред,сСчетАнДеб,сСчетАнКред :String;
  var цКодОшибки :Integer;

  цКодОшибки=цКОДОШИБКИ_НЕТ_ОШИБОК;
  сКОСГУДеб=Раб.Бюджет2005.ВзятьКодСчета(сСчДеб,"","КОСГУ",false);
  сКОСГУКред=Раб.Бюджет2005.ВзятьКодСчета(сСчКред,"","КОСГУ",false);
  сСчетСинтДеб=Раб.Бюджет2005.ВзятьКодСчета(сСчДеб,"","СИНТ",false);
  сСчетСинтКред=Раб.Бюджет2005.ВзятьКодСчета(сСчКред,"","СИНТ",false);
  сСчетАнДеб=Раб.Бюджет2005.ВзятьКодСчета(сСчДеб,"","АН",false);
  сСчетАнКред=Раб.Бюджет2005.ВзятьКодСчета(сСчКред,"","АН",false);
  if сКОСГУКред="830" or сКОСГУДеб="730": цКодОшибки=цКОДОШИБКИ_ОКОНЧАНИЕ_730_830; return цКодОшибки;
    |сКОСГУКред="560" or сКОСГУДеб="660": цКодОшибки=цКОДОШИБКИ_ОКОНЧАНИЕ_560_660; return цКодОшибки;
  fi;
  if ((сСчетСинтДеб="302" and сКОСГУДеб="830") and (сСчетСинтКред="206" and сКОСГУКред="660")):
    if not (сСчетАнДеб = сСчетАнКред): цКодОшибки=цКОДОШИБКИ_ЗАКРЫТИЕ_302_206; return цКодОшибки; fi;
  fi;
  if(сСчетСинтДеб="401" and сСчетАнДеб="01") or (сСчетСинтКред="401" and сСчетАнКред="01"): цКодОшибки=цКОДОШИБКИ_ИСПОЛЬЗОВАНИЕ_40101; return цКодОшибки; fi;
  return цКодОшибки;
end;

-- Проверка правильности использования счетов в проводках
Proc ПроверкаПроводок;
  var цПр,цКодОшибки :Integer;

  ClearTrace;
  while цОшибки>0 do DeleteFrame(цОшибки,цОшибки); od;
  ClearVariable(цНомПП);
  ClearVariable(цНомПр);
  ClearVariable(сЖурналПр);
  ClearVariable(чСуммаПр);
  ClearVariable(сДебетПр);
  ClearVariable(сКредитПр);
  ClearVariable(сКомментПр);
  ClearVariable(сОписОшибки);

  for transaction цПр='*',1.1.100,Today+1 do
    цКодОшибки=ПроверкаПроводки(TransDeb(цПр),TransCre(цПр));
    if цКодОшибки<>цКОДОШИБКИ_НЕТ_ОШИБОК:
      InsertFrame(цОшибки,цОшибки+1);
      цНомПр[цОшибки]=цПр;
      сЖурналПр[цОшибки]=JournalName(TransJurNum(цПр));
      чСуммаПр[цОшибки]=TransSum1(цПр);
      сДебетПр[цОшибки]=TransDeb(цПр);
      сКредитПр[цОшибки]=TransCre(цПр);
      сКомментПр[цОшибки]=TransComment(цПр);
      if цКодОшибки=цКОДОШИБКИ_ОКОНЧАНИЕ_730_830:   сОписОшибки[цОшибки]='КОСГУ 730 в дебете либо 830 в кредите';
	|цКодОшибки=цКОДОШИБКИ_ОКОНЧАНИЕ_560_660:   сОписОшибки[цОшибки]='КОСГУ 660 в дебете либо 560 в кредите';
	|цКодОшибки=цКОДОШИБКИ_ЗАКРЫТИЕ_302_206:    сОписОшибки[цОшибки]='Не совпадающие счета аналитического учета при списании (зачете) аванса';
	|цКодОшибки=цКОДОШИБКИ_ИСПОЛЬЗОВАНИЕ_40101: сОписОшибки[цОшибки]='Недопустимо использование счета 401.01 в проводках!';
      fi;
    fi;
  od;
  ВидимостьОтчетаПоОшибкамВПроводках;
  Message('Проверка завершена!');
end;


Proc Button1_OnClick(Sender: String);
  ПроверкаПланаСчетов;
end;


Proc Button2_OnClick(Sender: String);
  ПроверкаПроводок;
end;


Func Jump_OnLookup(Sect: String; Row: Integer; Col: Integer; Cur: String): String;
  Template.HideEditor(False);
  TransOpenJur(цНомПр[Int(Row/2)]);
  return Cur;
end;


Proc OnOpen(Create: Logical);
  ОчисткаОтчетов;
  ВидимостьОтчетаПоОшибкамВПроводках;
  Refresh;
end;


Конец
