-- Шаблон создан мастером бланков
-- 18.11.2004 13:25:39
--
БланкСШаблоном "Работа с планом бухгалтерии";
var buf[]:s;
var buf1[]:s;
var buf2[]:s;
var TempStrArray1[]:s;
var TempStrArray2[]:s;

-- массивы структуры плана бухгалтерии
var Plan_Direct[]:s; --список директив влана бухгалтерии в порядке их описания в плане
var Plan_DirectV[]:s;--список значений директив
var Plan_DirectC[]:s;--список сомментариев директив
var Plan_DirectV_full[]:s;--список значений директив с расшифровкой макроподстановок и полными путями

-- массивы структуры текущего плана бухгалтерии
var CurPlan_Direct_ready:l; -- флаг загрузки текущего плана бухгалтерии
var CurPlan_DirectFull_ready:l; -- флаг загрузки текущего плана бухгалтерии c полными путями
var CurPlan_Direct[]:s; --список директив влана бухгалтерии в порядке их описания в плане
var CurPlan_DirectV[]:s;--список значений директив
var CurPlan_DirectC[]:s;--список сомментариев директив
var CurPlan_DirectV_full[]:s;--список значений директив с расшифровкой макроподстановок и полными путями


var PLAN_NAME_FULL:s;   -- полное имя текущего плана бухгалтерии (путь к плану, в т.ч.сетевой\план.pro)
var PLAN_FOLDER_FULL:s; -- полное имя папки с текущим планом бухгалтерии (путь к папке с планом, в т.ч.сетевой)
var CurPlan_FOLDER[]:i;
var ПолныйСписокБланков[]:s;
var PAR_JDF[]:s;--список распарсерных JDF
---------------------- функции обработки текста из файлов -------------------
func txt_unformat_TB(ss:s):s; -- удаляет форматирование ТБ (жирн, курсив и т.п.)
var z,j:i;
var rez,tab:s;
    tab=chr(127);
    z=pos(tab,ss);
    if z>0:
      rez=ВыделитьСлово(1,ss,tab);
      if z=1:rez=SubStr(rez,2,255);fi;
      z=КоличествоСлов(ss,tab);
      for j=2..z do
        rez=rez+SubStr(ВыделитьСлово(j,ss,tab),2,255);
      od;
     | true:
       rez=ss;
    fi;
    ^rez;
end;

func txt_standart(ss:s):s; -- удаляет форматирование ТБ (жирн, курсив и т.п.), замена табуляции на пробелы
var z,j:i;
var rez,tab:s;
    ss=txt_unformat_TB(ss);
    tab=chr(9);
    if pos(tab,ss)>0:
      z=КоличествоСлов(ss,tab);
      for j=1..z do
        rez=rez+' '+ВыделитьСлово(j,ss,tab);
      od;
     | true:
       rez=ss;
    fi;
    ^rez;
end;

func УдалитьВнешниеСкобки(st:s;parenthesis:s):s;-- удаляет первый и последний символ в st, если они в паре есть в списке скобок parenthesis с разделителем пар = пробелу (пример списка="() {} [] '' "+'""')
var z,j:i;
var rez:s;
    parenthesis=' '+parenthesis+' ';
    rez=SubStr(st,1,1)+SubStr(st,length(st),1);
    if pos(rez,parenthesis)>0:
       rez=SubStr(st,2,length(st)-2);
     | true:rez=st;
    fi;
    ^rez;
end;
func del_ext_quote(st:s):s; -- удалить внешние кавычки (проверяет как двойные так и одинарные - опострофы)
    ^УдалитьВнешниеСкобки(st,"'' "+'""');
end;
Func POS_end(s1:S;s2:S) :i; --последний POS в строке
var p,lens1,lens2:i;
  p=pos(s1,s2);
  if p<1:^p;fi;
  lens1=length(s1);
  lens2=length(s2);
  while p>0 do
    s2=SubStr(s2,p+lens1,255);
    p=pos(s1,s2);
  od;
  p=lens2-Length(s2)-lens1+1;
  ^p;
end;

  Func Загрузить_СтрМассив_ИзФайла(m2:l;нач1:i;Файл:s):l;
    var нф,i:i;
    var ss1,ss2:s;
    var ll:l;
    ll=false;
    if нач1<1:нач1=1;fi;
    if не ЕстьФайл(Файл):^false;fi;
     Попытка
      нф =ТекстФайлОткрытьНаЧтение(Файл);
      Пока не ТекстФайлКонецФайла(нф) do
        ss1=ТекстФайлПрочитать(нф,255);
        if не ТекстФайлКонецФайла(нф):
         ss2=ТекстФайлПрочитатьСтроку(нф);
        fi;
        if not m2:
           if Длина(ss1)>0:
             TempStrArray1[нач1]=ss1;
             нач1=нач1+1;
           fi;
         | true:
           if Длина(ss1)>0:
             TempStrArray1[нач1]=ss1;
             TempStrArray2[нач1]=ss2;
             нач1=нач1+1;
           fi;
        fi;
      od;
      ll=true;
     Окончание
      ТекстФайлЗакрыть(нф);
     Конец;
    ^ll;
  end;

  Func Выгрузить_СтрМассив_Вфайл(m2:l;нач1:i;нач2:i;Файл:s;Дописывать:l;DOS:l):l;
    var нф1,i:i;
    var ss1,ss2:s;
    var ll:l;
    ll=false;
    if не ЕстьФайл(Файл) или не Дописывать:СоздатьФайл(Файл);fi;
     Попытка
      нф1=ТекстФайлОткрытьНаЗапись(Файл,DOS);
      ТекстФайлВКонец(нф1);
      if not m2:
         for i=нач1..нач2 do
            ss1=TempStrArray1[i];
           ТекстФайлЗаписатьСтроку(нф1,ss1);
         od;
       | true:
         for i=нач1..нач2 do
            ss1=TempStrArray1[i];
            ss2=TempStrArray2[i];
           ТекстФайлДописатьСтроку(нф1,ss1);
           ТекстФайлЗаписатьСтроку(нф1,ss2);
         od;
      fi;
      ll=true;
     Окончание
      ТекстФайлЗакрыть(нф1);
     Конец;
    ^ll;
  end;
Func ПравильныйФильтрНаКартотеку(F:S;CRD:S):l;
  var wa:i;
  var ll:l;
  if trim(f)='':^true;fi;
  try
    wa=openworkarea(CRD,'','1=0 and('+F+')');
    CloseWorkArea(wa);
    ll=true;
  except
    ll=false;
  end;
  ^ll;
end;

---------------------- конец функции обработки текста из файлов -------------------
---------------------- функции обработки файлов из плана бухгалтерии -------------------
var par[]:s; -- массив параметров выбранных из файла (строка имя параметра, следующая строка - его значение, имя параметра начинается на @)

Func Get_Real_FILTER_JDF(F:S;CRD:S) :String; -- разбор строки с фильтром в которой замешан комментарий с "опасными" закрывающимися круглыми скобками
-- Пример фильтра F заключен между  символов @
--    @"проводить и соотв(код,"ВНЕШНИЕ_*")" ) -- (проблемный комментарий)@
var wa,z,k:i;
var ll:l;
  ll=false;
  F=trim(F);
  k=0;-- для ограничения при зацикливании
  While not ПравильныйФильтрНаКартотеку(trim(del_ext_quote(F)),CRD) and k<255 do
    if SubStr(F,length(F),1)=')':F=SubStr(F,1,Length(F)-1);
     | true:z=POS_end(')',F);F=SubStr(F,1,z-1);
    fi;
     F=trim(F);
    k=k+1;
  od;
^trim(del_ext_quote(F));
end;

Func GET_PAR_JDF0(JDFфайл:S) :i;-- возвращает количество найденых параметров
-- par[1]=КАРТОТЕКА
-- par[2]=ПОЛЕ ДАТЫ
-- par[3]=ПОЛЕ УПОРЯДОЧИВАНИЯ
-- par[4]=ФИЛЬТР НА КАРТОТЕКУ
-- par[5]=ПОДТАБЛИЦА:ИМЯ ОПЕРАЦИИ
-- par[6]=ПОДТАБЛИЦА:ИМЯ ОПЕРАЦИИ
-- par[7]=ПОДТАБЛИЦА:ИМЯ ОПЕРАЦИИ
var File, x, j ,pcmnt,rez:Integer;
var tmp, res ,crd,crdf,dd,cmnt,ord:String;
 res="";
 cmnt='--';
 File=TextFileOpenRead(JDFфайл);
 ClearVariable(Раб.План.par);
 Try
   while not TextFileEndOfFile(File) do
     tmp=Up(TextFileReadLn(File));
     tmp=txt_standart(tmp);
     if rez>4:-- уже было описание картотеки
        pcmnt=Pos(cmnt, tmp);
        if pcmnt>0:tmp=trim(substr(tmp,1,pcmnt-1));fi;
        x=Pos(':', tmp);
        if x>0:
           tmp=trim(substr(tmp,1,x-1))+':'+trim(substr(tmp,x+1,255));
           rez=rez+1;
           par[rez]=tmp;
        fi;
      | true:
        pcmnt=Pos(cmnt, tmp);
        x=max(Pos("КАРТОТЕКА", tmp),Pos("CARDFILE", tmp));
        if x>0 and (x<pcmnt or pcmnt=0):
          rez=4;
          x=Pos("(", tmp);
          crd=trim(ВыделитьСлово(2,SubStr(tmp,1,x-1),' '));
          tmp=trim(SubStr(tmp, x+1, 255));
   --       pcmnt=Pos(cmnt, tmp);
          x=Pos(",", tmp);
          j=Pos(")", tmp);
          if x<j and x>0: -- есть еще параметр ord
            dd =trim(SubStr(tmp,1,x-1));
            tmp=trim(SubStr(tmp, x+1, 255));
            x=Pos(",", tmp);
            j=Pos(")", tmp);
            if x<j and x>0: -- есть еще параметр фильтр (который всегда в кавычках)
              ord =trim(SubStr(tmp,1,x-1));
              tmp =trim(SubStr(tmp, x+1, 255)); -- взяли фильтр

              x=Pos("'", tmp);
              j=Pos('"', tmp);
              if min(x,j)<1:res=SubStr(tmp,max(x,j),1);
               | true:res=SubStr(tmp,min(x,j),1);
              fi;
              x=POS_end(res,tmp);
              j=Pos(res, tmp);
              tmp =trim(SubStr(tmp, j+1, x-2)); -- фильтр без кавычек
              pcmnt=Pos(cmnt, tmp);
              if pcmnt<1:crdf=tmp; -- если нет комментария внутри фильтра, то нашли правильный фильтр
               | true:tmp=res+tmp+res; -- есть комментарий - нужна спец проверка
                 crdf=Get_Real_FILTER_JDF(tmp,crd);
              fi;
             | true: ord =trim(SubStr(tmp,1,j-1));
            fi;
           | true: dd =trim(SubStr(tmp,1,j-1));
          fi;
       fi;
     fi;
   od;
 Except
   TextFileClose(File);
   ^0;
 end;
 TextFileClose(File);
 par[1]=crd;
 par[2]=dd;
 par[3]=ord;
 par[4]=crdf;
 ^rez;
end;
Func GET_PAR_JDF(JDFфайл:S) :i;-- возвращает количество найденых параметров
var k, x, j ,pcmnt,rez:Integer;
var tmp, res ,crd,crdf,dd,cmnt,ord:String;
 if JDFфайл='':^0;fi;
 JDFфайл=up(JDFфайл);
 if LengthOfArray(PAR_JDF)>1 and PAR_JDF[1]='':ClearVariable(Раб.План.PAR_JDF);fi;
 j=SearchInArray(PAR_JDF,'JDF='+JDFфайл);
 if j<1:
   rez=GET_PAR_JDF0(JDFфайл);
   x=LengthOfArray(PAR_JDF)+1;
   PAR_JDF[x]='JDF='+JDFфайл;
   CopyArray(Раб.План.par, Раб.План.PAR_JDF,1,x+1);
   ^rez;
 fi;
 x=LengthOfArray(PAR_JDF);
 ClearVariable(Раб.План.par);
 rez=0;
 for k=j+1..x do
   if pos('JDF=',PAR_JDF[k])=1:^rez;fi;
   rez=rez+1;
   par[rez]=PAR_JDF[k];
 od;
 ^rez;
end;
Func GET_DATEFIELD_JDF(JDFфайл:S) :s;
 if GET_PAR_JDF(JDFфайл)<2: ^''; fi;
 ^par[2];
end;
Func GET_ORDER_JDF(JDFфайл:S) :s;
 if GET_PAR_JDF(JDFфайл)<3: ^''; fi;
 ^par[3];
end;
Func GET_FILTER_JDF(JDFфайл:S) :s;
 if GET_PAR_JDF(JDFфайл)<4: ^''; fi;
 ^par[4];
end;

---------------------- конец функции обработки файлов из плана бухгалтерии -------------------

Func GetPlanVar(PVar:s):s;  -- возвращает значение директивы КАТАЛОГИ с именем PVar из плана бухгалтерии , если такой директивы нет - пустая строка
  try
   ^PlanVar(PVar);
  except
  end;
  ^'';
end;
Func ExistPlanVar(PVar:s):l; -- проверка на существование директивы КАТАЛОГИ с именем PVar
var ss:s;
var ll:l;
  try
   ss=PlanVar(PVar);
   ll=true;
  except
   ll=false;
  end;
  ^ll;
end;


Func ВзятьCACHEПлана:s;-- Полный путь к папке с временными файлами для текущего плана бухгалтерии (с учетом ключа DBOPATH),без "\" в конце результата
 var ss,ds:s;
 var p:i;
 ss=trim(BlankFileName('B'));
 if SubStr(ss,1,2)='\\':ds='\\';ss=SubStr(ss,3,255);
  | true:ds='';
 fi;
 p=КоличествоСлов(ss,'\');
 ss=ds+ВыделитьСлова(1,p-1,ss,'\');
 ^ss;
end;

Func ВзятьПапкуПлана:s; -- имя папки с текущим планом без полного пути
 var ss:s;
 var p:i;
 ss=BlankFileName('B');
 p=КоличествоСлов(ss,'\');
 ss=ВыделитьСлово(p-1,ss,'\');
 ^ss;
end;

Func ВзятьИмяПлана:s;-- имя текущего плана без полного пути
 var ss:s;
 var p:i;
 ss=BlankFileName('B');
 p=КоличествоСлов(ss,'\');
 ss=ВыделитьСлово(p,ss,'\');
 p=length(ss);
 ss=SubStr(ss,1,p-3)+'pro';
 ^ss;
end;

Proc Load_Plan_Direct(PlanFile:s;ТекущийКаталог:s); --формируем массивы структуры любого плана бухгалтерии
-- PlanFile = если полное имя файла с полным путем к нему, то расчитываем Plan_DirectV_full
-- ТекущийКаталог= имя добавляемой в план директивы КАТАЛОГИ (пример: ТЕКУЩИЙКАТАЛОГ=.), если не найдено ни одной директивы каталоги вида КАТАЛОГИ ИМЯ=.
-- примечание: функция PlanVar возвращает полный путь к текущему плану бухгалтерии (включая вариант расположения текущего плана бухгалтерии в сети) 
-- при варианте строки в плане бухгалтерии "КАТАЛОГИ ИМЯ=." , где ИМЯ  - любое  имя директивы КАТАЛОГИ
    var нф,i,cur_line,p1,p2,p,t,z:i;
    var ss1,ss2,s0,ss:s;
    var s_direct:s;
    var ПолныйПуть_PlanFile:s;
    var ПолныйПуть_PlanFile_выше_уровень:s;
    var Direct_List:s;
    var Direct_ListRU:s;
    var Direct_ListEN:s;
    var Direct_ListRU_as_file_DirectV_full  :s;
    var Direct_ListRU_as_folder_DirectV_full:s;
    var ll,m2,m2_Слитно,Кмнт_сразу_за_директивой,PlanFile_Full:l;
  ClearVariable(Раб.План.Plan_Direct      );
  ClearVariable(Раб.План.Plan_DirectV     );
  ClearVariable(Раб.План.Plan_DirectC     );
  ClearVariable(Раб.План.Plan_DirectV_full);
  Direct_ListRU=' КАТАЛОГИ БАЗА_ДАННЫХ ЖУРНАЛ РАЗДЕЛ ТАБЛИЧНЫЙ_ЖУРНАЛ ЖУРНАЛ_КАРТОТЕКА СЧЕТА ПРИЗНАКИ ПРИЗНАКИДОП ОПЕРАЦИИ ПЕРЕМЕННЫЕ БЛАНКИ ПАПКИ_БЛАНКОВ АВТОЗАПУСК ПРОПИСИ ЗАГОЛОВОК ИНТЕРФЕЙС БД_ЗЕРКАЛО_ИСТОЧНИК БД_ЗЕРКАЛО_ПРИЕМНИК ПАПКА_БРО ПАПКА_ОТЧЕТЫ ';
  Direct_ListEN=' DIR DATA_BASE JOURNALS PARTITIONS TAB_JUR JOURNAL_CARDFILE ACCOUNTS SIGNS SIGNSADD OPERATIONS VARS BLANKS BLANKS_FOLDER AUTOEXEC SPELLINGS CAPTION INTERFACE DB_MIRROR_SOURCE DB_MIRROR_RECEIVER FOLDER_BRO FOLDER_REPORTS ';
  Direct_ListRU_as_file_DirectV_full  =' ЖУРНАЛ ЖУРНАЛ_КАРТОТЕКА СЧЕТА ПРИЗНАКИ ПРИЗНАКИДОП ОПЕРАЦИИ ПЕРЕМЕННЫЕ БЛАНКИ ПРОПИСИ ИНТЕРФЕЙС ';
  Direct_ListRU_as_folder_DirectV_full=' КАТАЛОГИ ПАПКИ_БЛАНКОВ ПАПКА_БРО ПАПКА_ОТЧЕТЫ ';

  if not existfile(PlanFile):exit;fi;
   s0='';ss=PlanFile;
   PlanFile_Full=pos('\\',ss)=1 or pos(':\',ss)=2;
   if PlanFile_Full:
      if pos('\\',ss)=1:s0='\\';ss=SubStr(ss,3,255);
       | pos(':\',ss)=2:s0=SubStr(ss,1,3);ss=SubStr(ss,4,255);
      fi;
      p=КоличествоСлов(ss,'\');
      ПолныйПуть_PlanFile=s0+ВыделитьСлова(1,p-1,ss,'\');
      ПолныйПуть_PlanFile_выше_уровень=s0+ВыделитьСлова(1,p-2,ss,'\');
    | true:
      ПолныйПуть_PlanFile='';
      ПолныйПуть_PlanFile_выше_уровень='';
   fi;
    cur_line=0;
    ll=false;
     Попытка
      if ТекущийКаталог='':
         нф =ТекстФайлОткрытьНаЧтение(PlanFile);
       | true:
         try
           нф =ТекстФайлОткрытьНаЗапись(PlanFile);
         except
         end;

         if нф<1:
          try
           ll=ЗакрытьРедактор (PlanFile,false);
           ll=false;
          except
          end;
         fi;

         if нф<1:
          try
            нф =ТекстФайлОткрытьНаЗапись(PlanFile);
          except
            message('Невозможно изменить файл:'+PlanFile,mterror);
            нф =ТекстФайлОткрытьНаЧтение(PlanFile);
            ТекущийКаталог='';
          end;
         fi;
      fi;
      Пока не ТекстФайлКонецФайла(нф) do
        ss1=ТекстФайлПрочитать(нф,255);
        ss1=txt_standart(ss1);
        if не ТекстФайлКонецФайла(нф):
         ss2=ТекстФайлПрочитатьСтроку(нф);
         ss2=txt_standart(ss2);
        fi;
        m2=Length(trim(ss2))>0;
        s0=up(trim(ss1));
        s_direct=(ВыделитьСлово(1,s0,' '));
        p=pos('--',s_direct);
        if p>0:s_direct=SubStr(s_direct,1,p-1);Кмнт_сразу_за_директивой=true;
         | true:Кмнт_сразу_за_директивой=false;
        fi;
        s_direct=' '+s_direct+' ';
        p1=pos(s_direct,Direct_ListEN);
        p2=pos(s_direct,Direct_ListRU);
        if p1>0 or p2>0: --нашли строку с действующей директивой плана
           if p1>0:s_direct=SubStr(s_direct,1,p1);
                   p1=КоличествоСлов(Direct_ListEN,' ');
                   s_direct=ВыделитьСлово(p1+1,Direct_ListRU,' ');
            | p2>0:s_direct=trim(s_direct);
           fi;
         | true:s_direct='';
        fi;
        if s_direct<>'':--обрабатываем строку с действующей директивой плана
           cur_line=cur_line+1;
           Plan_Direct  [cur_line]=s_direct;
           if Кмнт_сразу_за_директивой: -- директива без параметров
              p1=pos('--',ss1);
              Plan_DirectC [cur_line]=SubStr(ss1,p1+2,255);
              if m2:Plan_DirectC [cur_line]=Plan_DirectC [cur_line]+ss2;fi;
            | true:
              if m2:
                if pos(' ',ss2)=1 or SubStr(ss1,Length(ss1),1)=' ':
                   ss1=trim(ss1);
                   ss2=' '+trim(ss2);
                 | true:
                   ss1=trim(ss1);
                   ss2=trim(ss2);
                fi;
                p1=pos(' ',ss1);
                ss1=trim(SubStr(ss1,p1,255));
               | true:
                ss1=trim(ss1);
                p1=pos(' ',ss1);
                ss1=trim(SubStr(ss1,p1,255));
              fi;
              p1=pos('--',ss1);
              if p1>0:-- комментарий в первых 255 символах
                 Plan_DirectC [cur_line]=trim(SubStr(ss1,p1+2,255))+ss2;m2=false;ss1=trim(SubStr(ss1,1,p1-1));
               | true:
                 p1=pos('--',ss2);
                 if p1>0:-- комментарий во вторых 255 символах
                    Plan_DirectC [cur_line]=trim(SubStr(ss2,p1+2,255));ss2=trim(SubStr(ss2,1,p1-1));
                    if length(ss1)+length(ss2)<256:
                       m2=false;ss1=ss1+ss2;
                    fi;
                 fi;
              fi;
              --------------- обработка директивы без комментария ------------
              Plan_DirectV[cur_line]=ss1+ss2;
              if PlanFile_Full:
                 s_direct=' '+s_direct+' ';
                 p1=pos(s_direct,Direct_ListRU_as_file_DirectV_full);
                 p2=pos(s_direct,Direct_ListRU_as_folder_DirectV_full);
                 if p1>0 or p2>0:--надо считать полный путь
                    ss2='';
                    if s_direct=' КАТАЛОГИ ':
                      ss2=trim(ВыделитьСлово(1,ss1,'='))+'=';
                      ss1=trim(ВыделитьСлово(2,ss1,'='));
                    fi;
                    s0='';-- макроподстановка
                    if pos('$',ss1)=1:-- есть макроподстановка
                       ss1=SubStr(ss1,2,255);
                       p=pos('\',ss1);
                       if p>0:s0=trim(SubStr(ss1,1,p-1));ss1=SubStr(ss1,p+1,255);
                        | true:s0=ss1;ss1='';
                       fi;
--                     | true:s0=ss1;ss1='';
                    fi;
                    if length(s0)>0:
                       s0=up(planvar(s0));
                       if pos('\\',s0)=1:ll=true;
                        | pos(':\',s0)=2:ll=true;
                        | true:          ll=false;
                       fi;
                       if not ll:-- нет полного пути- пытаемся найти
                          if pos('..',s0)=1:s0=ПолныйПуть_PlanFile_выше_уровень+SubStr(s0,3,255);
                           | pos('.',s0)=1 :s0=ПолныйПуть_PlanFile+SubStr(s0,2,255);
                           | true          :s0=ПолныйПуть_PlanFile+'\'+s0;
                          fi;
                       fi;
                       p=length(s0);
                       if substr(s0,p,1)<>'\':s0=s0+'\';fi;
                     | true:
                       if pos('\\',ss1)=1:ll=true;
                        | pos(':\',ss1)=2:ll=true;
                        | true:          ll=false;
                       fi;
                       if not ll:-- нет полного пути- пытаемся найти
                          if pos('..',ss1)=1:ss1=ПолныйПуть_PlanFile_выше_уровень+SubStr(ss1,3,255);
                           | pos('.',ss1)=1 :ss1=ПолныйПуть_PlanFile+SubStr(ss1,2,255);
                           | true          :ss1=ПолныйПуть_PlanFile+'\'+ss1;
                          fi;
                       fi;
                       p=length(ss1);
                       if substr(ss1,p,1)<>'\':ss1=ss1+'\';fi;
                    fi;
                    Plan_DirectV_full[cur_line]=trim(ss2+s0+ss1);
                    if p2>0:-- удаляем последний слеш для папки
                       p2=Length(Plan_DirectV_full[cur_line]);
                       if SubStr(Plan_DirectV_full[cur_line],p2,1)='\':
                          Plan_DirectV_full[cur_line]=SubStr(Plan_DirectV_full[cur_line],1,p2-1);
                       fi;
                    fi;
                 fi;
              fi;
           fi;
        fi;
      od;
      ll=true;
      if ТекущийКаталог<>'':
         z=LengthOfArray(Раб.План.CurPlan_Direct);
         for t=1..z do
           if CurPlan_Direct[t]='КАТАЛОГИ':
              ss1=trim(CurPlan_DirectV[t]);
              if КоличествоСлов(ss1,'=')=2:
                 ss2=trim(ВыделитьСлово(2,ss1,'='));
                 ss1=trim(ВыделитьСлово(1,ss1,'='));
                 if ss1=ТекущийКаталог:break;fi;
--                 if ss2='.':^trim(ВыделитьСлово(1,ss1,'='));
--                 fi;
              fi;
           fi;
         od;
         if ss1<>ТекущийКаталог:
            ТекстФайлВКонец(нф);
            ТекстФайлЗаписатьСтроку(нф,'КАТАЛОГИ '+ТекущийКаталог+'=.');
         fi;
      fi;
     Окончание
      ТекстФайлЗакрыть(нф);
     Конец;

--  Загрузить_СтрМассив_ИзФайла(true,1,PlanFile);



end;

Proc Load_CurPlan_Direct; --формируем массивы структуры текущего плана бухгалтерии
  if CurPlan_Direct_ready:exit;fi;
  Load_Plan_Direct(ВзятьИмяПлана,'');
  CopyArray(Раб.План.Plan_Direct      ,Раб.План.CurPlan_Direct);
  CopyArray(Раб.План.Plan_DirectV     ,Раб.План.CurPlan_DirectV);
  CopyArray(Раб.План.Plan_DirectC     ,Раб.План.CurPlan_DirectC);
  CopyArray(Раб.План.Plan_DirectV_full,Раб.План.CurPlan_DirectV_full);
  CurPlan_Direct_ready=true;
end;

func GetPlanVar_cur(ДобавитьДирективуКаталогиЕслиТакойНет:s):s;-- Возвращаяет директиву КАТАЛОГИ с точкой после "="
var z,t:i;
var ss1,ss2:s;
  if CurPlan_Direct_ready:
   | true:Load_CurPlan_Direct;
  fi;
  z=LengthOfArray(Раб.План.CurPlan_Direct);
  for t=1..z do
    if CurPlan_Direct[t]='КАТАЛОГИ':
       ss1=trim(CurPlan_DirectV[t]);
       if КоличествоСлов(ss1,'=')=2:
          ss2=trim(ВыделитьСлово(2,ss1,'='));
          if ss2='.':^trim(ВыделитьСлово(1,ss1,'='));
          fi;
       fi;
    fi;
  od;
  CurPlan_Direct_ready=false;
  Load_Plan_Direct(ВзятьИмяПлана,ДобавитьДирективуКаталогиЕслиТакойНет);

  CurPlan_Direct_ready=false;
  ^trim(ДобавитьДирективуКаталогиЕслиТакойНет);
end;

func ВзятьПолныйПутьПапкиПлана:s;
var ss,ss1:s;
var nf:i;
var ll:l;
 if trim(PLAN_FOLDER_FULL)<>'':^PLAN_FOLDER_FULL;fi;
--  CurPlan_Direct_ready=false;
  ss=GetPlanVar_cur('ТЕКУЩИЙКАТАЛОГ');
  ll=false;
  try
    ss1=PlanVar(ss);
    ll=true;
  except
  end;
  if not ll:
    try
      RefreshAna;
    except
    end;
    ss1=PlanVar(ss);
  fi;
 PLAN_FOLDER_FULL=ss1;
 ^ss1;
end;

func ВзятьПолноеИмяПлана:s;
 if trim(PLAN_NAME_FULL)<>'':^PLAN_NAME_FULL;fi;
 if trim(PLAN_FOLDER_FULL)='':
    PLAN_FOLDER_FULL=trim(ВзятьПолныйПутьПапкиПлана);
 fi;
 PLAN_NAME_FULL=PLAN_FOLDER_FULL+if(SubStr(PLAN_FOLDER_FULL,length(PLAN_FOLDER_FULL),1)='\','','\')+ВзятьИмяПлана;
 ^PLAN_NAME_FULL;
end;

Proc Load_CurPlan_DirectFull; --формируем массивы структуры текущего плана бухгалтерии
  if CurPlan_DirectFull_ready:exit;fi;
  Load_Plan_Direct(ВзятьПолноеИмяПлана,'');
  CopyArray(Раб.План.Plan_Direct       ,Раб.План.CurPlan_Direct);
  CopyArray(Раб.План.Plan_DirectV      ,Раб.План.CurPlan_DirectV);
  CopyArray(Раб.План.Plan_DirectC      ,Раб.План.CurPlan_DirectC);
  CopyArray(Раб.План.Plan_DirectV_full ,Раб.План.CurPlan_DirectV_full);
  CurPlan_Direct_ready=true;
  CurPlan_DirectFull_ready=true;
end;
Func ВзятьПолныйПутьКаталога(v:s):s;
var z,j,k:i;
  Load_CurPlan_DirectFull;
  v=trim(v);
  z=LengthOfArray(Plan_DirectV_full);
  for j=1..z do
   if Plan_Direct[j]='КАТАЛОГИ':
      k=pos('=',Plan_DirectV_full[j]);
      if v=trim(SubStr(Plan_DirectV_full[j],1,k-1)):
         ^trim(SubStr(Plan_DirectV_full[j],k+1,255));
      fi;
   fi;
  od;
  ^'';
end;

Func ВзятьПолныйПутьSTD_RPO:s;
 var STD,ss:s;
 var ll:l;
 var z,p,t:i;
 STD=GetPlanVar('STD_RPO');
 if STD="":ll=false;
  | pos('\\',STD)=1:ll=true;
  | pos(':\',STD)=2:ll=true;
  | true:ll=false;
 fi;
 if ll:^STD;fi;
 if pos('.',STD)>0 or pos('$',STD)>0:
    ^ВзятьПолныйПутьКаталога('STD_RPO');
  |  true:
     ss=trim(ВзятьПолныйПутьПапкиПлана);
     if ss<>'':
      if SubStr(ss,length(ss),1)<>'\':ss=ss+'\';fi;
      ^ss+STD;
     fi;
 fi;
 --------- поиск по путям к бланкам --------
 z=GetBlankNames('*', buf, True, False, False);
 if STD="":STD="\БЛАНКИ\";
  | true:STD=STD+if(SubStr(STD,Length(STD),1)='\','','\')+"БЛАНКИ\";
 fi;
 for t=1..z do
   ss=up(BlankFileName(buf[t]));
   if pos(STD,ss)>0:
      p=pos('\БЛАНКИ\',ss);
      ss=SubStr(ss,1,p);
      ^ss;
   fi;
 od;
^'';
end;
Proc append_nf(file:s;add_st:s);
 var нф1:i;
     Попытка
      нф1=TextFileOpenWrite(file);
      ТекстФайлВКонец(нф1);
      ТекстФайлЗаписатьСтроку(нф1,add_st);
     Окончание
      ТекстФайлЗакрыть(нф1);
     Конец;
end;

Func exec_cmd_hide_(cmd:s;wait:l):i; -- wait - лучше true, при повторном вызове не дождавшись отработки пред. команды могут быть глюки
 var ll:l;
 var x,нф1:i;
 var file_VBS:s;
  file_VBS=ВзятьCACHEПлана+'\exec_cmd_hide.VBS';
--  file_VBS=ВзятьCACHEПлана+'\'+getguid+'.VBS';
  ll=false;
  x=-1;
  CreateFile(file_VBS);
     Попытка
      нф1=ТекстФайлОткрытьНаЗапись(file_VBS);
      ТекстФайлВКонец(нф1);
      ТекстФайлЗаписатьСтроку(нф1,'Set WshShell = CreateObject("WScript.Shell")');
      ТекстФайлДописатьСтроку(нф1,'WshShell.Run "');
      ТекстФайлДописатьСтроку(нф1,cmd);
      ТекстФайлДописатьСтроку(нф1,'", 0, '+if(wait,'true','false'));
      ll=true;
     Окончание
      ТекстФайлЗакрыть(нф1);
     Конец;
  if ll:
     x=ВыполнитьПрограмму(file_VBS,wait);
     if x<>0:
       trace('Ошибка выполнения: '+cmd);
     fi;
  fi;
  if existfile(file_VBS):
     DeleteFile(file_VBS);
  fi;
  ^x;
end;

--var  AutoObj1:AutoObject;
--var  AutoObj2:AutoObject;
--var  AutoObj3:AutoObject;
--var  AutoObj4:AutoObject;
--var  AutoObj5:AutoObject;
--var  AutoObj6:AutoObject;
--var  AutoObj7:AutoObject;
--var  AutoObj8:AutoObject;
--var  AutoObj9:AutoObject;
--var  AutoObjStatus[]:i;


--Func Get_A_Obj(number:i):AutoObject;
-- if number=1:^AutoObj1;
--  | number=2:^AutoObj2;
--  | number=3:^AutoObj3;
--  | number=4:^AutoObj4;
--  | number=5:^AutoObj5;
--  | number=6:^AutoObj6;
--  | number=7:^AutoObj7;
--  | number=8:^AutoObj8;
--  | number=9:^AutoObj9;
-- fi;
--end;

--Func Get_number_A_Obj(AutoObj:AutoObject):i;
-- if AutoObj=AutoObj1:^1;
--  | AutoObj=AutoObj2:^2;
--  | AutoObj=AutoObj3:^3;
--  | AutoObj=AutoObj4:^4;
--  | AutoObj=AutoObj5:^5;
--  | AutoObj=AutoObj6:^6;
--  | AutoObj=AutoObj7:^7;
--  | AutoObj=AutoObj8:^8;
--  | AutoObj=AutoObj9:^9;
-- fi;
--end;

--var Cmd_list[]:s;
--var Cmd_list_status[]:i;
--Func exec_cmd_by_list(cmd:s;wait:l):i;
-- var x,z,j:i;
-- var Wsh:AutoObject;
--  z=LengthOfArray(Cmd_list)+1;
--  ClearVariable(Cmd_list_status);
--  Wsh=CreateAutoObject("WScript.Shell");
--  j=1;
--  try
--    while SumOfArray(Cmd_list_status,5)>0 or j<z do

--       for j=1..z do
--       x=AsInteger(Wsh.Exec(cmd,0,wait));
--    od;
--  finally
--    ClearVariable(Wsh);
--  end;
--  ^x;
--end;

Func exec_cmd_hide(cmd:s;wait:l):i;
 var x:i;
 var Wsh:AutoObject;
  Wsh=CreateAutoObject("WScript.Shell");
  try
    x=AsInteger(Wsh.Run(cmd,0,wait));
  finally
    ClearVariable(Wsh);
  end;
  ^x;
end;

--Dim WshShell, oExec
--Set WshShell = CreateObject("WScript.Shell")

--Set oExec = WshShell.Exec("calc")

--Do While oExec.Status = 0
--     WScript.Sleep 100
--Loop

--WScript.Echo oExec.Status








Func СоздатьФайлыСпискаБланков:s;-- возвращает количество файлов и путь к папке с файлами в формате число_файлов#путь_к_папке_с_файлами файлы с именами 1.txt 2.txt и т.д.
var ii,j,z,x:i;
var pt1,pt2,s1,s2,cmd,CACHEПлана:s;
  ClearVariable(Раб.План.CurPlan_FOLDER);
  ClearVariable(Раб.План.TempStrArray1);
  ClearVariable(Раб.План.TempStrArray2);
--    Раб.План.CurPlan_DirectFull_ready=false;
  if не Раб.План.CurPlan_DirectFull_ready:
    Раб.План.Load_CurPlan_DirectFull;
  fi;
  CACHEПлана=ВзятьCACHEПлана;
  z=Lengthofarray(Раб.План.CurPlan_Direct);
  ii=0;
  for j=1..z do
   if pos(Раб.План.CurPlan_Direct[j],'ПАПКИ_БЛАНКОВ БЛАНКИ')>0:
      ii=ii+1;
      AddInArray(Раб.План.CurPlan_FOLDER,true,false,j);
    pt2=CACHEПлана+'\'+str(ii)+'.txt';
    if Раб.План.CurPlan_Direct[j]='БЛАНКИ':
            cmd='XCOPY "'+Раб.План.CurPlan_DirectV_full[j]+'" "'+CACHEПлана+'" /l >"'+pt2+'"';
     | true:
            cmd='XCOPY "'+Раб.План.CurPlan_DirectV_full[j]+'\*.BLN" "'+CACHEПлана+'" /l >"'+pt2+'"';
    fi;
    TempStrArray1[ii]=cmd;
--    trace(cmd);
   fi;
  od;
--  Set WshShell = CreateObject("WScript.Shell")
--  WshShell.Run "cmd.exe /c D:\directory\your_batch.cmd", 0, false
  if ii>0:
     ii=ii+1;
     InsertInArray(Раб.План.TempStrArray1,1,'@echo off');
     ii=ii+1;
     TempStrArray1[ii]='EXIT';
     Выгрузить_СтрМассив_Вфайл(false,1,ii,CACHEПлана+'\Выгрузить_СтрМассив_Вфайл.bat',false,true);
     ClearVariable(Раб.План.TempStrArray1);
     ---------- попытка запуска через VBS ----------------
--     x=exec_cmd_hide('cmd /c '+CACHEПлана+'\Выгрузить_СтрМассив_Вфайл.bat',true);
     x=exec_cmd_hide('%COMSPEC% /c '+CACHEПлана+'\Выгрузить_СтрМассив_Вфайл.bat',true);

--     if x<>0:
--     ---------- попытка запуска через BAT ----------------
--       ClearVariable(Раб.План.TempStrArray1);
--       TempStrArray1[1]='start /min '+CACHEПлана+'\Выгрузить_СтрМассив_Вфайл.bat';
--       Выгрузить_СтрМассив_Вфайл(false,1,1,CACHEПлана+'\Выгрузить_СтрМассив_Вфайл_START.bat',false,true);
--       ClearVariable(Раб.План.TempStrArray1);
--       cmd='cmd /q /c "'+CACHEПлана+'\Выгрузить_СтрМассив_Вфайл_START.bat"';
--       x=ВыполнитьПрограмму(cmd,true);
--       DeleteFile(CACHEПлана+'\Выгрузить_СтрМассив_Вфайл_START.bat');
--     fi;
  fi;
  if existfile(CACHEПлана+'\Выгрузить_СтрМассив_Вфайл.bat'):
     DeleteFile(CACHEПлана+'\Выгрузить_СтрМассив_Вфайл.bat');
  fi;
^str(ii)+'#'+CACHEПлана;
end;

Func СоздатьПолныйСписокБланков(ТолькоГрупповые:l):i;-- возвращает количество бланков из всех файлов созданных функцией - СоздатьФайлыСпискаБланков
var s1,s2,s3,st,f:s;
var z,j,nf,k:i;
var ll:l;
  ClearVariable(Раб.План.ПолныйСписокБланков);
  s1=СоздатьФайлыСпискаБланков;
  s2=ВыделитьСлово(2,s1,'#');
  s1=ВыделитьСлово(1,s1,'#');
  z=int(s1);
  for j=1..z do
    f=s2+'\'+str(j)+'.txt';
    if existfile(f):
      nf=ТекстФайлОткрытьНаЧтение(f,true);
      try
       While не ТекстФайлКонецФайла(nf) do
         st = ТекстФайлПрочитатьСтроку(nf);
         s3=SubStr(st,1,3);
         if pos('\\',s3)=1 or pos(':\',s3)=2:
            k=КоличествоСлов(st,'\');
            s3=ВыделитьСлово(k,st,'\');
            ll=true;
            if ТолькоГрупповые:
               if pos('.',s3)<1:ll=false;
               fi;
            fi;
            if ll:
              s3=format('%s*%.3d*%s',s3,j,st);
              AddInArray(ПолныйСписокБланков,true,false,s3);
            fi;
         fi;
       od;
      finally
       ТекстФайлЗакрыть(nf);
      end;
      DeleteFile(f);
    fi;
  od;
  ^LengthOfArray(Раб.План.ПолныйСписокБланков);
end;

Func ОбновитьЛокальныеБланкиПапки_СетевымиПредками(Folder_loc:s;add:l;del_nul:l;refresh_plan:l):s;  -- возвращает надобность перезапуска бухгалтерии
-- Folder_loc - путь к локальной папке с бланками, 
-- add - режим добавления сетевых бланков не имеющих локальных потомков
-- del_nul - режим удаления бланков в Folder_loc не имеющих сетевых предков
-- обновляются (добавляются) только сетевые бланки описанные "выше" в плане бухгалтерии
var z,j,k,t,p:i;
var s1,s2,s3,ss,ПропускатьБланк:s;
var ll:l;
var file_VBS,rez:s;
    rez='';
      s1=GetPlanVar('LocalData');
      s2=ВзятьИмяПлана;
      if s1='':
         WriteLn(s2,'');
         WriteLn(s2,'КАТАЛОГИ LocalData=$WRK\'+SubStr(ВзятьИмяПлана,1,length(ВзятьИмяПлана)-4));
--         WriteLn(s2,'ПАПКИ_БЛАНКОВ $LocalData\BLN_LOCAL_CACHE -- кэшируемые бланки при нахождении STD_RPO в сети');
--       | true:
--         WriteLn(s2,'');
--         WriteLn(s2,'ПАПКИ_БЛАНКОВ $LocalData\BLN_LOCAL_CACHE -- кэшируемые бланки при нахождении STD_RPO в сети');
      ^'Был изменен план бухгалтерии,^Mтребуется перезапуск программы!';
      fi;
    file_VBS=ВзятьCACHEПлана+'\exec_cmd_hide.VBS';
    --Раб.План.CurPlan_DirectFull_ready=false;
    if refresh_plan:
       CurPlan_DirectFull_ready=false;
       ClearVariable(Раб.План.ПолныйСписокБланков);
    fi;
    if Folder_loc='':Folder_loc='$LocalData\BLN_LOCAL_CACHE';fi;
    z=LengthOfArray(Раб.План.ПолныйСписокБланков);
    if z<1:z=СоздатьПолныйСписокБланков(true);fi;
    k=LengthOfArray(Раб.План.CurPlan_FOLDER);
    p=0;
    for j=1..k do -- поиск номера папки Folder_loc
       t=k-j+1;
       if Folder_loc=CurPlan_DirectV_full[CurPlan_FOLDER[t]] or Folder_loc=CurPlan_DirectV[CurPlan_FOLDER[t]]:
          p=CurPlan_FOLDER[t];
          break;
       fi;
    od;
    if p<1:
      s1=GetPlanVar('LocalData');
      s2=ВзятьИмяПлана;
      if s1='':
         WriteLn(s2,'');
         WriteLn(s2,'КАТАЛОГИ LocalData=$WRK\'+SubStr(ВзятьИмяПлана,1,length(ВзятьИмяПлана)-4));
         WriteLn(s2,'ПАПКИ_БЛАНКОВ $LocalData\BLN_LOCAL_CACHE -- кэшируемые бланки при нахождении STD_RPO в сети');
       | true:
         WriteLn(s2,'');
         WriteLn(s2,'ПАПКИ_БЛАНКОВ $LocalData\BLN_LOCAL_CACHE -- кэшируемые бланки при нахождении STD_RPO в сети');
      fi;
--        append_nf(s2,'ПАПКИ_БЛАНКОВ $LocalData\BLN_LOCAL_CACHE -- кэшируемые бланки при нахождении STD_RPO в сети');
      ^'Был изменен план бухгалтерии,^Mтребуется перезапуск программы!';
    fi; -- нет папки Folder_loc - выходим
    ClearVariable(Раб.План.buf); -- сетевые предки для обновления
    ClearVariable(Раб.План.buf1);-- бланки в Folder_loc для удаления
    ClearVariable(Раб.План.buf2);-- сетевые бланки еще не закэшированные в Folder_loc

    -- создаем список бланков которые нужно скопировать в Folder_loc
    ПропускатьБланк='';
    for j=1..z do
       k=z-j+1;
       s1=ВыделитьСлово(1,ПолныйСписокБланков[k],'*');-- бланк
       s2=ВыделитьСлово(2,ПолныйСписокБланков[k],'*');-- номер
       s3=ВыделитьСлово(3,ПолныйСписокБланков[k],'*');-- полный путь и имя бланка
       s3=SubStr(s3,1,Length(s3)-3)+'???';
       if ПропускатьБланк<>s1:
          if int(s2)<=t:
             if int(s2)=t:-- бланк из Folder_loc
                ПропускатьБланк=s1; -- пропускаем предки текущего бланка (уже нашли первого предка, - остальные не нужны)
                if k=1:-- нет предков - надо удалить если del_nul=true
                   if del_nul:addinarray(buf1,true,false,s3);fi;
                 | k>1:-- проверяем на наличие сетевого предка
                   ss=ВыделитьСлово(1,ПолныйСписокБланков[k-1],'*');-- бланк
                   if ss<>s1:--нет предков - надо удалить если del_nul=true
                      if del_nul:addinarray(buf1,true,false,s3);fi;
                    | true:ss=ВыделитьСлово(3,ПолныйСписокБланков[k-1],'*');-- полный путь и имя бланка
                      ss=SubStr(ss,1,Length(ss)-3)+'???';
                      if '\\'<>substr(ss,1,2):-- нужны только сетевые бланки --нет предков - надо удалить если del_nul=true
                         if del_nul:addinarray(buf1,true,false,s3);fi;
                       | true:addinarray(buf,true,false,ss);-- запомнили сетевого предка
                      fi;
                   fi;
                fi;
              | true:-- бланка нет в Folder_loc
                if '\\'=substr(s3,1,2):-- нужны только сетевые бланки
                   if add:addinarray(buf2,true,false,s3);fi;-- запомнили бланк для добавления в Folder_loc
                fi;
                ПропускатьБланк=s1; -- пропускаем предки текущего бланка (уже нашли первого предка, - остальные не нужны)
             fi;
          fi;
       fi;
--       trace(Раб.План.ПолныйСписокБланков[j]);
    od;
    ClearVariable(Раб.План.TempStrArray1);
    ClearVariable(Раб.План.TempStrArray2);
--    s1='WshShell.Run " XCOPY ';
    s1='WshShell.Run "%COMSPEC% /c XCOPY ';
    ss=' '+CurPlan_DirectV_full[p];-- полный путь, куда копировать
    s3=ss+'/y", 0, true';
    TempStrArray1[1]='Set WshShell = CreateObject("WScript.Shell")';
    k=1;
    z=LengthOfArray(Раб.План.buf2);
    if z>0:rez='Закэшировано '+str(z)+'^M';fi;
    for j=1..z do --бланк для добавления в Folder_loc
      k=k+1;
      s2=buf2[j];TempStrArray1[k]=s1+s2;TempStrArray2[k]=s3;
    od;

    s1='WshShell.Run "%COMSPEC% /c DEL ';
    s3='/q", 0, true';
    z=LengthOfArray(Раб.План.buf1); --бланки в Folder_loc для удаления
    if z>0:rez='Удалено из кэша '+str(z)+'^M';fi;
    for j=1..z do
      k=k+1;
      s2=buf1[j];TempStrArray1[k]=s1+s2+s3;
    od;

    s1='WshShell.Run "%COMSPEC% /c XCOPY ';
    ss=' '+CurPlan_DirectV_full[CurPlan_FOLDER[p]];-- полный путь, куда копировать
    s3=ss+' /u", 0, true';

    z=LengthOfArray(Раб.План.buf);
    for j=1..z do --бланк для обновления в Folder_loc
      k=k+1;
      s2=buf[j];TempStrArray1[k]=s1+s2;TempStrArray2[k]=s3;
    od;
    Выгрузить_СтрМассив_Вфайл(true,1,k,file_VBS,false,false);
    if ВыполнитьПрограмму(file_VBS,true)<>0:
       trace('Ошибка выполнения: '+file_VBS);
    fi;
    if rez<>'':rez=rez+'требуется перезапуск программы!';fi;
    ^rez;
--     if existfile(file_VBS):
--        DeleteFile(file_VBS);
--     fi;
--    for j=1..k do --бланк для обновления в Folder_loc
--     trace(TempStrArray1[j]+TempStrArray2[j]);
--    od;

--     x=exec_cmd_hide('%COMSPEC% /c '+CACHEПлана+'\Выгрузить_СтрМассив_Вфайл.bat',true);
--            cmd='XCOPY "'+Раб.План.CurPlan_DirectV_full[j]+'\*.BLN" "'+CACHEПлана+'" /l >"'+pt2+'"';


end;
--1- путь к кэшу - желательно локальной папке бланков описанной в плане бухгалтерии
--2- ищем ее номер в  CurPlan_DirectV_full[CurPlan_FOLDER[номер]] если его нет - добавляем новую папку в конец плана бухгалтерии
--3- все номера бланков с меньшими номерами должны попасть в папку если они с тем же именем, т.е. цикл по именам вланков с конца с номерами меньшими номера папки кэша
Конец