//АЦК: Выгрузка КБК
//Постановка: Exchange #1569
uses
  'Un_Exch2629',      // exchange #2629
  'Un_Export',
  'Un_Default',
  'Un_GrantInvestmentList',
  'Un_Generator_NomTL',
  'QueryWork',
  'QueryKbk',
  'Un_SysParams',     // exchange #2412
  'QueryTools',
  'Un_MessageValidForm',
  'Un_VersionSupport',
  'Un_Schems',
  'Un_ToolsXml',
  'Un_Tools',
  'Un_ConstRef',
  'Un_Progress',
  'Un_System',
  'Un_Log',
  'Un_Debug';

const
  TestFileName = 'Exp_Fk_KBK.Xml';
var
  Form, Fm_ParamUnloadKbk: TFormCustom;//TForm;
  Fm_KbkList: TFormCustomList;
  PacketNumber, BudgIndx, i, idx, j: Integer;
  IniSection, DolIsp, FioIsp, TelIsp, BudgetId, param_VariantUnloadKBK,
  param_ModeSubDohIst, KbkIdList: String;
  UnloadKbk, UnloadGlava, UnloadKcsr, UnloadKvr, param_ref, UnloadSubDohIst,
  UnloadGrantInvestment, param_UnloadKbkFromAllBudget, EmptySysParam, param_NameKBK,
  param_ChangePrevYear, param_ShowFormParam, fm_ModalResultOk,
  param_OutListKbk: Boolean;
  Fo, Ufk, Kbk, BudgXml, OldKbk, SysParam, CurrHistory, NodeXmlList,
  CodeXmlList, MappBudgXml, Uchr: Variant;
  UnloadKbk_Chbx, UnloadKcsr_Chbx, UnloadKvr_Chbx, UnloadPodvid_Chbx,
  UnloadGlava_Chbx, UnloadGrantInvestment_Chbx: TCheckBox;
  OkBtn, CancelBtn: TBitBtn;
  CdsList: TClientDataSet;
  DbGrid: TDBGridEh;
  EdtCdsId, edKesCode, edKadmCode: TEdit;
  tlbFilterClear, tlbFilter: TToolButton;
  PanelFilter: TPanel;
  RadioTypeKbk: TRadioGroup;
  spbKesCode, spbKadmCode: TSpeedButton;
  vFilterGrandInvesment: string;
  
procedure Main(Xml: Variant);
begin
  InitializeProgressControl;
  xml := InitializeMain( xml, TestFileName);
  if VarIsNull( xml) then exit;
  if NOT CompareVersionAZK_Finance( 'Выгрузка КБК', '2.23.65.26')
    then EXIT;
  Initialize(Xml);
  try
    if (param_ShowFormParam) and (not fm_ModalResultOk) then
    begin
      ShowMessage('Выгрузка прервана.');
      WriteLog('Выгрузка прервана пользователем');
      Exit;
    end;
    try
      //сюда дописывать логические параметры по выгрузке кодов, если все параметры
      //не установлены, то досвидания.
      if (not UnloadKbk) and (not UnloadGlava) and (not UnloadKcsr) and
        (not UnloadKvr) and (not UnloadSubDohIst) and (not UnloadGrantInvestment) then
      begin
        ShowMessage('Ни одного параметра выгрузки кодов не установлено.');
        Exit;
      end;
      if (UnloadSubDohIst) and (AzkCompareVersion('2.25.0.33') < 0) then
        Raise('Выгрузка справочников кодов видов источников, кодов подвидов' +
          ' доходов доступна с версии АЦК-Финансы 2.25.0.33.' + #13#10 +
          'Установите параметр "Выгружать справочник коды видов источников,' +
          ' коды подвидов доходов" = Нет, или обновите систему');
{
      if (UnloadGrantInvestment) and (AzkCompareVersion('2.27.2.48') < 0) then
        Raise('Выгрузка справочника целевых субсидий доступна с версии АЦК-Финансы 2.27.2.48.' + #13#10 +
          'Установите параметр "Выгружать справочник целевых субсидий" = Нет, или обновите систему');
}

      // начало экспорта - инициализируем номер операции экспорта для
      // ведения нумерации учредителей
      InializeActionExportNomTL( DirIni);

      Form.Caption := 'Выгрузка справочников КБК';
      Form.Show;
      Form.Width := 500;
      WriteLog('Чтение системных параметров', True);
      SysParam := CreateOleObject('Microsoft.XmlDom');
      OldKbk := CreateOleObject('Microsoft.XmlDom');
      EmptySysParam := QueryField('Select Id From SysParam Where Name = ?',
        ['exchange.kbkcompare'], 'ID') = '';
      with SysParam.appendChild(SysParam.createElement('EXCH_UTILS_PROCESSOR')) do
      begin
        setAttribute('action', 'get_sys_param_value');
        if EmptySysParam then
          setAttribute('NAME', 'exchange.kbkcompare')
        else
        with appendChild(SysParam.createElement('SYSPARAM')) do
          setAttribute('NAME', 'exchange.kbkcompare');
        SysParam.loadXml(ExecXml(SysParam.xml));
        SysParam := SysParam.getElementsByTagName('PARAM_VALUE');
        if SysParam.length = 1 then
          OldKbk.loadXml(SysParam.items[0].firstChild.Data);
      end;
      if EmptySysParam then
      begin
        OldKbk := CreateOleObject('Microsoft.XmlDom');
        OldKbk.appendChild(OldKbk.createElement('EXCHQUERY'));
        OldKbk.documentElement.setAttribute('completed', 'true');
      end;
      OldKbk := OldKbk.documentElement;
      // продолжить
      WriteLog('Получение списка бюджетов', True);
      BudgXml := QueryXml(sqlBudget + ' Where FinYear = ?', [Budget_Year]);
      BudgXml := BudgXml.documentElement;
      //Exchange #2039
      if (not EmptySysParam) and (param_ChangePrevYear)
          and (param_VariantUnloadKBK = 'только измененные строки') then
      begin
        if param_UnloadKbkFromAllBudget then
          //проставляем соответтствие для всех бюджетов
          MappBudgXml := QueryXml(
            ' Select Ic.Budget_Id NewBudget_Id, Ic.Old_Budget_Id OldBudget_Id' +
            ' From IdChanges Ic' +
            ' Join Budget B on B.Id = Ic.Budget_Id' +
            ' Where Ic.TableName = ''BUDGET'' and B.FinYear = ?', [Budget_Year])
        else
          //соответствие только для прилогиненного бюджета
          MappBudgXml := QueryXml(
            ' Select Ic.Budget_Id NewBudget_Id, Ic.Old_Budget_Id OldBudget_Id' +
            ' From IdChanges Ic' +
            ' Where Ic.TableName = ''BUDGET'' and Ic.Budget_Id = ?', [Budget_Id]);
        MappBudgXml := MappBudgXml.documentElement;
        //удаляем ноды, в которые будут переименованы по соответсвию ноды бюджетов
        //прошлых лет.
        for i := 0 to MappBudgXml.ChildNodes.Length - 1 do
        begin
          idx := 0;
          while idx <= OldKbk.ChildNodes.Length - 1 do
            if ('B' + MappBudgXml.ChildNodes.Item[i].getAttribute('OLDBUDGET_ID') =
              OldKbk.ChildNodes.Item[idx].NodeName) then
            begin
              //удаляем возможно уже существующий Node с именем переименовывае-
              //мого Node
              RemoveNode(OldKbk.ChildNodes.Item[idx],
                'B' + MappBudgXml.ChildNodes.Item[i].getAttribute('NEWBUDGET_ID'));
              Break;
            end
            else
              Inc(idx);
        end;
        for i := 0 to MappBudgXml.ChildNodes.Length - 1 do
        begin
          idx := 0;
          while idx <= OldKbk.ChildNodes.Length - 1 do
            if ('B' + MappBudgXml.ChildNodes.Item[i].getAttribute('OLDBUDGET_ID') =
              OldKbk.ChildNodes.Item[idx].NodeName) then
            begin
              //переименовывем Node
              RenameNode(OldKbk.ChildNodes.Item[idx],
                'B' + MappBudgXml.ChildNodes.Item[i].getAttribute('NEWBUDGET_ID'));
              Break;
            end
            else
              Inc(idx);
        end;
      end;
      
      OldKbk := OldKbk.ownerDocument.documentElement;
      BudgIndx := 0;
      repeat
        if not param_UnloadKbkFromAllBudget then
          BudgetId := Budget_Id
        else
          BudgetId := BudgXml.childNodes.Item[BudgIndx].getAttribute('ID');

        //ищем нужный бюджет в значении из sysparam
        NodeXmlList := OldKbk.SelectNodes('B' + BudgetId);
        if (NodeXmlList.Length = 0) then
          OldKbk := OldKbk.appendChild(OldKbk.ownerDocument.createElement('B' + BudgetId))
        else
          OldKbk := NodeXmlList.Item[0];
        Data := CreateOleObject('Microsoft.XmlDom');
        Data.appendChild(Data.createElement('FORMAT'));
        WriteLog('Определение данных Финансового органа', True);
        Fo := GetOrgByBudget(BudgetId);
        if Fo.documentElement.childNodes.Length <> 1 then
          Fo := QueryXml(sqlOrgByBudget, [BudgetId]);
        Fo := Fo.documentElement.childNodes.Item[0];;
        WriteLog('Определение данных ТОФК', True);
        Ufk := GetTofkByBuh(BudgetId);
        if Ufk.documentElement.childNodes.Length = 0 then
          Raise('Не удалось получить реквизиты организации ТОФК. ' +
          'Проверьте заполение счета в АЦК "Бухгалтерия-Настройка счетов-Счета ФО-' +
          'Основной бюджетный счет".');
        Ufk := Ufk.documentElement.childNodes.Item[0];
        //обнуляем кэш
        CacheFormatKbk.Clear;
        //заполнение содержимого файла.
        if UnloadKbk then begin
          IniSection := 'КБК';
          if MakeFormatKBK then begin
            //валидация схем.
            if param_CtlValidOn then
              if not ValidateFormat then begin
                if Not ShowMessageValid( FileValidate) then begin
//                MessageValidText.Lines.LoadFromFile( FileValidate);
//                if ( Form_MessageValid.ShowModal = mrCancel) then
              {
                ShellExecute('NotePad', FileValidate, False);
                WriteLog('Не пройден контроль валидности отдельными документами');
                if MessageDlg('Не пройден контроль валидности.' + cr +
                  'Продолжить выгрузку?', mtConfirmation, mbYes + mbNo, 0) = mrNo then
                  }
                  //сохраняем измененые данные по другим КБК перед выходом
                  SaveDataInSysParam;
                  WriteLog('Выгрузка прервана пользователем');
                  Exit;
                end;
              end;
            //end if param_CtlValidOn then
            try
              FileOut := DirOut + FileOut;
              WriteLog('Сохранение в исходящем каталоге: ' + FileOut, True);
              XmlToTextFile(FileOut);
              //Запись номера посылки в течении дня
              with TIniFile.Create(DirIni + 'Schems\Send.dat') do
              begin
                WriteString( IniSection,
                             FormatDateTime('yyyymmdd', Now),
                             IntToStr(PacketNumber));
                // exchange #2406
                { сохраняем дату выполнения операции как дату выгрузки КБК
                  сохранение параметра в файле Send.Dat }
                WriteString( 'ВЫГРУЗКА_КБК',
                             'БЮДЖЕТ_' + BudgetId,
                              DateTimeToStr_YYYYMMDD_HHMMSS( NOW));
                UpdateFile;
                Free;
              end;
            except
              raise('Ошибка сохранения: ' + FileOut);
            end;
            //сохраняем данные по выгруженным КБК в Xml для sysparam
            NodeXmlList := OldKbk;
            OldKbk := OldKbk.parentNode;
            OldKbk.ReplaceChild(CurrHistory, NodeXmlList);
          end;
        end; //if UnloadKbk then
        if UnloadKcsr then
        begin
          IniSection := 'КЦСР';
          if MakeFormatKcsr then
          begin
            //валидация схем.
            if param_CtlValidOn then
              if not ValidateFormat then
              begin
                if Not ShowMessageValid( FileValidate) then
//                MessageValidText.Lines.LoadFromFile( FileValidate);
  //              if ( Form_MessageValid.ShowModal = mrCancel) then
              {
                ShellExecute('NotePad', FileValidate, False);
                WriteLog('Не пройден контроль валидности отдельными документами');
                if MessageDlg('Не пройден контроль валидности.' + cr +
                  'Продолжить выгрузку?', mtConfirmation, mbYes + mbNo, 0) = mrNo then
                  }
                begin
                  //сохраняем измененые данные по другим КБК перед выходом
                  SaveDataInSysParam;
                  WriteLog('Выгрузка прервана пользователем');
                  Exit;
                end;
              end;
            //end if param_CtlValidOn then
            try
              FileOut := DirOut + FileOut;
              WriteLog('Сохранение в исходящем каталоге: ' + FileOut, True);
              XmlToTextFile(FileOut);
              //Запись номера посылки в течении дня
              with TIniFile.Create(DirIni + 'Schems\Send.dat') do
              begin
                WriteString(IniSection, FormatDateTime('yyyymmdd', Now),
                IntToStr(PacketNumber));
                Free;
              end;
            except
              raise('Ошибка сохранения: ' + FileOut);
            end;
            //сохраняем данные по выгруженным КБК в Xml для sysparam
            NodeXmlList := OldKbk;
            OldKbk := OldKbk.parentNode;
            OldKbk.ReplaceChild(CurrHistory, NodeXmlList);
          end;
        end; //if UnloadKcsr then
        if UnloadKvr then
        begin
          IniSection := 'КВР';
          if MakeFormatKvr then
          begin
            //валидация схем.
            if param_CtlValidOn then
              if not ValidateFormat then
              begin
                if Not ShowMessageValid( FileValidate) then
//                MessageValidText.Lines.LoadFromFile( FileValidate);
  //              if ( Form_MessageValid.ShowModal = mrCancel) then
              {
                ShellExecute('NotePad', FileValidate, False);
                WriteLog('Не пройден контроль валидности отдельными документами');
                if MessageDlg('Не пройден контроль валидности.' + cr +
                  'Продолжить выгрузку?', mtConfirmation, mbYes + mbNo, 0) = mrNo then
                  }
                begin
                  //сохраняем измененые данные по другим КБК перед выходом
                  SaveDataInSysParam;
                  WriteLog('Выгрузка прервана пользователем');
                  Exit;
                end;
              end;
            //end if param_CtlValidOn then
            try
              FileOut := DirOut + FileOut;
              WriteLog('Сохранение в исходящем каталоге: ' + FileOut, True);
              XmlToTextFile(FileOut);
              //Запись номера посылки в течении дня
              with TIniFile.Create(DirIni + 'Schems\Send.dat') do
              begin
                WriteString(IniSection, FormatDateTime('yyyymmdd', Now),
                IntToStr(PacketNumber));
                Free;
              end;
            except
              raise('Ошибка сохранения: ' + FileOut);
            end;
            //сохраняем данные по выгруженным КБК в Xml для sysparam
            NodeXmlList := OldKbk;
            OldKbk := OldKbk.parentNode;
            OldKbk.ReplaceChild(CurrHistory, NodeXmlList);
          end;
        end; //if UnloadKvr then
        if UnloadGlava then
        begin
          IniSection := 'ГЛАВА';
          if MakeFormatGlava then
          begin
            //валидация схем.
            if param_CtlValidOn then
              if not ValidateFormat then
              begin
                if Not ShowMessageValid( FileValidate) then
//                MessageValidText.Lines.LoadFromFile( FileValidate);
  //              if ( Form_MessageValid.ShowModal = mrCancel) then
              {
                ShellExecute('NotePad', FileValidate, False);
                WriteLog('Не пройден контроль валидности отдельными документами');
                if MessageDlg('Не пройден контроль валидности.' + cr +
                  'Продолжить выгрузку?', mtConfirmation, mbYes + mbNo, 0) = mrNo then
                  }
                begin
                  //сохраняем измененые данные по другим КБК перед выходом
                  SaveDataInSysParam;
                  WriteLog('Выгрузка прервана пользователем');
                  Exit;
                end;
              end;
            //end if param_CtlValidOn then
            try
              FileOut := DirOut + FileOut;
              WriteLog('Сохранение в исходящем каталоге: ' + FileOut, True);
              XmlToTextFile(FileOut);
              //Запись номера посылки в течении дня
              with TIniFile.Create(DirIni + 'Schems\Send.dat') do
              begin
                WriteString(IniSection, FormatDateTime('yyyymmdd', Now),
                IntToStr(PacketNumber));
                Free;
              end;
            except
              raise('Ошибка сохранения: ' + FileOut);
            end;
            //сохраняем данные по выгруженным КБК в Xml для sysparam
            NodeXmlList := OldKbk;
            OldKbk := OldKbk.parentNode;
            OldKbk.ReplaceChild(CurrHistory, NodeXmlList);
          end;
        end; //if UnloadGlava then
        if UnloadSubDohIst then
        begin
          IniSection := 'ПОДВИДДОХИСТ';
          if MakeFormatSubDohIst then
          begin
            //валидация схем.
            if param_CtlValidOn then
              if not ValidateFormat then
              begin
                if Not ShowMessageValid( FileValidate) then
//                MessageValidText.Lines.LoadFromFile( FileValidate);
  //              if ( Form_MessageValid.ShowModal = mrCancel) then
{
                ShellExecute('NotePad', FileValidate, False);
                WriteLog('Не пройден контроль валидности отдельными документами');
                if MessageDlg('Не пройден контроль валидности.' + cr +
                  'Продолжить выгрузку?', mtConfirmation, mbYes + mbNo, 0) = mrNo then
}
                begin
                  //сохраняем измененые данные по другим КБК перед выходом
                  SaveDataInSysParam;
                  WriteLog('Выгрузка прервана пользователем');
                  Exit;
                end;
              end;
            //end if param_CtlValidOn then
            try
              FileOut := DirOut + FileOut;
              WriteLog('Сохранение в исходящем каталоге: ' + FileOut, True);
              XmlToTextFile(FileOut);
              //Запись номера посылки в течении дня
              with TIniFile.Create(DirIni + 'Schems\Send.dat') do
              begin
                WriteString(IniSection, FormatDateTime('yyyymmdd', Now),
                IntToStr(PacketNumber));
                Free;
              end;
            except
              raise('Ошибка сохранения: ' + FileOut);
            end;
            //сохраняем данные по выгруженным КБК в Xml для sysparam
            NodeXmlList := OldKbk;
            OldKbk := OldKbk.parentNode;
            OldKbk.ReplaceChild(CurrHistory, NodeXmlList);
          end;
        end; //if UnloadSubDohIst then
        if UnloadGrantInvestment then
        begin
          // Exchange #2334
          // выбираем список субсидий и инвестиций из справочника.
          // в результате формируется список ID через запятую
          vFilterGrandInvesment := ChoiceGrantInvestmentListEx( DirIni, BudgetId);
          if (vFilterGrandInvesment = '') then begin
            ShowMessage( 'Отменено пользователем.');
            Exit;
          end;
    //      ShowMessage( 'Filter = "' + vFilterGrandInvesment + '"');
    //      exit;

          IniSection := 'СУБСИДИЯ';
          // разбиение по учредителям
          Uchr := GetUchrGrantInvestment(BudgetId, vFilterGrandInvesment);
          Uchr := Uchr.documentElement;
          //создаем xml c текущей историей из базы
          CurrHistory := CreateOleObject('Microsoft.XmlDom');
          CurrHistory := CurrHistory.appendChild(CurrHistory.createElement('HISTORY'));
          CurrHistory := CurrHistory.appendChild(CurrHistory.ownerDocument.createElement('GRANTINV'));
          //ищем node GRANTINV
          NodeXmlList := OldKbk.selectNodes('GRANTINV');
          if NodeXmlList.Length = 0 then
            OldKbk := OldKbk.appendChild(OldKbk.ownerDocument.createElement('GRANTINV'))
          else
            OldKbk := NodeXmlList.Item[0];
          for j := 0 to Uchr.ChildNodes.Length - 1 do
          begin
            Uchr := Uchr.ChildNodes.item[j];
            case MakeFormatGrantInvestment of
             -1: exit;
              1: begin
              //валидация схем.
              if param_CtlValidOn then
                if not ValidateFormat then
                begin
                if Not ShowMessageValid( FileValidate) then
//                MessageValidText.Lines.LoadFromFile( FileValidate);
  //              if ( Form_MessageValid.ShowModal = mrCancel) then
{
                  ShellExecute('NotePad', FileValidate, False);
                  WriteLog('Не пройден контроль валидности отдельными документами');
                  if MessageDlg('Не пройден контроль валидности.' + cr +
                    'Продолжить выгрузку?', mtConfirmation, mbYes + mbNo, 0) = mrNo then
}
                  begin
                    //сохраняем измененые данные по другим КБК перед выходом
                    SaveDataInSysParam;
                    WriteLog('Выгрузка прервана пользователем');
                    Exit;
                  end;
                end;
              //end if param_CtlValidOn then
              try
                FileOut := DirOut + FileOut;
                WriteLog('Сохранение в исходящем каталоге: ' + FileOut, True);
                XmlToTextFile(FileOut);
                //Запись номера посылки в течении дня
                with TIniFile.Create(DirIni + 'Schems\Send.dat') do
                begin
                  WriteString(IniSection, FormatDateTime('yyyymmdd', Now),
                  IntToStr(PacketNumber));
                  Free;
                end;
              except
                raise('Ошибка сохранения: ' + FileOut);
              end;
              //сохраняем данные по выгруженным КБК в Xml для sysparam
              NodeXmlList := OldKbk;
              OldKbk := OldKbk.parentNode;
              OldKbk.ReplaceChild(CurrHistory, NodeXmlList);
              CurrHistory := CurrHistory.parentNode;
            end;
            else begin
              NodeXmlList := OldKbk;
              OldKbk := OldKbk.parentNode;
              OldKbk.ReplaceChild(CurrHistory, NodeXmlList);
            end;
            end;//case//
            Uchr := Uchr.parentNode;
          end;
        end; //if UnloadGrantInvestment then
        Inc(BudgIndx);
        OldKbk := OldKbk.ownerdocument.documentElement;
      until (BudgIndx > BudgXml.childNodes.Length - 1) or (not param_UnloadKbkFromAllBudget);
      //сохраняем данные выгруженных КБК
      SaveDataInSysParam;
    finally
      Finalize(Xml);
    end;
    except
      ExceptionHandler;
  end;
end;

function MakeFormatKBK: Boolean;
var
  i: Integer;
  CodeList: TStringList; //содержит список выгруженных кодов
  XmlListCodeforCds: Variant; //содержит перечень кодов для выбора из списка.
begin
  Result := False;
  Form.Caption := 'Выгрузка справочников по кодам бюджетной классификации';
  // Чтение номера посылки.
  with TIniFile.Create(DirIni + 'Schems\Send.dat') do
  begin
    PacketNumber := StrToInt(ReadString(IniSection,
      FormatDateTime('yyyymmdd', Now), '0')) + 1;
    Free;
  end;

  //Загрузка схемы
//  LoadSchema(DirIni + 'Schems\dk_txdk090925.xml');
  LoadSchema( GetFileNameSchemaTFF( 'dk_txdk*'));

  WriteLog('Формирование имени выгружаемого файла', True);
  FileOut := GetFileName(Fo.getAttribute('NAME'), 'DK', Now, PacketNumber,
    FileOutIsLocalNet, FileOutOrgCodeIsFk);
  Data := Data.documentElement;
  //создаем xml c текущей историей из базы
  CurrHistory := CreateOleObject('Microsoft.XmlDom');
  CurrHistory := CurrHistory.appendChild(CurrHistory.createElement('HISTORY'));
  CurrHistory := CurrHistory.appendChild(CurrHistory.ownerDocument.createElement('KBK'));
  //ищем node KBK
  NodeXmlList := OldKbk.selectNodes('KBK');
  if NodeXmlList.Length = 0 then
    OldKbk := OldKbk.appendChild(OldKbk.ownerDocument.createElement('KBK'))
  else
    OldKbk := NodeXmlList.Item[0];
  WriteLog('Заполнение данных файла: ' + FileOut, True);
  Data := Data.appendChild(FillElementBySchema(Fo, 'FK'));
  Data.setAttribute('FORM_VER', AppVersion);
  Data := Data.parentNode;
  Data := Data.appendChild(FillElementBySchema(Fo, 'FROM'));
  Data.setAttribute('BUDG_LEVEL', GetBudgLevel(BudgetId));
  Data := Data.parentNode;
  Data.appendChild(FillElementBySchema(Ufk, 'TO'));
  Data := Data.appendChild(FillElementBySchema(Fo, 'DK'));
  Data.setAttribute('NAME_BUD', QueryField(sqlBudgId, [BudgetId], 'CAPTION'));
  Data.setAttribute('DATE_FORM', FormatDateTime('dd.mm.yyyy', Now));
  Data.setAttribute('DOL_ISP', DolIsp);
  Data.setAttribute('NAME_ISP', FioIsp);
  Data.setAttribute('TEL_ISP', TelIsp);
  Data := Data.parentNode;
  CodeXmlList := null;
  XmlListCodeforCds := CreateOleObject('Microsoft.XmlDom');
  XmlListCodeforCds.appendChild(XmlListCodeforCds.createElement('EXCHQUERY'));
  XmlListCodeforCds := XmlListCodeforCds.documentElement;
  //DKST
  CodeList := TStringList.Create;
  try
    CodeList.Clear;
    WriteLog('Получение данных по расходам...', True);
    Kbk := Bk_Ras(BudgetId, StatusBar, ProgressBar);
    Kbk := Kbk.documentElement;
    ProgressBar.Max := Kbk.ChildNodes.Length;
    WriteLog('Формирование данных по расходам к выгрузке...', True);
    for i := 0 to Kbk.ChildNodes.Length - 1 do
    begin
      ProgressBar.Position := i + 1;
      Kbk := Kbk.ChildNodes.Item[i];
      //код не выгружался или не проверялся
      if CodeList.IndexOf(Kbk.getAttribute('CODE')) = -1 then
      begin
        if not VarIsNull(CodeXmlList) then
        begin
          KbkLineRash(CodeXmlList, XmlListCodeforCds, param_OutListKbk);
          CodeXmlList := null;
        end;
        //коды отсортированы при выборке. Создаем Xml для одного кода со всей историей
        CodeXmlList := CreateOleObject('Microsoft.XmlDom');
        CodeXmlList := CodeXmlList.appendChild(CodeXmlList.createElement('ROOT'));
        CodeXmlList.appendChild(Kbk.cloneNode(False));
        CodeList.Add(Kbk.getAttribute('CODE'));
      end
      else
        CodeXmlList.appendChild(Kbk.cloneNode(False));
      Kbk := Kbk.parentNode;
    end;
    //выгрузка последнего кода
    if not VarIsNull(CodeXmlList) then
      KbkLineRash(CodeXmlList, XmlListCodeforCds, param_OutListKbk);
    CodeList.Clear;
    CodeXmlList := null;
    ProgressBar.Position := 0;
    WriteLog('Получение данных по доходам...', True);
    Kbk := Bk_Doh(BudgetId, StatusBar, ProgressBar);
    Kbk := Kbk.documentElement;
    ProgressBar.Max := Kbk.ChildNodes.Length;
    WriteLog('Формирование данных по доходам к выгрузке...', True);
    for i := 0 to Kbk.ChildNodes.Length - 1 do
    begin
      ProgressBar.Position := i + 1 ;
      Kbk := Kbk.ChildNodes.Item[i];
      //код не выгружался или не проверялся
      if CodeList.IndexOf(Kbk.getAttribute('CODE')) = -1 then
      begin
        if not VarIsNull(CodeXmlList) then
        begin
          KbkLineDoh(CodeXmlList, XmlListCodeforCds, param_OutListKbk);
          CodeXmlList := null;
        end;
        //коды отсортированы при выборке. Создаем Xml для одного кода со всей историей
        CodeXmlList := CreateOleObject('Microsoft.XmlDom');
        CodeXmlList := CodeXmlList.appendChild(CodeXmlList.createElement('ROOT'));
        CodeXmlList.appendChild(Kbk.cloneNode(False));
        CodeList.Add(Kbk.getAttribute('CODE'));
      end
      else
        CodeXmlList.appendChild(Kbk.cloneNode(False));
      Kbk := Kbk.parentNode;
    end;
    //выгрузка последнего кода
    if not VarIsNull(CodeXmlList) then
      KbkLineDoh(CodeXmlList, XmlListCodeforCds, param_OutListKbk);
    CodeList.Clear;
    CodeXmlList := null;
    ProgressBar.Position := 0;
    WriteLog('Получение данных по источникам...', True);
    Kbk := Bk_Ist(BudgetId, StatusBar, ProgressBar);
    Kbk := Kbk.documentElement;
    ProgressBar.Max := Kbk.ChildNodes.Length;
    WriteLog('Формирование данных по источникам к выгрузке...', True);
    for i := 0 to Kbk.ChildNodes.Length - 1 do
    begin
      ProgressBar.Position := i + 1 ;
      Kbk := Kbk.ChildNodes.Item[i];
      //код не выгружался или не проверялся
      if CodeList.IndexOf(Kbk.getAttribute('CODE')) = -1 then
      begin
        if not VarIsNull(CodeXmlList) then
        begin
          KbkLineIst(CodeXmlList, XmlListCodeforCds, param_OutListKbk);
          CodeXmlList := null;
        end;
        //коды отсортированы при выборке. Создаем Xml для одного кода со всей историей
        CodeXmlList := CreateOleObject('Microsoft.XmlDom');
        CodeXmlList := CodeXmlList.appendChild(CodeXmlList.createElement('ROOT'));
        CodeXmlList.appendChild(Kbk.cloneNode(False));
        CodeList.Add(Kbk.getAttribute('CODE'));
      end
      else
        CodeXmlList.appendChild(Kbk.cloneNode(False));
      Kbk := Kbk.parentNode;
    end;
    //выгрузка последнего кода
    if not VarIsNull(CodeXmlList) then
      KbkLineIst(CodeXmlList, XmlListCodeforCds, param_OutListKbk);
  finally
    CodeList.Free;
  end;
  if param_OutListKbk then
  begin
    InsertDataToCds(CdsList, DBGrid, XmlListCodeforCds.ownerDocument, True);
    Fm_KbkList.Caption := 'Список выгружаемых кодов бюджетной классификации...';
    tlbFilterClear.Visible := True;
    tlbFilter.Visible := True;
    if Fm_KbkList.ShowModal = MrOk then
    begin
      Kbk := GetSelectedKbk(CdsList, KbkIdList);
      if not VarIsNull(Kbk) then
      begin
        Kbk := Kbk.documentElement;
        ProgressBar.Max := Kbk.ChildNodes.Length;
        WriteLog('Формирование данных по КБК к выгрузке...', True);
        for i := 0 to Kbk.ChildNodes.Length - 1 do
        begin
          ProgressBar.Position := i + 1 ;
          Kbk := Kbk.ChildNodes.Item[i];
          Data := Data.appendChild(FillElementBySchema(Kbk, 'DKST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'DK',
                                            Kbk.getAttribute('DESCRIPTION')));

          Data.setAttribute('DATE_BEGIN', IfThen(Kbk.getAttribute('BEGIN_DATE') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Kbk.getAttribute('BEGIN_DATE'))), ''));
          Data.setAttribute('DATE_END', IfThen(Kbk.getAttribute('END_DATE') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Kbk.getAttribute('END_DATE'))), ''));
          Data.setAttribute('DATE_CHANGE', IfThen(Kbk.getAttribute('CHANGE_DATE') <> '',
            FormatDateTime('dd.mm.yyyy hh:nn:ss',
              XmlToDateTime(Kbk.getAttribute('CHANGE_DATE'))), ''));
          Data.setAttribute('TYPE_KBK', Kbk.getAttribute('TYPE_KBK'));
          Data.setAttribute('LIMIT', Kbk.getAttribute('LIMIT'));
          Data := Data.parentNode;
          Kbk := Kbk.parentNode;
        end;
      end;
    end;
    CdsList.Filter := '';
    tlbFilterClear.Visible := False;
    tlbFilter.Visible := False;
    PanelFilter.Visible := False;
  end;
  Result := Data.SelectNodes('DKST').length > 0;
  if not Result then
    OldKbk := OldKbk.parentNode;
  Data := Data.ownerDocument;
end;

function MakeFormatKcsr: Boolean;
var
  i: Integer;
begin
  Result := False;
  Data := CreateOleObject('Microsoft.XmlDom');
  Data.appendChild(Data.createElement('FORMAT'));
  // Чтение номера посылки.
  with TIniFile.Create(DirIni + 'Schems\Send.dat') do
  begin
    PacketNumber := StrToInt(ReadString(IniSection,
      FormatDateTime('yyyymmdd', Now), '0')) + 1;
    Free;
  end;

  //Загрузка схемы
//  LoadSchema(DirIni + 'Schems\fc_txfc090925.xml');
  LoadSchema( GetFileNameSchemaTFF( 'fc_txfc*'));

  WriteLog('Формирование имени выгружаемого файла', True);
  FileOut := GetFileName(Fo.getAttribute('NAME'), 'FC', Now, PacketNumber,
    FileOutIsLocalNet, FileOutOrgCodeIsFk);
  Data := Data.documentElement;
  //создаем xml c текущей историей из базы
  CurrHistory := CreateOleObject('Microsoft.XmlDom');
  CurrHistory := CurrHistory.appendChild(CurrHistory.createElement('HISTORY'));
  CurrHistory := CurrHistory.appendChild(CurrHistory.ownerDocument.createElement('KCSR'));
  //ищем node KCSR
  NodeXmlList := OldKbk.selectNodes('KCSR');
  if NodeXmlList.Length = 0 then
    OldKbk := OldKbk.appendChild(OldKbk.ownerDocument.createElement('KCSR'))
  else
    OldKbk := NodeXmlList.Item[0];
  WriteLog('Заполнение данных файла: ' + FileOut, True);
  Data := Data.appendChild(FillElementBySchema(Fo, 'FK'));
  Data.setAttribute('FORM_VER', AppVersion);
  Data := Data.parentNode;
  Data := Data.appendChild(FillElementBySchema(Fo, 'FROM'));
  Data.setAttribute('BUDG_LEVEL', GetBudgLevel(BudgetId));
  Data := Data.parentNode;
  Data.appendChild(FillElementBySchema(Ufk, 'TO'));
  Data := Data.appendChild(FillElementBySchema(Fo, 'FC'));
  Data.setAttribute('NAME_BUD', QueryField(sqlBudgId, [BudgetId], 'CAPTION'));
  Data.setAttribute('DATE_FORM', FormatDateTime('dd.mm.yyyy', Now));
  Data.setAttribute('DOL_ISP', DolIsp);
  Data.setAttribute('NAME_ISP', FioIsp);
  Data.setAttribute('TEL_ISP', TelIsp);
  Data := Data.parentNode;
  WriteLog('Получение данных по КЦСР...', True);
  Kbk := Bk_Kcsr(BudgetId, StatusBar, ProgressBar, param_ref);
  if param_OutListKbk then
  begin
    InsertDataToCds(CdsList, DBGrid, Kbk);
    Fm_KbkList.Caption := 'Список выгружаемых КЦСР...';
    if Fm_KbkList.ShowModal = MrOk then
    begin
      Kbk := GetSelectedKbk(CdsList, KbkIdList);
      if not VarIsNull(Kbk) then
      begin
        Kbk := Kbk.documentElement;
        ProgressBar.Max := Kbk.ChildNodes.Length;
        WriteLog('Формирование данных по КЦСР к выгрузке...', True);
        for i := 0 to Kbk.ChildNodes.Length - 1 do
        begin
          ProgressBar.Position := i + 1 ;
          Kbk := Kbk.ChildNodes.Item[i];
          Data := Data.appendChild(FillElementBySchema(Kbk, 'FCST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'FC',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'FC',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

          Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
          Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
          Data.setAttribute('DATE_CHANGE', IfThen(Data.getAttribute('DATE_CHANGE') <> '',
            FormatDateTime('dd.mm.yyyy hh:nn:ss',
              XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
          Data := Data.parentNode;
          Kbk := Kbk.parentNode;
        end;
      end;
    end;
  end
  else begin
    Kbk := Kbk.documentElement;
    ProgressBar.Max := Kbk.ChildNodes.Length;
    WriteLog('Формирование данных по КЦСР к выгрузке...', True);
    for i := 0 to Kbk.ChildNodes.Length - 1 do
    begin
      ProgressBar.Position := i + 1 ;
      Kbk := Kbk.ChildNodes.Item[i];
      if param_VariantUnloadKBK = 'только измененные строки' then
      begin
        //ищем выбранный код в sysparam
        NodeXmlList := OldKbk.SelectNodes('//ROW[@CODE=''' + Kbk.getAttribute('CODE') +
          ''' and @CNAME =''' + Trim(Kbk.getAttribute('CAPTION')) + ''' and @NAME=''' +
          Trim(Kbk.getAttribute('DESCRIPTION')) + ''' and @DATE_BEGIN=''' +
          Kbk.getAttribute('BEGIN_DATE') + ''' and @DATE_END=''' +
          Kbk.getAttribute('END_DATE') + ''']');
        if NodeXmlList.length = 0 then
        begin
          Data := Data.appendChild(FillElementBySchema(Kbk, 'FCST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'FC',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'FC',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

          Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
          Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
          Data.setAttribute('DATE_CHANGE', IfThen(Data.getAttribute('DATE_CHANGE') <> '',
            FormatDateTime('dd.mm.yyyy hh:nn:ss',
              XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
          Data := Data.parentNode;
        end;
      end
      else if param_VariantUnloadKBK = 'все строки' then
      begin
        Data := Data.appendChild(FillElementBySchema(Kbk, 'FCST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'FC',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'FC',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

        Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
          FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
        Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
          FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
        Data.setAttribute('DATE_CHANGE', IfThen(Data.getAttribute('DATE_CHANGE') <> '',
          FormatDateTime('dd.mm.yyyy hh:nn:ss',
            XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
        Data := Data.parentNode;
      end
      //все последние строки
      else begin
        //дата окончания д.б. больше рабочей или не установлена
        if Kbk.getAttribute('END_DATE') = '' then
        begin
          //выгржаем всегда, т.к. нет даты окончания действия кода.
          Data := Data.appendChild(FillElementBySchema(Kbk, 'FCST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'FC',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'FC',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

          Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
          Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
          Data.setAttribute('DATE_CHANGE', IfThen(Data.getAttribute('DATE_CHANGE') <> '',
            FormatDateTime('dd.mm.yyyy hh:nn:ss',
              XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
          Data := Data.parentNode;
        end
        else begin
          if (XmlToDateTime(Kbk.getAttribute('END_DATE')) >= Work_Date) then
          begin
            //ищем выгружаемый код, среди выгруженных кодов
            NodeXmlList := Data.selectNodes('//FCST[@STATIA= ' +
              Kbk.getAttribute('CODE') + ']');
            if NodeXmlList.length = 0 then
            begin
              //код в этой сессии не выгружался
              Data := Data.appendChild(FillElementBySchema(Kbk, 'FCST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'FC',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'FC',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

              Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
                FormatDateTime('dd.mm.yyyy',
                  XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
              Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
                FormatDateTime('dd.mm.yyyy',
                  XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
              Data.setAttribute('DATE_CHANGE',
                IfThen(Data.getAttribute('DATE_CHANGE') <> '',
                  FormatDateTime('dd.mm.yyyy hh:nn:ss',
                    XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
              Data := Data.parentNode;
            end
            else begin
              //нод будет всегда один
              NodeXmlList := NodeXmlList.Item[0];
              //код присутвует в xml для выгрузки, проверяем дату начала действия
              if (StrToDate(NodeXmlList.getAttribute('DATE_BEGIN')) <
                XmlToDateTime(Kbk.getAttribute('BEGIN_DATE')))
                and (NodeXmlList.getAttribute('DATE_END') <> '') then
              begin
                Data.RemoveChild(NodeXmlList);
                Data := Data.appendChild(FillElementBySchema(Kbk, 'FCST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'FC',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'FC',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

                Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
                  FormatDateTime('dd.mm.yyyy',
                    XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
                Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
                  FormatDateTime('dd.mm.yyyy',
                    XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
                Data.setAttribute('DATE_CHANGE',
                  IfThen(Data.getAttribute('DATE_CHANGE') <> '',
                    FormatDateTime('dd.mm.yyyy hh:nn:ss',
                      XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
                Data := Data.parentNode;
              end;
            end;
          end;
        end;
      end;
      CurrHistory := CurrHistory.appendChild(CurrHistory.ownerDocument.createElement('ROW'));
      CurrHistory.setAttribute('CODE', Kbk.getAttribute('CODE'));
      CurrHistory.setAttribute('CNAME', Trim(Kbk.getAttribute('CAPTION')));
      CurrHistory.setAttribute('NAME', Trim(Kbk.getAttribute('DESCRIPTION')));
      CurrHistory.setAttribute('DATE_BEGIN', Kbk.getAttribute('BEGIN_DATE'));
      CurrHistory.setAttribute('DATE_END', Kbk.getAttribute('END_DATE'));
      CurrHistory := CurrHistory.parentNode;
      Kbk := Kbk.parentNode;
    end;
  end;
  Result := Data.SelectNodes('FCST').length > 0;
  if not Result then
    OldKbk := OldKbk.parentNode;
  Data := Data.ownerDocument;
end;

function MakeFormatKvr: Boolean;
var
  i: Integer;
begin
  Result := False;
  Data := CreateOleObject('Microsoft.XmlDom');
  Data.appendChild(Data.createElement('FORMAT'));
  // Чтение номера посылки.
  with TIniFile.Create(DirIni + 'Schems\Send.dat') do
  begin
    PacketNumber := StrToInt(ReadString(IniSection,
      FormatDateTime('yyyymmdd', Now), '0')) + 1;
    Free;
  end;

  //Загрузка схемы
//  LoadSchema(DirIni + 'Schems\fn_txfn090925.xml');
  LoadSchema( GetFileNameSchemaTFF( 'fn_txfn*'));

  WriteLog('Формирование имени выгружаемого файла', True);
  FileOut := GetFileName(Fo.getAttribute('NAME'), 'FN', Now, PacketNumber,
    FileOutIsLocalNet, FileOutOrgCodeIsFk);
  Data := Data.documentElement;
  //создаем xml c текущей историей из базы
  CurrHistory := CreateOleObject('Microsoft.XmlDom');
  CurrHistory := CurrHistory.appendChild(CurrHistory.createElement('HISTORY'));
  CurrHistory := CurrHistory.appendChild(CurrHistory.ownerDocument.createElement('KVR'));
  //ищем node KVR
  NodeXmlList := OldKbk.selectNodes('KVR');
  if NodeXmlList.Length = 0 then
    OldKbk := OldKbk.appendChild(OldKbk.ownerDocument.createElement('KVR'))
  else
    OldKbk := NodeXmlList.Item[0];
  WriteLog('Заполнение данных файла: ' + FileOut, True);
  Data := Data.appendChild(FillElementBySchema(Fo, 'FK'));
  Data.setAttribute('FORM_VER', AppVersion);
  Data := Data.parentNode;
  Data := Data.appendChild(FillElementBySchema(Fo, 'FROM'));
  Data.setAttribute('BUDG_LEVEL', GetBudgLevel(BudgetId));
  Data := Data.parentNode;
  Data.appendChild(FillElementBySchema(Ufk, 'TO'));
  Data := Data.appendChild(FillElementBySchema(Fo, 'FN'));
  Data.setAttribute('NAME_BUD', QueryField(sqlBudgId, [BudgetId], 'CAPTION'));
  Data.setAttribute('DATE_FORM', FormatDateTime('dd.mm.yyyy', Now));
  Data.setAttribute('DOL_ISP', DolIsp);
  Data.setAttribute('NAME_ISP', FioIsp);
  Data.setAttribute('TEL_ISP', TelIsp);
  Data := Data.parentNode;
  WriteLog('Получение данных по КВР...', True);
  Kbk := Bk_Kvr(BudgetId, StatusBar, ProgressBar, param_ref);
  if param_OutListKbk then
  begin
    InsertDataToCds(CdsList, DBGrid, Kbk);
    Fm_KbkList.Caption := 'Список выгружаемых КВР...';
    if Fm_KbkList.ShowModal = MrOk then
    begin
      Kbk := GetSelectedKbk(CdsList, KbkIdList);
      if not VarIsNull(Kbk) then
      begin
        Kbk := Kbk.documentElement;
        ProgressBar.Max := Kbk.ChildNodes.Length;
        WriteLog('Формирование данных по КВР к выгрузке...', True);
        for i := 0 to Kbk.ChildNodes.Length - 1 do
        begin
          ProgressBar.Position := i + 1 ;
          Kbk := Kbk.ChildNodes.Item[i];
          Data := Data.appendChild(FillElementBySchema(Kbk, 'FNST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'FN',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'FN',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

          Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
          Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
          Data.setAttribute('DATE_CHANGE', IfThen(Data.getAttribute('DATE_CHANGE') <> '',
            FormatDateTime('dd.mm.yyyy hh:nn:ss',
              XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
          Data := Data.parentNode;
          Kbk := Kbk.parentNode;
        end;
      end;
    end;
  end
  else begin
    Kbk := Kbk.documentElement;
    ProgressBar.Max := Kbk.ChildNodes.Length;
    WriteLog('Формирование данных по КВР к выгрузке...', True);
    for i := 0 to Kbk.ChildNodes.Length - 1 do
    begin
      ProgressBar.Position := i + 1 ;
      Kbk := Kbk.ChildNodes.Item[i];
      if param_VariantUnloadKBK = 'только измененные строки' then
      begin
        //ищем выбранный код в sysparam
        NodeXmlList := OldKbk.SelectNodes('//ROW[@CODE=''' + Kbk.getAttribute('CODE') +
          ''' and @CNAME =''' + Trim(Kbk.getAttribute('CAPTION')) + ''' and @NAME=''' +
          Trim(Kbk.getAttribute('DESCRIPTION')) + ''' and @DATE_BEGIN=''' +
          Kbk.getAttribute('BEGIN_DATE') + ''' and @DATE_END=''' +
          Kbk.getAttribute('END_DATE') + ''']');
        if NodeXmlList.length = 0 then
        begin
          Data := Data.appendChild(FillElementBySchema(Kbk, 'FNST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'FN',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'FN',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

          Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
          Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
          Data.setAttribute('DATE_CHANGE', IfThen(Data.getAttribute('DATE_CHANGE') <> '',
            FormatDateTime('dd.mm.yyyy hh:nn:ss',
              XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
          Data := Data.parentNode;
        end;
      end
      else if param_VariantUnloadKBK = 'все строки' then
      begin
        Data := Data.appendChild(FillElementBySchema(Kbk, 'FNST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'FN',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'FN',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

        Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
          FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
        Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
          FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
        Data.setAttribute('DATE_CHANGE', IfThen(Data.getAttribute('DATE_CHANGE') <> '',
          FormatDateTime('dd.mm.yyyy hh:nn:ss',
            XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
        Data := Data.parentNode;
      end
      //все последние строки
      else begin
        //дата окончания д.б. больше рабочей или не установлена
        if Kbk.getAttribute('END_DATE') = '' then
        begin
          //выгржаем всегда, т.к. нет даты окончания действия кода.
          Data := Data.appendChild(FillElementBySchema(Kbk, 'FNST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'FN',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'FN',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

          Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
          Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
          Data.setAttribute('DATE_CHANGE', IfThen(Data.getAttribute('DATE_CHANGE') <> '',
            FormatDateTime('dd.mm.yyyy hh:nn:ss',
              XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
          Data := Data.parentNode;
        end
        else begin
          if (XmlToDateTime(Kbk.getAttribute('END_DATE')) >= Work_Date) then
          begin
            //ищем выгружаемый код, среди выгруженных кодов
            NodeXmlList := Data.selectNodes('//FNST[@VID= ' +
              Kbk.getAttribute('CODE') + ']');
            if NodeXmlList.length = 0 then
            begin
              //код в этой сессии не выгружался
              Data := Data.appendChild(FillElementBySchema(Kbk, 'FNST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'FN',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'FN',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

              Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
                FormatDateTime('dd.mm.yyyy',
                  XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
              Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
                FormatDateTime('dd.mm.yyyy',
                  XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
              Data.setAttribute('DATE_CHANGE',
                IfThen(Data.getAttribute('DATE_CHANGE') <> '',
                  FormatDateTime('dd.mm.yyyy hh:nn:ss',
                    XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
              Data := Data.parentNode;
            end
            else begin
              //нод будет всегда один
              NodeXmlList := NodeXmlList.Item[0];
              //код присутвует в xml для выгрузки, проверяем дату начала действия
              if (StrToDate(NodeXmlList.getAttribute('DATE_BEGIN')) <
                XmlToDateTime(Kbk.getAttribute('BEGIN_DATE')))
                and (NodeXmlList.getAttribute('DATE_END') <> '') then
              begin
                Data.RemoveChild(NodeXmlList);
                Data := Data.appendChild(FillElementBySchema(Kbk, 'FNST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'FN',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'FN',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

                Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
                  FormatDateTime('dd.mm.yyyy',
                    XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
                Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
                  FormatDateTime('dd.mm.yyyy',
                    XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
                Data.setAttribute('DATE_CHANGE',
                  IfThen(Data.getAttribute('DATE_CHANGE') <> '',
                    FormatDateTime('dd.mm.yyyy hh:nn:ss',
                      XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
                Data := Data.parentNode;
              end;
            end;
          end;
        end;
      end;
      //записываем строку истории кода в sysparam, даже если она не выгружалась
      CurrHistory := CurrHistory.appendChild(CurrHistory.ownerDocument.createElement('ROW'));
      CurrHistory.setAttribute('CODE', Kbk.getAttribute('CODE'));
      CurrHistory.setAttribute('CNAME', Trim(Kbk.getAttribute('CAPTION')));
      CurrHistory.setAttribute('NAME', Trim(Kbk.getAttribute('DESCRIPTION')));
      CurrHistory.setAttribute('DATE_BEGIN', Kbk.getAttribute('BEGIN_DATE'));
      CurrHistory.setAttribute('DATE_END', Kbk.getAttribute('END_DATE'));
      CurrHistory := CurrHistory.parentNode;
      Kbk := Kbk.parentNode;
    end;
  end;
  Result := Data.SelectNodes('FNST').length > 0;
  if not Result then
    OldKbk := OldKbk.parentNode;
  Data := Data.ownerDocument;
end;

function MakeFormatGlava: Boolean;
var
  i: Integer;
  XmlOrg: Variant;
begin
  Result := False;
  Data := CreateOleObject('Microsoft.XmlDom');
  Data.appendChild(Data.createElement('FORMAT'));
  // Чтение номера посылки.
  with TIniFile.Create(DirIni + 'Schems\Send.dat') do
  begin
    PacketNumber := StrToInt(ReadString(IniSection,
      FormatDateTime('yyyymmdd', Now), '0')) + 1;
    Free;
  end;

  //Загрузка схемы
//  LoadSchema(DirIni + 'Schems\fd_txfd090925.xml');
  LoadSchema( GetFileNameSchemaTFF( 'fd_txfd*'));

  WriteLog('Формирование имени выгружаемого файла', True);
  FileOut := GetFileName(Fo.getAttribute('NAME'), 'FD', Now, PacketNumber,
    FileOutIsLocalNet, FileOutOrgCodeIsFk);
  Data := Data.documentElement;
  //создаем xml c текущей историей из базы
  CurrHistory := CreateOleObject('Microsoft.XmlDom');
  CurrHistory := CurrHistory.appendChild(CurrHistory.createElement('HISTORY'));
  CurrHistory := CurrHistory.appendChild(CurrHistory.ownerDocument.createElement('KADM'));
  //ищем node KADM
  NodeXmlList := OldKbk.selectNodes('KADM');
  if NodeXmlList.Length = 0 then
    OldKbk := OldKbk.appendChild(OldKbk.ownerDocument.createElement('KADM'))
  else
    OldKbk := NodeXmlList.Item[0];
  WriteLog('Заполнение данных файла: ' + FileOut, True);
  Data := Data.appendChild(FillElementBySchema(Fo, 'FK'));
  Data.setAttribute('FORM_VER', AppVersion);
  Data := Data.parentNode;
  Data := Data.appendChild(FillElementBySchema(Fo, 'FROM'));
  Data.setAttribute('BUDG_LEVEL', GetBudgLevel(BudgetId));
  Data := Data.parentNode;
  Data.appendChild(FillElementBySchema(Ufk, 'TO'));
  Data := Data.appendChild(FillElementBySchema(Fo, 'FD'));
  Data.setAttribute('NAME_BUD', QueryField(sqlBudgId, [BudgetId], 'CAPTION'));
  Data.setAttribute('DATE_FORM', FormatDateTime('dd.mm.yyyy', Now));
  Data.setAttribute('DOL_ISP', DolIsp);
  Data.setAttribute('NAME_ISP', FioIsp);
  Data.setAttribute('TEL_ISP', TelIsp);
  Data := Data.parentNode;
  WriteLog('Получение данных по администраторам...', True);
  Kbk := Bk_Kadm(BudgetId, StatusBar, ProgressBar, param_ref);
  if param_OutListKbk then
  begin
    InsertDataToCds(CdsList, DBGrid, Kbk);
    Fm_KbkList.Caption := 'Список выгружаемых кодов администратора...';
    if Fm_KbkList.ShowModal = MrOk then
    begin
      Kbk := GetSelectedKbk(CdsList, KbkIdList);
      if not VarIsNull(Kbk) then
      begin
        Kbk := Kbk.documentElement;
        ProgressBar.Max := Kbk.ChildNodes.Length;
        WriteLog('Формирование данных по администраторам к выгрузке...', True);
        for i := 0 to Kbk.ChildNodes.Length - 1 do
        begin
          ProgressBar.Position := i + 1 ;
          Kbk := Kbk.ChildNodes.Item[i];
          Data := Data.appendChild(FillElementBySchema(Kbk, 'FDST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'FD',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'FD',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

          Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
          Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
          Data.setAttribute('DATE_CHANGE', IfThen(Data.getAttribute('DATE_CHANGE') <> '',
            FormatDateTime('dd.mm.yyyy hh:nn:ss',
              XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
          Data := Data.parentNode;
          Kbk := Kbk.parentNode;
        end;
      end;
    end;
  end
  else begin
    Kbk := Kbk.documentElement;
    ProgressBar.Max := Kbk.ChildNodes.Length;
    WriteLog('Формирование данных по администраторам к выгрузке...', True);
    for i := 0 to Kbk.ChildNodes.Length - 1 do
    begin
      ProgressBar.Position := i + 1 ;
      Kbk := Kbk.ChildNodes.Item[i];
      if param_VariantUnloadKBK = 'только измененные строки' then
      begin
        //ищем выбранный код в sysparam
        NodeXmlList := OldKbk.SelectNodes('//ROW[@CODE=''' + Kbk.getAttribute('CODE') +
          ''' and @CNAME =''' + Trim(Kbk.getAttribute('CAPTION')) + ''' and @NAME=''' +
          Trim(Kbk.getAttribute('DESCRIPTION')) + ''' and @DATE_BEGIN=''' +
          Kbk.getAttribute('BEGIN_DATE') + ''' and @DATE_END=''' +
          Kbk.getAttribute('END_DATE') + ''']');
        if NodeXmlList.length = 0 then
        begin
          Data := Data.appendChild(FillElementBySchema(Kbk, 'FDST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'FD',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'FD',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

          Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
          Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
          Data.setAttribute('DATE_CHANGE', IfThen(Data.getAttribute('DATE_CHANGE') <> '',
            FormatDateTime('dd.mm.yyyy hh:nn:ss',
              XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
          Data := Data.parentNode;
        end;
      end
      else if param_VariantUnloadKBK = 'все строки' then
      begin
        Data := Data.appendChild(FillElementBySchema(Kbk, 'FDST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'FD',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'FD',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

        Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
          FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
        Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
          FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
        Data.setAttribute('DATE_CHANGE', IfThen(Data.getAttribute('DATE_CHANGE') <> '',
          FormatDateTime('dd.mm.yyyy hh:nn:ss',
            XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
        Data := Data.parentNode;
      end
      //все последние строки
      else begin
        //дата окончания д.б. больше рабочей или не установлена
        if Kbk.getAttribute('END_DATE') = '' then
        begin
          //выгржаем всегда, т.к. нет даты окончания действия кода.
          Data := Data.appendChild(FillElementBySchema(Kbk, 'FDST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'FD',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'FD',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

          Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
          Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
          Data.setAttribute('DATE_CHANGE', IfThen(Data.getAttribute('DATE_CHANGE') <> '',
            FormatDateTime('dd.mm.yyyy hh:nn:ss',
              XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
          Data := Data.parentNode;
        end
        else begin
          if (XmlToDateTime(Kbk.getAttribute('END_DATE')) >= Work_Date) then
          begin
            //ищем выгружаемый код, среди выгруженных кодов
            NodeXmlList := Data.selectNodes('//FDST[@GLAVA= ' +
              Kbk.getAttribute('CODE') + ']');
            if NodeXmlList.length = 0 then
            begin
              //код в этой сессии не выгружался
              Data := Data.appendChild(FillElementBySchema(Kbk, 'FDST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'FD',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'FD',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

              Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
                FormatDateTime('dd.mm.yyyy',
                  XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
              Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
                FormatDateTime('dd.mm.yyyy',
                  XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
              Data.setAttribute('DATE_CHANGE',
                IfThen(Data.getAttribute('DATE_CHANGE') <> '',
                  FormatDateTime('dd.mm.yyyy hh:nn:ss',
                    XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
              Data := Data.parentNode;
            end
            else begin
              //нод будет всегда один
              NodeXmlList := NodeXmlList.Item[0];
              //код присутвует в xml для выгрузки, проверяем дату начала действия
              if (StrToDate(NodeXmlList.getAttribute('DATE_BEGIN')) <
                XmlToDateTime(Kbk.getAttribute('BEGIN_DATE')))
                and (NodeXmlList.getAttribute('DATE_END') <> '') then
              begin
                Data.RemoveChild(NodeXmlList);
                Data := Data.appendChild(FillElementBySchema(Kbk, 'FDST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'FD',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'FD',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

                Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
                  FormatDateTime('dd.mm.yyyy',
                    XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
                Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
                  FormatDateTime('dd.mm.yyyy',
                    XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
                Data.setAttribute('DATE_CHANGE',
                  IfThen(Data.getAttribute('DATE_CHANGE') <> '',
                    FormatDateTime('dd.mm.yyyy hh:nn:ss',
                      XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
                Data := Data.parentNode;
              end;
            end;
          end;
        end;
      end;
      //записываем строку истории кода в sysparam, даже если она не выгружалась
      CurrHistory := CurrHistory.appendChild(CurrHistory.ownerDocument.createElement('ROW'));
      CurrHistory.setAttribute('CODE', Kbk.getAttribute('CODE'));
      CurrHistory.setAttribute('CNAME', Trim(Kbk.getAttribute('CAPTION')));
      CurrHistory.setAttribute('NAME', Trim(Kbk.getAttribute('DESCRIPTION')));
      CurrHistory.setAttribute('DATE_BEGIN', Kbk.getAttribute('BEGIN_DATE'));
      CurrHistory.setAttribute('DATE_END', Kbk.getAttribute('END_DATE'));
      CurrHistory := CurrHistory.parentNode;
      Kbk := Kbk.parentNode;
    end;
  end;
  Result := Data.SelectNodes('FDST').length > 0;
  if not Result then
    OldKbk := OldKbk.parentNode;
  Data := Data.ownerDocument;
end;

function MakeFormatSubDohIst: Boolean;
var
  i: Integer;
  XmlOrg: Variant;
begin
  Result := False;
  Data := CreateOleObject('Microsoft.XmlDom');
  Data.appendChild(Data.createElement('FORMAT'));
  // Чтение номера посылки.
  with TIniFile.Create(DirIni + 'Schems\Send.dat') do
  begin
    PacketNumber := StrToInt(ReadString(IniSection,
      FormatDateTime('yyyymmdd', Now), '0')) + 1;
    Free;
  end;

  //Загрузка схемы
//  LoadSchema(DirIni + 'Schems\wf_txwf100701.xml');
  LoadSchema( GetFileNameSchemaTFF( 'wf_txwf*'));

  WriteLog('Формирование имени выгружаемого файла', True);
  FileOut := GetFileName(Fo.getAttribute('NAME'), 'WF', Now, PacketNumber,
    FileOutIsLocalNet, FileOutOrgCodeIsFk);
  Data := Data.documentElement;
  //создаем xml c текущей историей из базы
  CurrHistory := CreateOleObject('Microsoft.XmlDom');
  CurrHistory := CurrHistory.appendChild(CurrHistory.createElement('HISTORY'));
  CurrHistory := CurrHistory.appendChild(CurrHistory.ownerDocument.createElement('KSDI'));
  //ищем node KSDI
  NodeXmlList := OldKbk.selectNodes('KSDI');
  if NodeXmlList.Length = 0 then
    OldKbk := OldKbk.appendChild(OldKbk.ownerDocument.createElement('KSDI'))
  else
    OldKbk := NodeXmlList.Item[0];
  WriteLog('Заполнение данных файла: ' + FileOut, True);
  Data := Data.appendChild(FillElementBySchema(Fo, 'FK'));
  Data.setAttribute('FORM_VER', AppVersion);
  Data := Data.parentNode;
  Data := Data.appendChild(FillElementBySchema(Fo, 'FROM'));
  Data.setAttribute('BUDG_LEVEL', GetBudgLevel(BudgetId));
  Data := Data.parentNode;
  Data.appendChild(FillElementBySchema(Ufk, 'TO'));
  Data := Data.appendChild(FillElementBySchema(Fo, 'WF'));
  Data.setAttribute('NAME_BUD', QueryField(sqlBudgId, [BudgetId], 'CAPTION'));
  Data.setAttribute('DATE_FORM', FormatDateTime('dd.mm.yyyy', Work_Date));
  Data.setAttribute('DOL_ISP', DolIsp);
  Data.setAttribute('NAME_ISP', FioIsp);
  Data.setAttribute('TEL_ISP', TelIsp);
  Data := Data.parentNode;
  WriteLog('Получение данных по кодам подвидов доходов, видов источников...', True);
  Kbk := Bk_Ksdi(BudgetId, param_ModeSubDohIst, StatusBar, ProgressBar, param_ref);
  if param_OutListKbk then
  begin
    InsertDataToCds(CdsList, DBGrid, Kbk);
    Fm_KbkList.Caption := 'Список выгружаемых кодов подвидов доходов, видов источников...';
    if Fm_KbkList.ShowModal = MrOk then
    begin
      Kbk := GetSelectedKbk(CdsList, KbkIdList);
      if not VarIsNull(Kbk) then
      begin
        Kbk := Kbk.documentElement;
        ProgressBar.Max := Kbk.ChildNodes.Length;
          WriteLog('Формирование данных по  кодам подвидов доходов,' +
            ' видов источников к выгрузке...', True);
        for i := 0 to Kbk.ChildNodes.Length - 1 do
        begin
          ProgressBar.Position := i + 1 ;
          Kbk := Kbk.ChildNodes.Item[i];
          Data := Data.appendChild(FillElementBySchema(Kbk, 'WFST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'WF',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'WF',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

          Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
          Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
          Data.setAttribute('DATE_CHANGE', IfThen(Data.getAttribute('DATE_CHANGE') <> '',
            FormatDateTime('dd.mm.yyyy hh:nn:ss',
              XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
          Data := Data.parentNode;
          Kbk := Kbk.parentNode;
        end;
      end;
    end;
  end
  else begin
    Kbk := Kbk.documentElement;
    ProgressBar.Max := Kbk.ChildNodes.Length;
    WriteLog('Формирование данных по  кодам подвидов доходов, видов источников' +
      ' к выгрузке...', True);
    for i := 0 to Kbk.ChildNodes.Length - 1 do
    begin
      ProgressBar.Position := i + 1 ;
      Kbk := Kbk.ChildNodes.Item[i];
      if param_VariantUnloadKBK = 'только измененные строки' then
      begin
        //ищем выбранный код в sysparam
        NodeXmlList := OldKbk.SelectNodes('//ROW[@CODE=''' + Kbk.getAttribute('CODE') +
          ''' and @CNAME =''' + Trim(Kbk.getAttribute('CAPTION')) + ''' and @NAME=''' +
          Trim(Kbk.getAttribute('DESCRIPTION')) + ''' and @DATE_BEGIN=''' +
          Kbk.getAttribute('BEGIN_DATE') + ''' and @DATE_END=''' +
          Kbk.getAttribute('END_DATE') + ''']');
        if NodeXmlList.length = 0 then
        begin
          Data := Data.appendChild(FillElementBySchema(Kbk, 'WFST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'WF',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'WF',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

          Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
          Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
          Data.setAttribute('DATE_CHANGE', IfThen(Data.getAttribute('DATE_CHANGE') <> '',
            FormatDateTime('dd.mm.yyyy hh:nn:ss',
              XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
          Data := Data.parentNode;
        end;
      end
      else if param_VariantUnloadKBK = 'все строки' then
      begin
        Data := Data.appendChild(FillElementBySchema(Kbk, 'WFST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'WF',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'WF',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

        Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
          FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
        Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
          FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
        Data.setAttribute('DATE_CHANGE', IfThen(Data.getAttribute('DATE_CHANGE') <> '',
          FormatDateTime('dd.mm.yyyy hh:nn:ss',
            XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
        Data := Data.parentNode;
      end
      //все последние строки
      else begin
        //дата окончания д.б. больше рабочей или не установлена
        if Kbk.getAttribute('END_DATE') = '' then
        begin
          //выгржаем всегда, т.к. нет даты окончания действия кода.
          Data := Data.appendChild(FillElementBySchema(Kbk, 'WFST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'WF',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'WF',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

          Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
          Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
            FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
          Data.setAttribute('DATE_CHANGE', IfThen(Data.getAttribute('DATE_CHANGE') <> '',
            FormatDateTime('dd.mm.yyyy hh:nn:ss',
              XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
          Data := Data.parentNode;
        end
        else begin
          if (XmlToDateTime(Kbk.getAttribute('END_DATE')) >= Work_Date) then
          begin
            //ищем выгружаемый код, среди выгруженных кодов
            NodeXmlList := Data.selectNodes('//WFST[@PVDOH= ' +
              Kbk.getAttribute('CODE') + ']');
            if NodeXmlList.length = 0 then
            begin
              //код в этой сессии не выгружался
              Data := Data.appendChild(FillElementBySchema(Kbk, 'WFST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'WF',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'WF',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

              Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
                FormatDateTime('dd.mm.yyyy',
                  XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
              Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
                FormatDateTime('dd.mm.yyyy',
                  XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
              Data.setAttribute('DATE_CHANGE',
                IfThen(Data.getAttribute('DATE_CHANGE') <> '',
                  FormatDateTime('dd.mm.yyyy hh:nn:ss',
                    XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
              Data := Data.parentNode;
            end
            else begin
              //нод будет всегда один
              NodeXmlList := NodeXmlList.Item[0];
              //код присутвует в xml для выгрузки, проверяем дату начала действия
              if (StrToDate(NodeXmlList.getAttribute('DATE_BEGIN')) <
                XmlToDateTime(Kbk.getAttribute('BEGIN_DATE')))
                and (NodeXmlList.getAttribute('DATE_END') <> '') then
              begin
                Data.RemoveChild(NodeXmlList);
                Data := Data.appendChild(FillElementBySchema(Kbk, 'WFST'));

          // exchange #2629
          Data.setAttribute( 'NAME',
                             ExchangeQuoteChars2629(
                                            'WF',
                                            Data.GetAttribute( 'NAME')));
          Data.setAttribute( 'CNAME',
                             ExchangeQuoteChars2629(
                                            'WF',
                                            VarToStr( Data.GetAttribute( 'CNAME'))));

                Data.setAttribute('DATE_BEGIN', IfThen(Data.getAttribute('DATE_BEGIN') <> '',
                  FormatDateTime('dd.mm.yyyy',
                    XmlToDateTime(Data.getAttribute('DATE_BEGIN'))), ''));
                Data.setAttribute('DATE_END', IfThen(Data.getAttribute('DATE_END') <> '',
                  FormatDateTime('dd.mm.yyyy',
                    XmlToDateTime(Data.getAttribute('DATE_END'))), ''));
                Data.setAttribute('DATE_CHANGE',
                  IfThen(Data.getAttribute('DATE_CHANGE') <> '',
                    FormatDateTime('dd.mm.yyyy hh:nn:ss',
                      XmlToDateTime(Data.getAttribute('DATE_CHANGE'))), ''));
                Data := Data.parentNode;
              end;
            end;
          end;
        end;
      end;
      //записываем строку истории кода в sysparam, даже если она не выгружалась
      CurrHistory := CurrHistory.appendChild(CurrHistory.ownerDocument.createElement('ROW'));
      CurrHistory.setAttribute('CODE', Kbk.getAttribute('CODE'));
      CurrHistory.setAttribute('CNAME', Trim(Kbk.getAttribute('CAPTION')));
      CurrHistory.setAttribute('NAME', Trim(Kbk.getAttribute('DESCRIPTION')));
      CurrHistory.setAttribute('DATE_BEGIN', Kbk.getAttribute('BEGIN_DATE'));
      CurrHistory.setAttribute('DATE_END', Kbk.getAttribute('END_DATE'));
      CurrHistory := CurrHistory.parentNode;
      Kbk := Kbk.parentNode;
    end;
  end;
  Result := Data.SelectNodes('WFST').length > 0;
  if not Result then
    OldKbk := OldKbk.parentNode;
  Data := Data.ownerDocument;
end;

function MakeFormatGrantInvestment: integer;
var
  i: Integer;
  XmlOrg, Budget, Xml: Variant;
  sql, UfkId: String;
  xKBK_List: variant;
  xNomTL: string;
begin
  Result := 0;
  Data := CreateOleObject('Microsoft.XmlDom');
  Data.appendChild(Data.createElement('FORMAT'));
  // Чтение номера посылки.
  with TIniFile.Create(DirIni + 'Schems\Send.dat') do
  begin
    PacketNumber := StrToInt(ReadString(IniSection,
      FormatDateTime('yyyymmdd', Now), '0')) + 1;
    Free;
  end;
  //Загрузка схемы
  // Exchange 2336 загружаем схему в зависимости от версии
  // exchange #2542 - переход на тфф11 + переработка модуля проверки версий схем
  LoadSchema( GetFileNameSchemaTFF( 'tl_txtl*'));
//  LoadSchema( DirIni + VersionSchemsDir + 'tl_txtl120101.xml');
  WriteLog('Формирование имени выгружаемого файла', True);
  //имя файла формируется по коду учредителя
  FileOut := GetFileName(Uchr.getAttribute('ORG_CODE'), 'TL', Now, PacketNumber,
    FileOutIsLocalNet, FileOutOrgCodeIsFk);
  Data := Data.documentElement;
  //ищем node ORGID_
  NodeXmlList := OldKbk.selectNodes('ORGID_' + Uchr.getAttribute('ORG_ID'));
  if NodeXmlList.Length = 0 then
    OldKbk := OldKbk.appendChild(OldKbk.ownerDocument.createElement('ORGID_' + Uchr.getAttribute('ORG_ID')))
  else
    OldKbk := NodeXmlList.Item[0];
  CurrHistory := CurrHistory.appendChild(CurrHistory.ownerDocument.createElement('ORGID_' + Uchr.getAttribute('ORG_ID')));
  WriteLog('Заполнение данных файла: ' + FileOut, True);
  Data := Data.appendChild(FillElementBySchema(Uchr, 'FK'));
  Data.setAttribute('FORM_VER', AppVersion);
  Data := Data.parentNode;
  Data := Data.appendChild(FillElementBySchema(Uchr, 'FROM'));
  Data.setAttribute('BUDG_LEVEL', GetBudgLevel(BudgetId));
  Data := Data.parentNode;
  sql := 'Select O.*, Coalesce(Ob.Code_Fk, O.Name) Org_Code' +
    ' From Org O' +
    ' Left Join OrgBudgetDet Ob on Ob.Org_Id = O.Id and Ob.Budget_Id = ?' +
    ' Where O.Id = ?';
  UfkId := SysParam_UFG_OrgID(BudgetId);
  if UfkId = '' then
    Raise('Не удалось получить организацию УФК. Проверьте заполнение организации' +
      ' в системных параметрах, ветка УФК.');
  Ufk := QueryXml(sql, [BudgetId, UfkId]);
  Ufk := Ufk.documentElement.childNodes.item[0];
  Data.appendChild(FillElementBySchema(Ufk, 'TO'));
  Data := Data.appendChild(FillElementBySchema(Uchr, 'TL'));
  
  // Exchange #2334
  // необходимо для каждого учредителя, при выгрузке, создавать новый номер.
  // этот номер клиент сверяет со своим номером(в диалоге).
  // при каждой выгрузке необходимо создавать свои номера учреждений.
  // в результате, этот номер записывается  поле TL.NOM_TL вместо PacketNumber.
  xNomTL := GetExportNomTL(
          DirIni,
          BudgetId,
          Uchr.getAttribute('ORG_ID'),
          Uchr.getAttribute('DESCRIPTION'));
  if xNomTL = '' then begin
    Result := -1;
    //raise ('Отменено пользователем.');
    EXIT;
  end;
  Data.setAttribute( 'NOM_TL', TRIM( xNomTL));
//  Data.setAttribute('NOM_TL', PacketNumber);
  
  Data.setAttribute('DATE_TL', FormatDateTime('dd.mm.yyyy', Work_Date));
  Budget := QueryXml(sqlBudgId, BudgetId);
  Budget := Budget.documentElement.Childnodes.item[0];
  Data.setAttribute('GOD_SUBS', Budget.getAttribute('FINYEAR'));
  if Data.getAttribute('GLAVA_UCHR') <> '' then
    Data.setAttribute('GLAVA_UCHR', StringReplace(Format('%3s', [Data.getAttribute('GLAVA_UCHR')]), ' ', '0'));
  Data.setAttribute('NAME_ORG', Ufk.getAttribute('DESCRIPTION'));
  Data.setAttribute('GLAVA_ORG', Ufk.getAttribute('KADM_CODE'));
  if Data.getAttribute('GLAVA_ORG') <> '' then
    Data.setAttribute('GLAVA_ORG', StringReplace(Format('%3s', [Data.getAttribute('GLAVA_ORG')]), ' ', '0'));
  Data.setAttribute('NAME_BUD', Budget.getAttribute('CAPTION'));
  // Exchange #2334
  Data.setAttribute('OKATO', QueryField(sqlTerritoryOKATO, [Budget.getAttribute('TERRITORY_ID')], 'TEROKATO'));
  sql := 'Select Rp.*, A.Caption from RespPerson Rp' +
    ' Left Join Appointment A on Rp.Appointment_Id = A.Id' +
    ' Where Rp.Org_Id = ? and A.Id = ?';
  Data.setAttribute('NAME_RUK', QueryField(sql, [Uchr.getAttribute('ORG_ID'), '-2'], 'FIO'));
  Data.setAttribute('NAME_RUK_FES', QueryField(sql, [Uchr.getAttribute('ORG_ID'), '-4'], 'FIO'));
  Xml := QueryXml(sql, [Uchr.getAttribute('ORG_ID'), '-5']);
  if Xml.documentElement.childNodes.Length = 1 then
  begin
    Xml := Xml.documentElement.childNodes.Item[0];
    Data.setAttribute('DOL_ISP_1', Xml.getAttribute('CAPTION'));
    Data.setAttribute('FIO_ISP_1', Xml.getAttribute('FIO'));
    Data.setAttribute('TEL_ISP_1', Xml.getAttribute('PHONE'));
  end;
  // дата подписания
  Data.setAttribute('DATE_POD_1', FormatDateTime('dd.mm.yyyy', Work_Date));
  Data := Data.parentNode;
  WriteLog('Получение данных по кодам субсидии...', True);
  // Exchange #2334
  // добавлен фильтр: по списку справочника субсидийи инвестиций.
  // в результате выбирать записи нужно только из этого справочника.
  Kbk := Bk_GrantInvestment( BudgetId,
                              Uchr.getAttribute('ORG_ID'),
                              StatusBar,
                              ProgressBar,
                              vFilterGrandInvesment,
                              Work_Date,
                              TRUE);
  if VarIsNull( Kbk) then begin
    // ошибка выгрузки
    Result := -1;
    EXIT;
  end;
{
//xFilter:= TStringList.Create;
//Kbk.save('C:\Temp\GrantInvestmentList.xml');
//xKBK_List := Kbk.childNodes.Item[0];
//showmessage(Kbk.xml);
xKBK_List := ChoiceGrantInvestmentList( Uchr.getAttribute('ORG_ID'), DirIni, Kbk.childNodes.Item[0], nil);//xFilter);
if VarIsNull(xKBK_List) then
  raise('Отменено пользователем.');//exit;
Kbk.LoadXml( xKBK_List.xml);
showmessage(Kbk.xml);
exit;
}
  Kbk := Kbk.documentElement;
  ProgressBar.Max := Kbk.ChildNodes.Length;
  WriteLog('Формирование данных по субсидиям к выгрузке...', True);
  for i := 0 to Kbk.ChildNodes.Length - 1 do
  begin
    ProgressBar.Position := i + 1 ;
    Kbk := Kbk.ChildNodes.Item[i];
    if (param_VariantUnloadKBK = 'только измененные строки') or
      (param_VariantUnloadKBK = 'все последние строки') then
    begin
      //ищем выбранный код в sysparam
      NodeXmlList := OldKbk.SelectNodes('//ORGID_' + Uchr.getAttribute('ORG_ID') + '/ROW[@CODE=''' +
        Kbk.getAttribute('CODE') + ''' and @CNAME =''' + Trim(Kbk.getAttribute('CAPTION')) + ''']');
      if NodeXmlList.length = 0 then
      begin
        Data := Data.appendChild(FillElementBySchema(Kbk, 'TLIS'));
        Data.setAttribute('DATE_NPA', IfThen(Data.getAttribute('DATE_NPA') <> '',
          FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_NPA'))), ''));

        // exchange #2629
        Data.setAttribute( 'NAME_SUBS',
                           ExchangeQuoteChars2629(
                                          'TL',
                                          Data.getAttribute('NAME_SUBS')));

        Data := Data.parentNode;
      end;
    end
    //все строки
    else begin
    Data := Data.appendChild(FillElementBySchema(Kbk, 'TLIS'));
    Data.setAttribute('DATE_NPA', IfThen(Data.getAttribute('DATE_NPA') <> '',
        FormatDateTime('dd.mm.yyyy', XmlToDateTime(Data.getAttribute('DATE_NPA'))), ''));

      // exchange #2629
      Data.setAttribute( 'NAME_SUBS',
                         ExchangeQuoteChars2629(
                                        'TL',
                                        Data.getAttribute('NAME_SUBS')));

    Data := Data.parentNode;
    end;
    //записываем строку истории кода в sysparam, даже если она не выгружалась
    CurrHistory := CurrHistory.appendChild(CurrHistory.ownerDocument.createElement('ROW'));
    CurrHistory.setAttribute('CNAME', Trim(Kbk.getAttribute('CAPTION')));
    CurrHistory.setAttribute('CODE', Trim(Kbk.getAttribute('CODE')));
    CurrHistory := CurrHistory.parentNode;
    Kbk := Kbk.parentNode;
  end;
  
  if (Data.SelectNodes('TLIS').length > 0) then Result := 1;
  Data := Data.ownerDocument;
end;

//сделано под текущию реализацию выборки КБК из базы
//NodeName может быть только BEGIN_DATE или CHANGE_DATE
//Возвращает максимальную дату среди дат в Node c атрибутами BEGIN_DATE,
//BEGIN_DATE1 ... или CHANGE_DATE, CHANGE_DATE1... в зависимости от параметра
//NodeName. NodeName подается в виде Xml даты. Пустых данных быть не может
function MaxDateFromNode(Node: Variant; NodeName: String): String;
var
  j: Integer;
begin
  Result := FormatDateTime('dd.mm.yyyy hh:nn:ss',
    XmlToDateTime(Node.getAttribute(NodeName)));
  for j := 1 to 4 do
    if (not VarIsNull(Node.getAttribute(NodeName + IntToStr(j)))) then
    begin
      if (StrToDateTime(Result) < XmlToDateTime(Node.getAttribute(NodeName +
        IntToStr(j)))) then
        Result := FormatDateTime('dd.mm.yyyy hh:nn:ss',
          XmlToDateTime(Node.getAttribute(NodeName + IntToStr(j))));
    end
    else
      Exit;
end;
//Поиск минимальной даты среди всех кодов. Для каждого кода ищется отрезок с
//с максимальной датой начала, среди этих отрезков выбирается отрезок с
//минимальной датой окончания
function MinDateFromNodes(Nodes: Variant): String;
var
  i, j, indxNode: Integer;
  Begin_Date: TDate;
begin
  Result := '';
  indxNode := 0;
  Begin_Date := XmlToDateTime(Nodes.ChildNodes.Item[0].getAttribute('BEGIN_DATE'));
  //Для первого кода цикл по нодам отдельный
  for i := 0 to Nodes.ChildNodes.Length - 1 do
  begin
    Nodes := Nodes.ChildNodes.Item[i];
    if (Begin_Date < XmlToDateTime(Nodes.getAttribute('BEGIN_DATE'))) then
    begin
      Begin_Date := XmlToDateTime(Nodes.getAttribute('BEGIN_DATE'));
      indxNode := i;
    end;
    Nodes := Nodes.parentNode;
  end;
  Result := IfThen(Nodes.ChildNodes.Item[indxNode].getAttribute('END_DATE') <> '',
    FormatDateTime('dd.mm.yyyy',
      XmlToDateTime(Nodes.ChildNodes.Item[indxNode].getAttribute('END_DATE'))), '');
  //цикл по атрибутам
  for j := 1 to 4 do
  begin
    if (not VarIsNull(Nodes.ChildNodes.Item[0].getAttribute('BEGIN_DATE' + IntToStr(j)))) then
    begin
      Begin_Date := XmlToDateTime(Nodes.ChildNodes.Item[0].getAttribute('BEGIN_DATE' +
        IntToStr(j)));
      for i := 0 to Nodes.ChildNodes.Length - 1 do
      begin
        Nodes := Nodes.ChildNodes.Item[i];
        if (Begin_Date < XmlToDateTime(Nodes.getAttribute('BEGIN_DATE' + IntToStr(j)))) then
        begin
          Begin_Date := XmlToDateTime(Nodes.getAttribute('BEGIN_DATE' + IntToStr(j)));
          indxNode := i;
        end;
        Nodes := Nodes.parentNode;
      end;
      if (Result <> '') and (Nodes.ChildNodes.Item[indxNode].getAttribute('END_DATE' + IntToStr(j)) <> '') then
      begin
        if (StrToDate(Result) > XmlToDateTime(Nodes.ChildNodes.Item[indxNode].getAttribute('END_DATE' +
          IntToStr(j)))) then
          Result := FormatDateTime('dd.mm.yyyy',
            XmlToDateTime(Nodes.ChildNodes.Item[indxNode].getAttribute('END_DATE' + IntToStr(j))));
      end
      else if (Nodes.ChildNodes.Item[indxNode].getAttribute('END_DATE' + IntToStr(j)) <> '') then
        Result := FormatDateTime('dd.mm.yyyy',
          XmlToDateTime(Nodes.ChildNodes.Item[indxNode].getAttribute('END_DATE' + IntToStr(j))));
    end
    else Exit;
  end;
end;

//Возвращает строку для записи в файл, в зависимости от параметра
//param_VariantUnloadKBK
//CodeLines - содержит код из РЧБ со всеми строками
//XmlListCodeforCds - используется для выгрузки списка кодов. Для формирования в cds
procedure KbkLineRash(CodeLines, XmlListCodeforCds: Variant;
  param_OutListKbk: Boolean);
var
  Begin_Date, End_Date, Change_Date, NewBegin_Date, NewEnd_Date,
  NewChange_Date, Kvsr_Name, Kfsr_Name, Kcsr_Name, Kvr_Name, Kes_Name: String;
  i: Integer;
  Kvsr_Date, Kfsr_Date, Kcsr_Date, Kvr_Date, Kes_Date: TDate;
  Lim: Boolean;// флаг выгрузки доведения лимитов
begin
  //для выгрузки всех кодов, независимо от параметра
  //один алгоритм формирования данных
  Kcsr_Name := CodeLines.ChildNodes.Item[0].getAttribute('KCSR_DESC');
  Kvr_Name := CodeLines.ChildNodes.Item[0].getAttribute('KVR_DESC');
  Kfsr_Name := CodeLines.ChildNodes.Item[0].getAttribute('KFSR_DESC');
  Kes_Name := CodeLines.ChildNodes.Item[0].getAttribute('KESR_DESC');
  Kvsr_Name := CodeLines.ChildNodes.Item[0].getAttribute('KADMR_DESC');
  Kcsr_Date := XmlToDateTime(CodeLines.ChildNodes.Item[0].getAttribute('BEGIN_DATE'));
  Kvr_Date := XmlToDateTime(CodeLines.ChildNodes.Item[0].getAttribute('BEGIN_DATE1'));
  Kfsr_Date := XmlToDateTime(CodeLines.ChildNodes.Item[0].getAttribute('BEGIN_DATE2'));
  Kes_Date := XmlToDateTime(CodeLines.ChildNodes.Item[0].getAttribute('BEGIN_DATE3'));
  Kvsr_Date := XmlToDateTime(CodeLines.ChildNodes.Item[0].getAttribute('BEGIN_DATE4'));
  //выбираем максимальную дату начала и минимальную дату окончания действия
  Begin_Date := MaxDateFromNode(CodeLines.ChildNodes.Item[0], 'BEGIN_DATE');
  Change_Date := MaxDateFromNode(CodeLines.ChildNodes.Item[0], 'CHANGE_DATE');
  Lim := True;
  for i := 1 to CodeLines.ChildNodes.Length - 1 do
  begin
    CodeLines := CodeLines.ChildNodes.Item[i];
    NewBegin_Date := MaxDateFromNode(CodeLines, 'BEGIN_DATE');
    NewChange_Date := MaxDateFromNode(CodeLines, 'CHANGE_DATE');
    if StrToDateTime(NewBegin_Date) > StrToDateTime(Begin_Date) then
      Begin_Date := NewBegin_Date;
    if StrToDateTime(NewChange_Date) > StrToDateTime(Change_Date) then
      Change_Date := NewChange_Date;
    if (Kcsr_Date < XmlToDateTime(CodeLines.getAttribute('BEGIN_DATE'))) then
    begin
      Kcsr_Date := XmlToDateTime(CodeLines.getAttribute('BEGIN_DATE'));
      Kcsr_Name := CodeLines.getAttribute('KCSR_DESC');
    end;
    if (Kvr_Date < XmlToDateTime(CodeLines.getAttribute('BEGIN_DATE1'))) then
    begin
      Kvr_Date := XmlToDateTime(CodeLines.getAttribute('BEGIN_DATE1'));
      Kvr_Name := CodeLines.getAttribute('KVR_DESC');
    end;
    if not param_NameKBK then begin
      if (Kfsr_Date < XmlToDateTime(CodeLines.getAttribute('BEGIN_DATE2'))) then
      begin
        Kfsr_Date := XmlToDateTime(CodeLines.getAttribute('BEGIN_DATE2'));
        Kfsr_Name := CodeLines.getAttribute('KFSR_DESC');
      end;
      if (Kes_Date < XmlToDateTime(CodeLines.getAttribute('BEGIN_DATE3'))) then
      begin
        Kes_Date := XmlToDateTime(CodeLines.getAttribute('BEGIN_DATE3'));
        Kes_Name := CodeLines.getAttribute('KESR_DESC');
      end;
      if (Kvsr_Date < XmlToDateTime(CodeLines.getAttribute('BEGIN_DATE4'))) then
      begin
        Kvsr_Date := XmlToDateTime(CodeLines.getAttribute('BEGIN_DATE4'));
        Kvsr_Name := CodeLines.getAttribute('KADMR_DESC');
      end;
    end;
    //Exchange #2167
    if (Lim) and (CodeLines.getAttribute('LIM') = 0) then
    begin
      Lim := False;
      CodeLines.parentNode.ChildNodes.Item[0].setAttribute('LIM', 0);
    end;
    CodeLines := CodeLines.parentNode;
  end;
  End_Date := MinDateFromNodes(CodeLines);
  CodeLines := CodeLines.childNodes.Item[0];
  //для выгрузки КБК из списка нужны только коды с правильными датами
  if param_OutListKbk then
  begin
    //проверка такая же как и при параметре все строки. По старой постановке.
    if (End_Date = '') or (StrToDateTime(Begin_Date) < StrToDateTime(End_Date)) then
    begin
      XmlListCodeforCds :=
        XmlListCodeforCds.appendChild(XmlListCodeforCds.ownerDocument.createElement('ROW'));
      XmlListCodeforCds.setAttribute('CODE', CodeLines.getAttribute('CODE'));
      if param_NameKBK then
        XmlListCodeforCds.setAttribute('DESCRIPTION',
          Kcsr_Name + Ifthen((Kcsr_Name <> '') and (Kvr_Name <> ''), ' ') + Kvr_Name)
      else
        XmlListCodeforCds.setAttribute('DESCRIPTION', Kvsr_Name + '.' +
          Kfsr_Name + '.' + Kcsr_Name + '.' + Kvr_Name + '.' + Kes_Name);
      XmlListCodeforCds.setAttribute('BEGIN_DATE', DateTimeToXml(StrToDateTime(Begin_Date)));
      XmlListCodeforCds.setAttribute('CHANGE_DATE', DateTimeToXml(StrToDateTime(Change_Date)));
      if (End_Date <> '') then
        XmlListCodeforCds.setAttribute('END_DATE', DateTimeToXml(StrToDateTime(End_Date)))
      else
        XmlListCodeforCds.setAttribute('END_DATE', '');
      XmlListCodeforCds.setAttribute('TYPE_KBK', 10);
      XmlListCodeforCds.setAttribute('LIMIT', CodeLines.getAttribute('LIM'));
      XmlListCodeforCds.setAttribute('CAPTION', '');
      XmlListCodeforCds := XmlListCodeforCds.parentNode;
    end;
    Exit;
  end;
  if param_VariantUnloadKBK = 'только измененные строки' then
  begin
    //ищем выбранный код в sysparam
    if param_NameKBK then
      NodeXmlList := OldKbk.SelectNodes('//ROW[@CODE=''' + CodeLines.getAttribute('CODE') +
        ''' and @NAME=''' + Trim(Kcsr_Name + ' ' + Kvr_Name) + ''' and @DATE_BEGIN=''' +
        DateToStr(StrToDateTime(Begin_Date)) + ''' and @DATE_END=''' + End_Date + ''']')
    else
      NodeXmlList := OldKbk.SelectNodes('//ROW[@CODE=''' + CodeLines.getAttribute('CODE') +
        ''' and @NAME=''' + Trim(Kvsr_Name + '.' + Kfsr_Name + '.' + Kcsr_Name + '.'
        + Kvr_Name + '.' + Kes_Name) + ''' and @DATE_BEGIN=''' +
        DateToStr(StrToDateTime(Begin_Date)) + ''' and @DATE_END=''' + End_Date + ''']');
    if NodeXmlList.length = 0 then
    begin
      Data := Data.appendChild(FillElementBySchema(CodeLines, 'DKST'));
      Data.setAttribute('TYPE_KBK', 10);
      if param_NameKBK then
        Data.setAttribute('NAME', Kcsr_Name + Ifthen((Kcsr_Name <> '') and (Kvr_Name <> ''), ' ') + Kvr_Name)
      else
        Data.setAttribute('NAME', Kvsr_Name + '.' + Kfsr_Name + '.' + Kcsr_Name + '.'
          + Kvr_Name + '.' + Kes_Name);

      // exchange #2629
      Data.setAttribute( 'NAME',
                         ExchangeQuoteChars2629(
                                        'DK',
                                        Data.GetAttribute( 'NAME')));

      Data.setAttribute('LIMIT', CodeLines.getAttribute('LIM'));
      Data.setAttribute('DATE_BEGIN', DateToStr(StrToDateTime(Begin_Date)));
      Data.setAttribute('DATE_CHANGE', Change_Date);
      Data.setAttribute('DATE_END', End_Date);
      Data := Data.parentNode;
    end;
  end
  else if param_VariantUnloadKBK = 'все строки' then
  begin
    if (End_Date = '') or (StrToDateTime(Begin_Date) < StrToDateTime(End_Date)) then
    begin
      Data := Data.appendChild(FillElementBySchema(CodeLines, 'DKST'));
      Data.setAttribute('TYPE_KBK', 10);
      if param_NameKBK then
        Data.setAttribute('NAME', Kcsr_Name + Ifthen((Kcsr_Name <> '') and (Kvr_Name <> ''), ' ') + Kvr_Name)
      else
        Data.setAttribute('NAME', Kvsr_Name + '.' + Kfsr_Name + '.' + Kcsr_Name + '.'
          + Kvr_Name + '.' + Kes_Name);

      // exchange #2629
      Data.setAttribute( 'NAME',
                         ExchangeQuoteChars2629(
                                        'DK',
                                        Data.GetAttribute( 'NAME')));

      Data.setAttribute('LIMIT', CodeLines.getAttribute('LIM'));
      Data.setAttribute('DATE_BEGIN', DateToStr(StrToDateTime(Begin_Date)));
      Data.setAttribute('DATE_CHANGE', Change_Date);
      Data.setAttribute('DATE_END', End_Date);
      Data := Data.parentNode;
    end;
  end
  //все последние строки
  else begin
    if (End_Date = '') or ((StrToDateTime(Begin_Date) < StrToDateTime(End_Date))
      and (Work_Date <= StrToDate(End_Date))) then
    begin
      Data := Data.appendChild(FillElementBySchema(CodeLines, 'DKST'));
      Data.setAttribute('TYPE_KBK', 10);
      if param_NameKBK then
        Data.setAttribute('NAME', Kcsr_Name + Ifthen((Kcsr_Name <> '') and (Kvr_Name <> ''), ' ') + Kvr_Name)
      else
        Data.setAttribute('NAME', Kvsr_Name + '.' + Kfsr_Name + '.' + Kcsr_Name + '.'
          + Kvr_Name + '.' + Kes_Name);

      // exchange #2629
      Data.setAttribute( 'NAME',
                         ExchangeQuoteChars2629(
                                        'DK',
                                        Data.GetAttribute( 'NAME')));

      Data.setAttribute('LIMIT', CodeLines.getAttribute('LIM'));
      Data.setAttribute('DATE_BEGIN', DateToStr(StrToDateTime(Begin_Date)));
      Data.setAttribute('DATE_CHANGE', Change_Date);
      Data.setAttribute('DATE_END', End_Date);
      Data := Data.parentNode;
    end;
  end;
  //историю по коду перезаписываем в любом случае. постановка.
  CurrHistory := CurrHistory.appendChild(CurrHistory.ownerDocument.createElement('ROW'));
  CurrHistory.setAttribute('CODE', CodeLines.getAttribute('CODE'));
  CurrHistory.setAttribute('CNAME', '');
  if param_NameKBK then
    CurrHistory.setAttribute('NAME', Trim(Kcsr_Name + ' ' + Kvr_Name))
  else
    CurrHistory.setAttribute('NAME', Trim(Kvsr_Name + '.' + Kfsr_Name + '.' + Kcsr_Name + '.'
      + Kvr_Name + '.' + Kes_Name));
  CurrHistory.setAttribute('DATE_BEGIN', DateToStr(StrToDateTime(Begin_Date)));
  CurrHistory.setAttribute('DATE_END', End_Date);
  CurrHistory := CurrHistory.parentNode;
  CodeLines := CodeLines.parentNode;
end;

//Возвращает строку для записи в файл, в зависимости от параметра
//param_VariantUnloadKBK
//CodeLines - содержит код из ДЧБ со всеми строками
//XmlListCodeforCds - используется для выгрузки списка кодов. Для формирования в cds
procedure KbkLineDoh(CodeLines, XmlListCodeforCds: Variant;
  param_OutListKbk: Boolean);
var
  Begin_Date, End_Date, Change_Date, NewBegin_Date, NewEnd_Date,
  NewChange_Date, Description: String;
  i: Integer;
  Kd_Date: TDate;
begin
  //для выгрузки всех кодов, независимо от параметра
  //один алгоритм формирования данных
  Description := CodeLines.ChildNodes.Item[0].getAttribute('DESCRIPTION');
  Kd_Date := XmlToDateTime(CodeLines.ChildNodes.Item[0].getAttribute('BEGIN_DATE'));
  //выбираем максимальную дату начала и минимальную дату окончания действия
  Begin_Date := MaxDateFromNode(CodeLines.ChildNodes.Item[0], 'BEGIN_DATE');
  Change_Date := MaxDateFromNode(CodeLines.ChildNodes.Item[0], 'CHANGE_DATE');
  for i := 1 to CodeLines.ChildNodes.Length - 1 do
  begin
    CodeLines := CodeLines.ChildNodes.Item[i];
    NewBegin_Date := MaxDateFromNode(CodeLines, 'BEGIN_DATE');
    NewChange_Date := MaxDateFromNode(CodeLines, 'CHANGE_DATE');
    if StrToDateTime(NewBegin_Date) > StrToDateTime(Begin_Date) then
      Begin_Date := NewBegin_Date;
    if StrToDateTime(NewChange_Date) > StrToDateTime(Change_Date) then
      Change_Date := NewChange_Date;
    if (Kd_Date < XmlToDateTime(CodeLines.getAttribute('BEGIN_DATE'))) then
    begin
      Kd_Date := XmlToDateTime(CodeLines.getAttribute('BEGIN_DATE'));
      Description := CodeLines.getAttribute('DESCRIPTION');
    end;
    CodeLines := CodeLines.parentNode;
  end;
  End_Date := MinDateFromNodes(CodeLines);
  CodeLines := CodeLines.childNodes.Item[0];
  if param_OutListKbk then
  begin
    //проверка такая же как и при параметре все строки. По старой постановке.
    if (End_Date = '') or (StrToDateTime(Begin_Date) < StrToDateTime(End_Date)) then
    begin
      XmlListCodeforCds :=
        XmlListCodeforCds.appendChild(XmlListCodeforCds.ownerDocument.createElement('ROW'));
      XmlListCodeforCds.setAttribute('CODE', CodeLines.getAttribute('CODE'));
      XmlListCodeforCds.setAttribute('DESCRIPTION', Description);
      XmlListCodeforCds.setAttribute('BEGIN_DATE', DateTimeToXml(StrToDateTime(Begin_Date)));
      XmlListCodeforCds.setAttribute('CHANGE_DATE', DateTimeToXml(StrToDateTime(Change_Date)));
      if (End_Date <> '') then
        XmlListCodeforCds.setAttribute('END_DATE', DateTimeToXml(StrToDateTime(End_Date)))
      else
        XmlListCodeforCds.setAttribute('END_DATE', '');
      XmlListCodeforCds.setAttribute('TYPE_KBK', 20);
      XmlListCodeforCds.setAttribute('CAPTION', '');
      XmlListCodeforCds := XmlListCodeforCds.parentNode;
    end;
    Exit;
  end;
  if param_VariantUnloadKBK = 'только измененные строки' then
  begin
    //ищем выбранный код в sysparam
    NodeXmlList := OldKbk.SelectNodes('//ROW[@CODE=''' + CodeLines.getAttribute('CODE') +
      ''' and @NAME=''' + Trim(Description) + ''' and @DATE_BEGIN=''' +
      DateToStr(StrToDateTime(Begin_Date)) + ''' and @DATE_END=''' + End_Date + ''']');
    if NodeXmlList.length = 0 then
    begin
      Data := Data.appendChild(FillElementBySchema(CodeLines, 'DKST'));
      Data.setAttribute('TYPE_KBK', 20);
      Data.setAttribute('NAME', Description);

      // exchange #2629
      Data.setAttribute( 'NAME',
                         ExchangeQuoteChars2629(
                                        'DK',
                                        Data.GetAttribute( 'NAME')));

      Data.setAttribute('DATE_BEGIN', DateToStr(StrToDateTime(Begin_Date)));
      Data.setAttribute('DATE_CHANGE', Change_Date);
      Data.setAttribute('DATE_END', End_Date);
      Data := Data.parentNode;
    end;
  end
  else if param_VariantUnloadKBK = 'все строки' then
  begin
    if (End_Date = '') or (StrToDateTime(Begin_Date) < StrToDateTime(End_Date)) then
    begin
      Data := Data.appendChild(FillElementBySchema(CodeLines, 'DKST'));
      Data.setAttribute('TYPE_KBK', 20);
      Data.setAttribute('NAME', Description);

      // exchange #2629
      Data.setAttribute( 'NAME',
                         ExchangeQuoteChars2629(
                                        'DK',
                                        Data.GetAttribute( 'NAME')));

      Data.setAttribute('DATE_BEGIN', DateToStr(StrToDateTime(Begin_Date)));
      Data.setAttribute('DATE_CHANGE', Change_Date);
      Data.setAttribute('DATE_END', End_Date);
      Data := Data.parentNode;
    end;
  end
  //все последние строки
  else begin
    if (End_Date = '') or ((StrToDateTime(Begin_Date) < StrToDateTime(End_Date))
      and (Work_Date <= StrToDate(End_Date))) then
    begin
      Data := Data.appendChild(FillElementBySchema(CodeLines, 'DKST'));
      Data.setAttribute('TYPE_KBK', 20);
      Data.setAttribute('NAME', Description);

      // exchange #2629
      Data.setAttribute( 'NAME',
                         ExchangeQuoteChars2629(
                                        'DK',
                                        Data.GetAttribute( 'NAME')));

      Data.setAttribute('DATE_BEGIN', DateToStr(StrToDateTime(Begin_Date)));
      Data.setAttribute('DATE_CHANGE', Change_Date);
      Data.setAttribute('DATE_END', End_Date);
      Data := Data.parentNode;
    end;
  end;
  //историю по коду перезаписываем в любом случае. постановка.
  CurrHistory := CurrHistory.appendChild(CurrHistory.ownerDocument.createElement('ROW'));
  CurrHistory.setAttribute('CODE', CodeLines.getAttribute('CODE'));
  CurrHistory.setAttribute('CNAME', '');
  CurrHistory.setAttribute('NAME', Trim(Description));
  CurrHistory.setAttribute('DATE_BEGIN', DateToStr(StrToDateTime(Begin_Date)));
  CurrHistory.setAttribute('DATE_END', End_Date);
  CurrHistory := CurrHistory.parentNode;
  CodeLines := CodeLines.parentNode;
end;

//Возвращает строку для записи в файл, в зависимости от параметра
//param_VariantUnloadKBK
//CodeLines - содержит код из ДЧБ со всеми строками
//XmlListCodeforCds - используется для выгрузки списка кодов. Для формирования в cds
procedure KbkLineIst(CodeLines, XmlListCodeforCds: Variant;
  param_OutListKbk: Boolean);
var
  Begin_Date, End_Date, Change_Date, NewBegin_Date, NewEnd_Date,
  NewChange_Date, Description: String;
  i: Integer;
  Ki_Date: TDate;
begin
  //для выгрузки всех кодов, независимо от параметра
  //один алгоритм формирования данных
  Description := CodeLines.childNodes.Item[0].getAttribute('DESCRIPTION');
  Ki_Date := XmlToDateTime(CodeLines.childNodes.Item[0].getAttribute('BEGIN_DATE'));
  //выбираем максимальную дату начала и минимальную дату окончания действия
  Begin_Date := MaxDateFromNode(CodeLines.childNodes.Item[0], 'BEGIN_DATE');
  Change_Date := MaxDateFromNode(CodeLines.childNodes.Item[0], 'CHANGE_DATE');
  for i := 1 to CodeLines.childNodes.Length - 1 do
  begin
    CodeLines := CodeLines.childNodes.Item[i];
    NewBegin_Date := MaxDateFromNode(CodeLines, 'BEGIN_DATE');
    NewChange_Date := MaxDateFromNode(CodeLines, 'CHANGE_DATE');
    if StrToDateTime(NewBegin_Date) > StrToDateTime(Begin_Date) then
      Begin_Date := NewBegin_Date;
    if StrToDateTime(NewChange_Date) > StrToDateTime(Change_Date) then
      Change_Date := NewChange_Date;
    if (Ki_Date < XmlToDateTime(CodeLines.getAttribute('BEGIN_DATE'))) then
    begin
      Ki_Date := XmlToDateTime(CodeLines.getAttribute('BEGIN_DATE'));
      Description := CodeLines.getAttribute('DESCRIPTION');
    end;
    CodeLines := CodeLines.parentNode;
  end;
  End_Date := MinDateFromNodes(CodeLines);
  CodeLines := CodeLines.childNodes.Item[0];
  if param_OutListKbk then
  begin
    //проверка такая же как и при параметре все строки. По старой постановке.
    if (End_Date = '') or (StrToDateTime(Begin_Date) < StrToDateTime(End_Date)) then
    begin
      XmlListCodeforCds :=
        XmlListCodeforCds.appendChild(XmlListCodeforCds.ownerDocument.createElement('ROW'));
      XmlListCodeforCds.setAttribute('CODE', CodeLines.getAttribute('CODE'));
      XmlListCodeforCds.setAttribute('DESCRIPTION', Description);
      XmlListCodeforCds.setAttribute('BEGIN_DATE', DateTimeToXml(StrToDateTime(Begin_Date)));
      XmlListCodeforCds.setAttribute('CHANGE_DATE', DateTimeToXml(StrToDateTime(Change_Date)));
      if (End_Date <> '') then
        XmlListCodeforCds.setAttribute('END_DATE', DateTimeToXml(StrToDateTime(End_Date)))
      else
        XmlListCodeforCds.setAttribute('END_DATE', '');
      if Copy(KiCodeFormat(CodeLines.getAttribute('KI_CODE'), BudgetId), 1, 2) = '01' then
        XmlListCodeforCds.setAttribute('TYPE_KBK', 31)
      else
        XmlListCodeforCds.setAttribute('TYPE_KBK', 32);
      XmlListCodeforCds.setAttribute('CAPTION', '');
      XmlListCodeforCds := XmlListCodeforCds.parentNode;
    end;
    Exit;
  end;
  if param_VariantUnloadKBK = 'только измененные строки' then
  begin
    //ищем выбранный код в sysparam
    NodeXmlList := OldKbk.SelectNodes('//ROW[@CODE=''' + CodeLines.getAttribute('CODE') +
      ''' and @NAME=''' + Description + ''' and @DATE_BEGIN=''' +
      DateToStr(StrToDateTime(Begin_Date)) + ''' and @DATE_END=''' + End_Date + ''']');
    if NodeXmlList.length = 0 then
    begin
      Data := Data.appendChild(FillElementBySchema(CodeLines, 'DKST'));
      if Copy(KiCodeFormat(CodeLines.getAttribute('KI_CODE'), BudgetId), 1, 2) = '01' then
        Data.setAttribute('TYPE_KBK', 31)
      else
        Data.setAttribute('TYPE_KBK', 32);
      Data.setAttribute('NAME', Description);

      // exchange #2629
      Data.setAttribute( 'NAME',
                         ExchangeQuoteChars2629(
                                        'DK',
                                        Data.GetAttribute( 'NAME')));

      Data.setAttribute('DATE_BEGIN', DateToStr(StrToDateTime(Begin_Date)));
      Data.setAttribute('DATE_CHANGE', Change_Date);
      Data.setAttribute('DATE_END', End_Date);
      Data := Data.parentNode;
    end;
  end
  else if param_VariantUnloadKBK = 'все строки' then
  begin
    if (End_Date = '') or (StrToDateTime(Begin_Date) < StrToDateTime(End_Date)) then
    begin
      Data := Data.appendChild(FillElementBySchema(CodeLines, 'DKST'));
      if Copy(KiCodeFormat(CodeLines.getAttribute('KI_CODE'), BudgetId), 1, 2) = '01' then
        Data.setAttribute('TYPE_KBK', 31)
      else
        Data.setAttribute('TYPE_KBK', 32);
      Data.setAttribute('NAME', Description);

      // exchange #2629
      Data.setAttribute( 'NAME',
                         ExchangeQuoteChars2629(
                                        'DK',
                                        Data.GetAttribute( 'NAME')));

      Data.setAttribute('DATE_BEGIN', DateToStr(StrToDateTime(Begin_Date)));
      Data.setAttribute('DATE_CHANGE', Change_Date);
      Data.setAttribute('DATE_END', End_Date);
      Data := Data.parentNode;
    end;
  end
  //все последние строки
  else begin
    if (End_Date = '') or ((StrToDateTime(Begin_Date) < StrToDateTime(End_Date))
      and (Work_Date <= StrToDate(End_Date))) then
    begin
      Data := Data.appendChild(FillElementBySchema(CodeLines, 'DKST'));
      if Copy(KiCodeFormat(CodeLines.getAttribute('KI_CODE'), BudgetId), 1, 2) = '01' then
        Data.setAttribute('TYPE_KBK', 31)
      else
        Data.setAttribute('TYPE_KBK', 32);
      Data.setAttribute('NAME', Description);

      // exchange #2629
      Data.setAttribute( 'NAME',
                         ExchangeQuoteChars2629(
                                        'DK',
                                        Data.GetAttribute( 'NAME')));

      Data.setAttribute('DATE_BEGIN', DateToStr(StrToDateTime(Begin_Date)));
      Data.setAttribute('DATE_CHANGE', Change_Date);
      Data.setAttribute('DATE_END', End_Date);
      Data := Data.parentNode;
    end;
  end;
  //историю по коду перезаписываем в любом случае. постановка.
  CurrHistory := CurrHistory.appendChild(CurrHistory.ownerDocument.createElement('ROW'));
  CurrHistory.setAttribute('CODE', CodeLines.getAttribute('CODE'));
  CurrHistory.setAttribute('CNAME', '');
  CurrHistory.setAttribute('NAME', Description);
  CurrHistory.setAttribute('DATE_BEGIN', DateToStr(StrToDateTime(Begin_Date)));
  CurrHistory.setAttribute('DATE_END', End_Date);
  CurrHistory := CurrHistory.parentNode;
  CodeLines := CodeLines.parentNode;
end;

procedure SaveDataInSysParam;
begin
  //историю выгрузки не сохраняем при ручном выборе КБК
  if param_OutListKbk then Exit;
  //Запись выгруженных КБК.
  WriteLog('Сохранение данных по выгруженным КБК...');
  OldKbk := OldKbk.ownerDocument;
  SysParam := CreateOleObject('Microsoft.XmlDom');
  with SysParam.appendChild(SysParam.createElement('REFERENCE')) do
  begin
    setAttribute('ref_name', 'SYSPARAM');
    setAttribute('action', 'save');
    with appendChild(SysParam.createElement('SYSPARAM')) do
    begin
      setAttribute('NAME', 'exchange.kbkcompare');
      with appendChild(SysParam.createElement('PARAM_VALUE')) do
        with appendChild(SysParam.createCDATASection('')) do
          SysParam.getElementsByTagName('PARAM_VALUE').items[0].
            firstChild.Data := OldKbk.Xml;
    end;
    ExecXml(SysParam.xml);
  end;
  //OldKbk.Save('D:\AzkExchange\Sysparam.xml');
end;

procedure Initialize(Xml: Variant);
var SL: TStringList;
begin
  SL := TStringList.Create;
  with SL do
  try
    CommaText := InitializeDefault(Xml, ChangeFileExt(TestFileName, ''));
    //визиуализация выгрузки
    Form := TFormCustom.Create(Application);
    //LoadForm(DirIni + 'Forms\Fm_Process.dfm', Form);
    Form.LoadDfm( DirIni + 'Forms\Fm_Process.dfm');
    // связываем контролы прогресс бара и стутс бара с доп.формой
    AttachProgressControl(
            TProgressBar(Form.FindComponent('ProgressBar')),
            TStatusBar(Form.FindComponent('StatusBar')));
    //инициализация кэша КБК по маске
    CacheFormatKbk := TStringList.Create;
    DolIsp := Values['Должность исполнителя'];
    FioIsp := Values['ФИО исполнителя'];
    TelIsp := Values['Телефон исполнителя'];
    UnloadKbk := Values['Выгружать КБК'] = 'Да';
    UnloadGlava := Values['Выгружать справочник кодов глав'] = 'Да';
    UnloadKcsr := Values['Выгружать справочник кодов по КЦСР'] = 'Да';
    UnloadKvr := Values['Выгружать справочник кодов по КВР'] = 'Да';
    UnloadSubDohIst := Values['Выгружать справочник коды видов источников,' +
      ' коды подвидов доходов'] = 'Да';
    UnloadGrantInvestment := Values['Выгружать справочник целевых субсидий'] = 'Да';
    param_ref := Values['Выгружать коды глав, КЦСР, КВР, коды подвидов доходов,' +
      ' видов источников из справочника'] = 'Да';
    param_UnloadKbkFromAllBudget := Values['Выгружать КБК из всех бюджетов'] = 'Да';
    param_VariantUnloadKBK := Values['Вариант выгрузки КБК'];
    param_NameKBK := Values['Выгрузка наименования кбк расходов'] = 'КЦСР КВР';
    param_ModeSubDohIst := Values['Режим выгрузки кодов видов источников,' +
      ' кодов подвидов доходов'];
    param_ChangePrevYear :=
      Values['Выгружать измененные КБК относительно прошлого года'] = 'Да';
    //Exchange #2144
    param_ShowFormParam :=
      Values['Выдавать запрос на выгрузку справочников КБК'] = 'Да';
    // Exchange 2336: поддерживаемая версия
    ParseParametersVersionSupport( DirIni, SL);
    // exchange #2629
    Exch2629_Initialize( SL);
    if param_ShowFormParam then
    begin
      Fm_ParamUnloadKbk := TFormCustom.Create(Application);
      try
        LoadForm(DirIni + 'Forms\Fm_ParamUnloadKbk.dfm', Fm_ParamUnloadKbk);
        UnloadKbk_Chbx :=
          TCheckBox(Fm_ParamUnloadKbk.FindComponent('UnloadKbk_Chbx'));
        UnloadKcsr_Chbx :=
          TCheckBox(Fm_ParamUnloadKbk.FindComponent('UnloadKcsr_Chbx'));
        UnloadKvr_Chbx :=
          TCheckBox(Fm_ParamUnloadKbk.FindComponent('UnloadKvr_Chbx'));
        UnloadPodvid_Chbx :=
          TCheckBox(Fm_ParamUnloadKbk.FindComponent('UnloadPodvid_Chbx'));
        UnloadGlava_Chbx :=
          TCheckBox(Fm_ParamUnloadKbk.FindComponent('UnloadGlava_Chbx'));
        UnloadGrantInvestment_Chbx :=
          TCheckBox(Fm_ParamUnloadKbk.FindComponent('UnloadGrantInvestment_Chbx'));
        OkBtn := TBitBtn(Fm_ParamUnloadKbk.FindComponent('OkBtn'));
        CancelBtn := TBitBtn(Fm_ParamUnloadKbk.FindComponent('CancelBtn'));
        //инициализация параметров из конфига, в конфиг сохранять
        //выбранные значения не надо. см постановку Exchange #2144
        UnloadKbk_Chbx.Checked := UnloadKbk;
        UnloadKcsr_Chbx.Checked := UnloadKcsr;
        UnloadKvr_Chbx.Checked := UnloadKvr;
        UnloadPodvid_Chbx.Checked := UnloadSubDohIst;
        UnloadGlava_Chbx.Checked := UnloadGlava;
        UnloadGrantInvestment_Chbx.Checked := UnloadGrantInvestment;
        OkBtn.OnClick := @OkBtnOnClick;
        CancelBtn.OnClick := @CancelBtnOnClick;
        // fm_ModalResultOk - нажата кнопка "Выгрузить"
        fm_ModalResultOk := Fm_ParamUnloadKbk.ShowModal = MrOk;
      finally
        Fm_ParamUnloadKbk.Close;
        Fm_ParamUnloadKbk.Free;
      end;
    end;
    param_OutListKbk := Values['Выгружать КБК из списка'] = 'Да';
    if param_OutListKbk then
    begin
      Fm_KbkList := TFormCustomList.Create(Application);
      LoadForm(DirIni + 'Forms\Fm_KbkList.dfm', Fm_KbkList);
      CdsList := TClientDataSet(Fm_KbkList.FindComponent('CdsData'));
      DbGrid := TDBGridEh(Fm_KbkList.FindComponent('DbGrid'));
      EdtCdsId := TEdit.Create(Fm_KbkList);
      tlbFilterClear := TToolButton(Fm_KbkList.FindComponent('tlbFilterClear'));
      tlbFilter := TToolButton(Fm_KbkList.FindComponent('tlbFilter'));
      tlbFilterClear.OnClick := @tlbFilterClearOnClick;
      tlbFilter.OnClick := @tlbFilterOnClick;
      PanelFilter := TPanel(Fm_KbkList.FindComponent('PanelFilter'));
      edKesCode := TEdit(Fm_KbkList.FindComponent('edKesCode'));
      edKadmCode := TEdit(Fm_KbkList.FindComponent('edKadmCode'));
      edKesCode.OnChange := @edKesCodeOnChange;
      edKadmCode.OnChange := @edKadmCodeOnChange;
      RadioTypeKbk := TRadioGroup(Fm_KbkList.FindComponent('RadioTypeKbk'));
      RadioTypeKbk.OnClick := @RadioTypeKbkOnClick;
      spbKesCode := TSpeedButton(Fm_KbkList.FindComponent('spbKesCode'));
      spbKadmCode := TSpeedButton(Fm_KbkList.FindComponent('spbKadmCode'));
      spbKesCode.OnClick := @spbKesCodeOnClick;
      spbKadmCode.OnClick := @spbKadmCodeOnClick;
      Fm_KbkList.Edit := EdtCdsId;
      Fm_KbkList.SQLText := '';
      Fm_KbkList.OnHide := @Fm_KbkListOnHide;
      Fm_KbkList.Caption := 'Список выгружаемых кодов бюджетной классификации...';
      Fm_KbkList.Show;
      Fm_KbkList.Close;
    end;
  finally
    SL.Free;
  end;
  // форма сообщений об ошибках проверки данных
  InitializeMessageValid( 'Exp_FK_KBK_OLD', DirIni);
end; {End Initialize}

procedure OkBtnOnClick(Sender: TObject);
begin
  UnloadKbk := UnloadKbk_Chbx.Checked;
  UnloadKcsr := UnloadKcsr_Chbx.Checked;
  UnloadKvr := UnloadKvr_Chbx.Checked;
  UnloadSubDohIst := UnloadPodvid_Chbx.Checked;
  UnloadGlava := UnloadGlava_Chbx.Checked;
  UnloadGrantInvestment := UnloadGrantInvestment_Chbx.Checked;
  Fm_ParamUnloadKbk.ModalResult := MrOk;
end; {End OkBtnOnClick}

procedure CancelBtnOnClick(Sender: TObject);
begin
  Fm_ParamUnloadKbk.ModalResult := MrCancel;
end; {End CancelBtnOnClick}

procedure tlbFilterClearOnClick(Sender: TObject);
begin
  CdsList.Filter := '';
  RadioTypeKbk.ItemIndex := -1;
  EdKesCode.Text := '';
  EdKadmCode.Text := '';
  if DBGrid.Visible then
    DBGrid.SetFocus;
  DBGrid.SumList.Active := False;
  DBGrid.SumList.Active := True;
end; {End tlbFilterClearOnClick}

procedure tlbFilterOnClick(Sender: TObject);
begin
  PanelFilter.Visible := tlbFilter.Down;
  tlbFilter.Hint := Ifthen(PanelFilter.Visible, 'Скрыть панель фильтрации',
    'Показать панель фильтрации');
end; {End tlbFilterOnClick}

procedure spbKesCodeOnClick(Sender: TObject);
begin
  EdKesCode.Text := GetKbkForFilter('Kes');
end; {End spbKesCodeOnClick}

procedure spbKadmCodeOnClick(Sender: TObject);
begin
  EdKadmCode.Text := GetKbkForFilter('Kadm');
end; {End spbKadmCodeOnClick}

//возвращает строку с перечисленными через запятую КБК.
function GetKbkForFilter(TableName: String): String;
var
  Fm_FilterKbk: TFormCustomList;
  EdFilter: TEdit;
  tlbRefresh: TToolButton;
  CdsFilterData: TClientDataSet;
  DBGridFilter: TDBGridEh;
  procedure Fm_FilterKbkOnActivate(Sender: TObject);
  var
    FilterXml: Variant;
    sql: String;
    iRow: Integer;
  begin
    FilterXml := CreateOleObject('Microsoft.XmlDom');
    sql := 'Select K.Code, L.Caption, L.Description,' +
      ' L.Begin_Date, L.End_Date, L.Change_Date' +
      ' From ' + TableName + ' K' +
      ' Join ' + TableName + '_Lines L on K.Id = L.Master_Id' +
      ' Where K.Budget_Id = ? and (L.End_Date is null or L.End_Date >= ?)' +
      ' and L.Begin_Date <= ? and L.Unapproved = 0';
    Query.AddStr(BudgetId);
    Query.AddDate(Work_Date);
    Query.AddDate(Work_Date);
    FilterXml.LoadXml(Query.Run(sql));
    FilterXml := FilterXml.documentElement;
    //дописывание нулей впереди
    if Sender is TToolButton then
      DBGridFilter.SavePosition;
    CdsFilterData.DisableControls;
    DBGridFilter.Enabled := False;
    CdsFilterData.First;
    while not CdsFilterData.Eof do
      CdsFilterData.Delete;
    for iRow := 0 to FilterXml.childNodes.Length - 1 do
    begin
      FilterXml := FilterXml.childNodes.Item[iRow];
      CdsFilterData.Append;
      CdsFilterData.FieldByName('CODE').AsString := StringReplace(
          Format('%3s', [FilterXml.getAttribute('CODE')]), ' ', '0');
      CdsFilterData.FieldByName('CAPTION').AsString := IfThen(
        FilterXml.getAttribute('CAPTION') <> '',
          FilterXml.getAttribute('CAPTION'), '');
      CdsFilterData.FieldByName('DESCRIPTION').AsString := IfThen(
        FilterXml.getAttribute('DESCRIPTION') <> '',
          FilterXml.getAttribute('DESCRIPTION'), '');
      CdsFilterData.FieldByName('BEGIN_DATE').AsDateTime :=
        XmlToDateTime(FilterXml.getAttribute('BEGIN_DATE'));
      CdsFilterData.FieldByName('CHANGE_DATE').AsDateTime :=
        XmlToDateTime(FilterXml.getAttribute('CHANGE_DATE'));
      if (FilterXml.getAttribute('END_DATE') <> '') then
        CdsFilterData.FieldByName('END_DATE').AsDateTime :=
          XmlToDateTime(FilterXml.getAttribute('END_DATE'));
      CdsFilterData.Post;
      FilterXml := FilterXml.parentNode;
    end;
    CdsFilterData.First;
    DBGridFilter.Enabled := True;
    CdsFilterData.EnableControls;
    if Sender is TToolButton then
      DBGridFilter.RestorePosition;
  end;
  procedure Fm_FilterKbkOnHide(Sender: TObject);
  begin
    EdFilter.Text := DbGrid.Bookmark.CommaText;
  end;
begin
  Result := '';
  Fm_FilterKbk := TFormCustomList.Create(Application);
  EdFilter := TEdit.Create(Fm_FilterKbk);
  try
    LoadForm(DirIni + 'Forms\Fm_KbkList.dfm', Fm_FilterKbk);
    Fm_FilterKbk.Caption := 'Фильтр по бюджетной классификации';
    if UpperCase(TableName) = 'KES' then
    begin
      Fm_FilterKbk.Caption := Fm_FilterKbk.Caption + ': КОСГУ';
      Result := edKesCode.Text;
    end
    else begin
      Fm_FilterKbk.Caption := Fm_FilterKbk.Caption + ': Код главы';
      Result := edKadmCode.Text;
    end;
    Fm_FilterKbk.Edit := EdFilter;
    tlbRefresh := TToolButton(Fm_FilterKbk.FindComponent('tlbRefresh'));
    tlbRefresh.Visible := True;
    tlbRefresh.OnClick := @Fm_FilterKbkOnActivate;
    CdsFilterData := TClientDataSet(Fm_FilterKbk.FindComponent('CdsData'));
    DBGridFilter := TDBGridEh(Fm_FilterKbk.FindComponent('DBGrid'));
    DBGridFilter.FieldKey := CdsFilterData.FieldByName('Code');
    Fm_FilterKbk.OnActivate := @Fm_FilterKbkOnActivate;
    Fm_FilterKbk.OnHide := @Fm_FilterKbkOnHide;
    if (Fm_FilterKbk.ShowModal = MrOk) and (EdFilter.Text <> '') then
      Result := '''' + StringReplace(EdFilter.Text, ',', ''',''') + ''''
  finally
    EdFilter.Free;
    Fm_FilterKbk.Free;
  end;
end; {End GetKbkForFilter}

//метод для установления фильтров.
procedure setKbkFilter;
var
  PFilter, Filter: String;
begin
  try
    DBGrid.BookmarkUnCheckAll;
    CdsList.Filter := '';
    Filter := '';
    case RadioTypeKbk.ItemIndex of
      0: PFilter := 'Type_Kbk = 10';
      1: PFilter := 'Type_Kbk = 20';
      2: PFilter := 'Type_Kbk in (31, 32)';
    else
      PFilter := '';
    end;
    if edKesCode.Text <> '' then
    begin
      Filter := 'KesCode in (' + edKesCode.Text + ')';
      if edKadmCode.Text <> '' then
        Filter := Filter + ' and KadmCode in (' + edKadmCode.Text + ')';
    end
    else if edKadmCode.Text <> '' then
      Filter := 'KadmCode in (' + edKadmCode.Text + ')';
    if (PFilter <> '') and (Filter <> '') then
      Filter := Filter + ' and ' + PFilter
    else if PFilter <> '' then Filter := PFilter;
    CdsList.Filter := Filter;
  except
    MessageDlg('Ошибка при установлении фильтра. Количество данных фильтра' +
      ' превышает допустимое значение', mtError, mbOk, 0);
    CdsList.Filter := '';
    tlbFilterClearOnClick(nil);
  end;
  DBGrid.SumList.Active := False;
  DBGrid.SumList.Active := True;
end;

procedure edKesCodeOnChange(Sender: TObject);
begin
  setKbkFilter;
end; {End edKesCodeOnChange}

procedure edKadmCodeOnChange(Sender: TObject);
begin
  setKbkFilter;
end; {End edKadmCodeOnChange}

procedure RadioTypeKbkOnClick(Sender: TObject);
begin
  setKbkFilter;
end; {End RadioTypeKbkOnClick}

//получает выбранные КБК из Dataset в Xml. Структура Xml приближена к структуре
//Xml, получаемой при выборке КБК из базы
function GetSelectedKbk(CdsList: TClientDataSet; var CdsIdList: String): Variant;
var
  i: Integer;
  //делит список Id в передаваемой строке StrId на количество ValueCountId
  //Если StrId = 1,2,3,4 и ValueCountId = 3. После выполнения функции получим
  //Result = 1,2,3 и StrId = 4
  function DelimitStrIdByCount(var StrId: String; ValueCountId: Integer): String;
  const
    Delimiter = ','; //разделитель Id.
  var
    j, CountId: Integer;
  begin
    Result := '';
    CountId := 0;
    j := 1;
    while (j <= Length(StrId)) and (CountId < ValueCountId) do
    begin
      if StrId[j] = Delimiter then
        Inc(CountId);
      Inc(j);
    end;
    if CountId = ValueCountId then
    begin
      Result := Copy(StrId, 1, j - 2);
      Delete(StrId, 1, j - 1);
    end
    else begin
      Result := StrId;
      StrId := '';
    end;
  end;
begin
  Result := null;
  while CdsIdList <> '' do
  begin
    CdsList.Filter := 'CDSID in(' + DelimitStrIdByCount(CdsIdList, 2000) + ')';
    if CdsList.RecordCount <= 0 then
    begin
      CdsList.Filter := '';
      CdsIdList := '';
      Exit
    end
    else if VarIsNull(Result) then
    begin
      Result := CreateOleObject('Microsoft.XmlDom');
      Result.appendChild(Result.createElement('EXCHQUERY'));
      Result := Result.documentElement;
    end;
    CdsList.First;
    for i := 0 to CdsList.RecordCount - 1 do
    begin
      Result := Result.appendChild(Result.ownerDocument.createElement('ROW'));
      Result.setAttribute('CODE', CdsList.FieldByName('CODE').AsString);
      Result.setAttribute('CAPTION', CdsList.FieldByName('CAPTION').AsString);
      Result.setAttribute('DESCRIPTION',
        CdsList.FieldByName('DESCRIPTION').AsString);
      Result.setAttribute('BEGIN_DATE',
        DateTimeToXml(CdsList.FieldByName('BEGIN_DATE').AsDateTime));
      Result.setAttribute('CHANGE_DATE',
        DateTimeToXml(CdsList.FieldByName('CHANGE_DATE').AsDateTime));
      Result.setAttribute('END_DATE',
        IfThen(CdsList.FieldByName('END_DATE').AsString <> '',
          DateTimeToXml(CdsList.FieldByName('END_DATE').AsDateTime), ''));
      Result.setAttribute('TYPE_KBK', CdsList.FieldByName('TYPE_KBK').AsString);
      Result.setAttribute('LIMIT', CdsList.FieldByName('LIMIT').AsString);
      Result := Result.parentNode;
      CdsList.Next;
    end;
  end;
  CdsList.Filter := '';
  CdsIdList := '';
  Result := Result.ownerDocument;
end;

//добавляет данные отобранные КБК в Dataset
//Kbk20 - флаг 20-тизначного КБК (кодов доходов бюджета, кодов расходов и
//кодов источников финансирования дефицитов бюджетов)
procedure InsertDataToCds( CdsList: TClientDataSet;
                           var DBGrid: TDBGridEh;
                           Xml: Variant;
                           Kbk20: Boolean = False);
var
  i: Integer;
  s1,s2,s3: string;
begin
  CdsList.DisableControls;
  DBGrid.Enabled := False;
  CdsList.First;
  while not CdsList.Eof do
    CdsList.Delete;
  Xml := Xml.documentElement;
  for i := 0 to Xml.childNodes.Length - 1 do
  begin
    Xml := Xml.childNodes.Item[i];
    CdsList.Append;
    CdsList.FieldByName('CDSID').AsInteger := i;
    CdsList.FieldByName('CODE').AsString := Xml.getAttribute('CODE');
    CdsList.FieldByName('CAPTION').AsString := IfThen(
      Xml.getAttribute('CAPTION') <> '', Xml.getAttribute('CAPTION'), '');
    CdsList.FieldByName('DESCRIPTION').AsString := IfThen(
      Xml.getAttribute('DESCRIPTION') <> '', Xml.getAttribute('DESCRIPTION'), '');
    CdsList.FieldByName('BEGIN_DATE').AsDateTime :=
      XmlToDateTime(Xml.getAttribute('BEGIN_DATE'));
    CdsList.FieldByName('CHANGE_DATE').AsDateTime :=
      XmlToDateTime(Xml.getAttribute('CHANGE_DATE'));
    if (Xml.getAttribute('END_DATE') <> '') then
      CdsList.FieldByName('END_DATE').AsDateTime :=
        XmlToDateTime(Xml.getAttribute('END_DATE'));
    if not VarIsNull(Xml.getAttribute('TYPE_KBK')) then
      CdsList.FieldByName('TYPE_KBK').AsString := Xml.getAttribute('TYPE_KBK');
    if not VarIsNull(Xml.getAttribute('LIMIT')) then
      CdsList.FieldByName('LIMIT').AsString := Xml.getAttribute('LIMIT');
    if Kbk20 then
    begin
      CdsList.FieldByName('KADMCODE').AsString :=
        Copy(Xml.getAttribute('CODE'), 1, 3);
      CdsList.FieldByName('KESCODE').AsString :=
        Copy(Xml.getAttribute('CODE'), 18, 3);
    end;
    CdsList.Post;
    Xml := Xml.parentNode;
  end;
  CdsList.First;
  DBGrid.Enabled := True;
  CdsList.EnableControls;
end;

//todo подумать как переделать инициализацию формы без Show и Hide.
//Как вариант повесить формирование Dataset на OnActivate
{procedure Fm_KbkListOnActivate(Sender: TObject);
begin
  //Если кнопака фильтрации видна, то выгружаем 20-тизначный код. Фильтры только
  //в 20-тизначных кодах, учесть/переписать в случае изменения выгрузки в части
  //фильтров для других кодов
  if tlbFilter.Visible then
    InsertDataToCds(CdsList, DBGrid, XmlListCodeforCds.ownerDocument, True)
  else
    InsertDataToCds(CdsList, DBGrid, Kbk);
end;}

//перекрывает событие скрытия формы. Здесь обнуляем DbGrid.Bookmark, иначе
//он сохраняется при следующем открытии формы
procedure Fm_KbkListOnHide(Sender: TObject);
begin
  KbkIdList := DbGrid.Bookmark.CommaText;
  DbGrid.Bookmark.Clear;
end;

procedure Finalize(Xml: Variant);
begin
  
  // отсоединяем контролы прогресс/статус баров
  FinalizeProgressControl;
  if (Form <> NIL) then begin
    Form.Close;
    Form.Free;
  end;
  if (CacheFormatKbk <> NIL) then CacheFormatKbk.Free;
  if (EdtCdsId <> NIL) then EdtCdsId.Free;
  if (Fm_KbkList <> NIL) then Fm_KbkList.Free;
  FinalizeMessageValid;
  FinalizeDefault(Xml);
  FinalizeMain;
{
  ProgressBar.Position := 0;
  StatusBar.SimpleText := '';
  Form.Close;
  Form.Free;
  CacheFormatKbk.Free;
  if param_OutListKbk then
  begin
    EdtCdsId.Free;
    Fm_KbkList.Free;
  end;
  FinalizeDefault(Xml);}
end; {End Finalize}

begin
  Main( null);
end. {End Begin}
