uses '..\Version\CheckVersion';

var
  Form: TFormCustom;
  FormEst, FormTer: TFormCustomTree;
  FormKFSR, FormKCSR, FormKVR, FormKESR, FormKADMR,
  FormKDF, FormKDE, FormKDR: TFormKbk;
  FormKDFNull, FormKDENull, FormKDRNull: TFormKbk;
  FormKIF: TFormCustomList;
  ProgressBar: TProgressBar;
  dtDate: TDateTimeEh;
  edtDir, edtEst, EdtTer, EdtKFSR, EdtKCSR, EdtKVR, EdtKESR, EdtKADMR,
  edtKDF, edtKDE, edtKDR, edtKIF: TEdit;
  edtKDFNull, edtKDENull, edtKDRNull: TEdit;
  btnDir, btnEst, btnTer, btnKFSR, btnKCSR, btnKVR, btnKESR, btnKADMR,
  btnKDF, btnKDE, btnKDR, btnKIF: TSpeedButton;
  btnKDFNull, btnKDENull, btnKDRNull: TSpeedButton;
  cdsEst, cdsOrg, cdsTer, cdsOperType: TClientDataSet;
  FormExpAssignment, FormExpAssignmentChange: TFormCustomList;
  edtExpAssignment, edtExpAssignmentChange: TEdit;
  btnExpAssignment, btnExpAssignmentChange: TSpeedButton;
  rgbExec: TRadioGroup;
  FileLog, FileInfo: String;
  FDebuger, FFormatXML: Boolean;
  FAzkIsLogin: Boolean;
  cbxWoCommit: TComboBox;
  // exchange #2465
  // форма кода цели с контролами
  vFormPurpFulGr: TFormKbk;
  vBtnPurpFulGr: TSpeedButton;
  vEdtPurpFulGr: TEdit;

const
  FFileVer = '1.3';
  FFileGuid = '{23A545C5-890D-49DE-AEE5-822C6B436ACF}';


procedure Main(Xml: Variant);
begin
  CheckWorkAppVersion;
  with Xml.documentElement do
  if getAttribute('TESTED') = 'True' then
  begin
    setAttribute('TESTED', 'False');
    Xml.save('C:\Temp\PlanExpenseExport.Xml');
    ShowMessage('Тестовый пример приготовлен: C:\Temp\PlanExpenseExport.Xml');
    Exit;
  end;
  FAzkIsLogin := AzkIsLogin;
  if not AzkIsLogin then
    if not AzkLogin then
      Exit;
  try
    try
      initialization(Xml);
      if FDebuger then
      begin
        Form.Show;
        repeat
          Application.handleMessage;
        until(not Form.Visible);
      end
      else
        Form.ShowModal;
    except
      WriteLog(LastException.Message);
      raise(LastException.Message);
    end;
  finally
    finalization;
    if not FAzkIsLogin then
      AzkLogout;
  end;
end; {End Main}

procedure initialization(Xml: Variant);
var
  IniPath: String;
begin
  IniPath := ExtractFilePath(Xml.documentElement.getAttribute('INI_FILE'));
//  IniPath := '.\';
  FileLog := IniPath + 'System_PlanIncomExport.Log';
  FileInfo := IniPath + 'User_PlanIncomExport.Log';

  Form := TFormCustom.Create(Application);
  Form.LoadDfm(IniPath + 'Fm_PlanExpenseExport.dfm');
  Form.Name := 'FmPlanExpenseExport';
  Form.actExecute.OnExecute := @actExecuteExecute;

  TLabel(Form.FindComponent('lblVersion')).Caption := 'Версия формата: ' + FFileVer;;
  ProgressBar := TProgressBar(Form.FindComponent('ProgressBar'));
  // Отчётная дата
  dtDate := TDateTimeEh(Form.FindComponent('dtDate'));
  dtDate.Date := Work_Date;
  rgbExec := TRadioGroup(Form.FindComponent('rgbExec'));
  if dtDate.Date >= StrToDate('01.01.2006') then
    rgbExec.ItemIndex := 1;
  // Каталог экспорта
  edtDir := TEdit(Form.FindComponent('edtDir'));
  btnDir := TSpeedButton(Form.FindComponent('btnDir'));
  btnDir.OnClick := @OnbtnDirClick;
  // Смета
  FormEst := TFormCustomTree.Create(Form);
  FormEst.LoadDfm(IniPath + '..\Forms\Fm_Estimate.dfm');
  FormEst.SQLText := 'Select E.Id, E.Parent_Id, E.Caption || '' ('' || K.Caption || '')'' Caption' +
    ' From Estimate E Left Join Estkind K On K.Id = E.EstKind_Id' +
    ' Where E.Budget_Id = ' + Budget_Id + ' Order By E.Caption';
  FormEst.EditResFieldName := 'Caption';
  edtEst := TEdit(Form.FindComponent('edtEst'));
  FormEst.Edit := edtEst;
  btnEst := TSpeedButton(Form.FindComponent('btnEst'));
  FormEst.SpeedButton := btnEst;
  // Территория
  FormTer := TFormCustomTree.Create(Form);
  FormTer.LoadDfm(IniPath + '..\Forms\Fm_Territory.dfm');

  // exchange #2715
  // поправлен запрос при переходе на символьные БК
  FormTer.SQLText :=
    ' Select Cast(Null As VarChar(15)) Id, Cast('#39'.'#39'  As VarChar(15)) Parent_Id,'
   +' Cast(''Территории'' As VarChar(255)) Caption'
   +' From Territory T Where T.Id = 0 Union' +
    ' Select cast(T.Id As VarChar(15)), cast(T.Parent_Id As VarChar(15)),'
   +' Cast(T.Caption As VarChar(255)) Caption From Territory T';

  FormTer.EditResFieldName := 'Caption';

  // exchange #2715
  // изменен код корневого узла и шаблон отображения кодов на дереве
  FormTer.ValueRoot := '.';
  FormTer.FilterFormatStr := #39'%s'#39;

  FormTer.RootSelect := False;
  edtTer := TEdit(Form.FindComponent('edtTer'));
  FormTer.Edit := edtTer;
  btnTer := TSpeedButton(Form.FindComponent('btnTer'));
  FormTer.SpeedButton := btnTer;
  // КФСР
  FormKFSR := TFormKbk.Create(Form);
  FormKFSR.Kbk_Code := KFSR_CODE;
  edtKFSR := TEdit(Form.FindComponent('edtKFSR'));
  FormKFSR.Edit := edtKFSR;
  btnKFSR := TSpeedButton(Form.FindComponent('btnKFSR'));
  FormKFSR.SpeedButton := btnKFSR;
  // КЦСР
  FormKCSR := TFormKbk.Create(Form);
  FormKCSR.Kbk_Code := KCSR_CODE;
  edtKCSR := TEdit(Form.FindComponent('edtKCSR'));
  FormKCSR.Edit := edtKCSR;
  btnKCSR := TSpeedButton(Form.FindComponent('btnKCSR'));
  FormKCSR.SpeedButton := btnKCSR;
  // КВР
  FormKVR := TFormKbk.Create(Form);
  FormKVR.Kbk_Code := KVR_CODE;
  edtKVR := TEdit(Form.FindComponent('edtKVR'));
  FormKVR.Edit := edtKVR;
  btnKVR := TSpeedButton(Form.FindComponent('btnKVR'));
  FormKVR.SpeedButton := btnKVR;
  // КЭС
  FormKESR := TFormKbk.Create(Form);
  FormKESR.Kbk_Code := KESR_CODE;
  edtKESR := TEdit(Form.FindComponent('edtKESR'));
  FormKESR.Edit := edtKESR;
  btnKESR := TSpeedButton(Form.FindComponent('btnKESR'));
  FormKESR.SpeedButton := btnKESR;
  // КВСР
  FormKADMR := TFormKbk.Create(Form);
  FormKADMR.Kbk_Code := KADMR_CODE;
  edtKADMR := TEdit(Form.FindComponent('edtKADMR'));
  FormKADMR.Edit := edtKADMR;
  btnKADMR := TSpeedButton(Form.FindComponent('btnKADMR'));
  FormKADMR.SpeedButton := btnKADMR;
  // Доп.ФК
  FormKDF := TFormKbk.Create(Form);
  FormKDF.Kbk_Code := KDF_CODE;
  FormKDF.Name := FormKDF.Name + '_Filtr_' + Form.Name;
  edtKDF := TEdit(Form.FindComponent('edtKDF'));
  FormKDF.Edit := edtKDF;
  btnKDF := TSpeedButton(Form.FindComponent('btnKDF'));
  FormKDF.SpeedButton := btnKDF;
  // Доп.ЭК
  FormKDE := TFormKbk.Create(Form);
  FormKDE.Kbk_Code := KDE_CODE;
  FormKDE.Name := FormKDE.Name + '_Filtr_' + Form.Name;
  edtKDE := TEdit(Form.FindComponent('edtKDE'));
  FormKDE.Edit := edtKDE;
  btnKDE := TSpeedButton(Form.FindComponent('btnKDE'));
  FormKDE.SpeedButton := btnKDE;
  // Доп.КР
  FormKDR := TFormKbk.Create(Form);
  FormKDR.Kbk_Code := KDR_CODE;
  FormKDR.Name := FormKDR.Name + '_Filtr_' + Form.Name;
  edtKDR := TEdit(Form.FindComponent('edtKDR'));
  FormKDR.Edit := edtKDR;
  btnKDR := TSpeedButton(Form.FindComponent('btnKDR'));
  FormKDR.SpeedButton := btnKDR;
  // КИФ
  FormKIF := TFormCustomList.Create(Form);
  FormKIF.LoadDfm(IniPath + '..\Forms\Fm_Kif.dfm');
  FormKIF.SQLText := 'Select F.Id, F.Caption From FinSource F';
  edtKIF := TEdit(Form.FindComponent('edtKIF'));
  FormKIF.Edit := edtKIF;
  btnKIF := TSpeedButton(Form.FindComponent('btnKIF'));
  FormKIF.SpeedButton := btnKIF;

  // exchange #2465
  // код цели
  vFormPurpFulGr:= TFormKbk.Create( Form);
  // это поле определяет название выбранных (bookmark) кодов целей в таблице.
  // id храняться в vEdtPurpFulGr.hint, а список кодов (caption)
  // в vEdtPurpFulGr.text.
  // не забываем, чтобы сохранились параметры этих контролов при закрытии
  // формы, нужно открыть форму в delphi и дописать сохраняемые свойства
  // в контроле TPropertyNamesEh (grbParams/grbFiltr/edtPurposefulgrant свойства
  // text и hint). так же и контрол btnPurposefulgrant - в свойстве hint
  // хранится ID записи курсора в таблице.
  // версия АЦК-exchange должна быть не ниже
  vFormPurpFulGr.EditResFieldName := 'Caption';
  vFormPurpFulGr.Columns := 'CAPTION|Код субсидии'#13#10'DESCRIPTION|Наименование';
  vFormPurpFulGr.Kbk_Code := PURPFULGR_CODE;
//  vFormPurpFulGr.Name := vFormPurpFulGr.Name + '_Filtr_' + vFormPurpFulGr.Name;
  vEdtPurpFulGr := TEdit(Form.FindComponent('edtPurposefulgrant'));
  vFormPurpFulGr.Edit := vEdtPurpFulGr;
  vBtnPurpFulGr := TSpeedButton(Form.FindComponent('btnPurposefulgrant'));
  vFormPurpFulGr.SpeedButton := vBtnPurpFulGr;

  // Доп.ФК для обнуления
  FormKDFNull := TFormKbk.Create(Form);
  FormKDFNull.Kbk_Code := KDF_CODE;
  FormKDFNull.Name := FormKDFNull.Name + '_Null_' + Form.Name;
  edtKDFNull := TEdit(Form.FindComponent('edtKDFNull'));
  FormKDFNull.Edit := edtKDFNull;
  btnKDFNull := TSpeedButton(Form.FindComponent('btnKDFNull'));
  FormKDFNull.SpeedButton := btnKDFNull;
  // Доп.ЭК для обнуления
  FormKDENull := TFormKbk.Create(Form);
  FormKDENull.Kbk_Code := KDE_CODE;
  FormKDENull.Name := FormKDENull.Name + '_Null_' + Form.Name;
  edtKDENull := TEdit(Form.FindComponent('edtKDENull'));
  FormKDENull.Edit := edtKDENull;
  btnKDENull := TSpeedButton(Form.FindComponent('btnKDENull'));
  FormKDENull.SpeedButton := btnKDENull;
  // Доп.КР для обнуления
  FormKDRNull := TFormKbk.Create(Form);
  FormKDRNull.Kbk_Code := KDR_CODE;
  FormKDRNull.Name := FormKDRNull.Name + '_Null_' + Form.Name;
  edtKDRNull := TEdit(Form.FindComponent('edtKDRNull'));
  FormKDRNull.Edit := edtKDRNull;
  btnKDRNull := TSpeedButton(Form.FindComponent('btnKDRNull'));
  FormKDRNull.SpeedButton := btnKDRNull;
  
  cbxWoCommit := TComboBox(Form.FindComponent('cbxWoCommit'));

  FormExpAssignment := TFormCustomList.Create(Form);
  FormExpAssignment.LoadDfm(IniPath + '..\Forms\Fm_OperType.dfm');
  FormExpAssignment.SQLText :=
 ' select ' +
 '   o.id, o.caption ' +
 ' from ' +
 '   opertype o left join classoper c on (c.opertype_id = O.Id) ' +
 ' where ' +
 '   c.documentclass_id in (127) or o.id = 0 ';
  FormExpAssignment.EditResFieldName := 'Caption';
  edtExpAssignment := TEdit(Form.FindComponent('edtExpAssignment'));
  FormExpAssignment.Edit := edtExpAssignment;
  btnExpAssignment := TSpeedButton(Form.FindComponent('btnExpAssignment'));
  FormExpAssignment.SpeedButton := btnExpAssignment;
  
  FormExpAssignmentChange := TFormCustomList.Create(Form);
  FormExpAssignmentChange.LoadDfm(IniPath + '..\Forms\Fm_OperType.dfm');
  FormExpAssignmentChange.SQLText :=
 ' select ' +
 '   o.id, o.caption ' +
 ' from ' +
 '   opertype o left join classoper c on (c.opertype_id = O.Id) ' +
 ' where ' +
 '   c.documentclass_id in (128) or o.id = 0 ';
  FormExpAssignmentChange.EditResFieldName := 'Caption';
  edtExpAssignmentChange := TEdit(Form.FindComponent('edtExpAssignmentChange'));
  FormExpAssignmentChange.Edit := edtExpAssignmentChange;
  btnExpAssignmentChange := TSpeedButton(Form.FindComponent('btnExpAssignmentChange'));
  FormExpAssignmentChange.SpeedButton := btnExpAssignmentChange;

  cdsEst := TClientDataSet(Form.FindComponent('cdsEst'));
  cdsOrg := TClientDataSet(Form.FindComponent('cdsOrg'));
  cdsTer := TClientDataSet(Form.FindComponent('cdsTer'));
  cdsOperType := TClientDataSet(Form.FindComponent('cdsOperType'));
  with tStringList.Create do
  try
    CommaText := Xml.documentElement.getAttribute('CONFIG');
    FFormatXML := Trim(Values['Форматировать XML']) = 'Да';
  finally
    Free;
  end;
end; {End initialization}

procedure finalization;
begin
  Form.Free;
end; {End finalization}

procedure OnbtnDirClick(Sender: TObject);
begin
  ChooseFolder('Укажите каталог экспорта', edtDir.Text);
end; {End OnbtnDirClick}

procedure WriteLog(Message: String);
begin
  if FileLog <> '' then
    WriteLogFile(FileLog, Message);
end; {End WriteLog}

procedure WriteInfo(Message: String);
begin
  WriteLogFile(FileInfo, Message);
  WriteLogFile(FileLog, Message);
end; {End WriteInfo}

procedure actExecuteExecute(Sender: TObject);
var
  i: Integer;
  ResFile: String;
  KDFNull, KDENull, KDRNull: TStringList;
  Xml, ResXml, Node: Variant;
begin
  if Trim(edtDir.Text) = '' then
  begin
    MessageDlg('Не указан каталог выгрузки', mtError, mbOk, 0);
    Exit;
  end;
  ResFile := StringReplace(edtDir.Text + '\', '\\', '\');
  if not DirectoryExists(ResFile) then
    raise('Отсутствует каталог: ' + ResFile);
  ResFile := GetUniqueFileName(ResFile + 'PlanExpenseExport.xml');
  Xml := CreateOleObject('Microsoft.XmlDom');
  WriteLog(' ====== НАЧАЛО ЭКСПОРТА ======');
  KDFNull := TStringList;
  KDENull := TStringList;
  KDRNull := TStringList;
  SetAppDisable;
  try
    KDFNull.CommaText := edtKDFNull.Hint;
    KDENull.CommaText := edtKDENull.Hint;
    KDRNull.CommaText := edtKDRNull.Hint;
    try
    CdsQuery(cdsEst, 'Select E.Id, E.Caption, E.FinSource_Id, E.EstKind_Id, K.Caption EstKind_Caption' +
      ' From Estimate E Left Join Estkind K On K.Id = E.EstKind_Id Where E.Budget_Id = ' + Budget_Id);
    CdsQuery(cdsOrg, 'Select O.Id, O.Caption, O.Description, O.TaxCode, O.Kpp, O.Okato From Org O');
    CdsQuery(cdsTer, 'Select T.Id, T.Code, T.Okato, T.Caption From Territory T');
    CdsQuery(cdsOperType, 'Select O.Id, O.Caption From OperType O');
    Xml := Xml.appendChild(Xml.createElement('EXCHEXPENSEDATA'));
    Xml.setAttribute('action', 'planexport');
    //Xml.setAttribute('BEGIN_DATE', FormatDateTime('yyyy-01-01', dtDate.Date));
    Xml.setAttribute('END_DATE', FormatDateTime('yyyy-mm-dd', dtDate.Date));
    Xml.setAttribute('EXEC_TYPE', rgbExec.ItemIndex);
    if edtEst.Hint <> '' then Xml.setAttribute('ESTIMATE_ID', edtEst.Hint);
    if edtTer.Hint <> '' then Xml.setAttribute('TERRITORY_ID', edtTer.Hint);
    if edtKFSR.Hint <> '' then Xml.setAttribute('KFSR_CODE', edtKFSR.Text);
    if edtKCSR.Hint <> '' then Xml.setAttribute('KCSR_CODE', edtKCSR.Text);
    if edtKVR.Hint <> '' then Xml.setAttribute('KVR_CODE', edtKVR.Text);
    if edtKADMR.Hint <> '' then Xml.setAttribute('KADMR_CODE', edtKADMR.Text);
    if edtKESR.Hint <> '' then Xml.setAttribute('KESR_CODE', edtKESR.Text);
    if edtKDF.Hint <> '' then Xml.setAttribute('KDF_CODE', edtKDF.Text);
    if edtKDE.Hint <> '' then Xml.setAttribute('KDE_CODE', edtKDE.Text);
    if edtKDR.Hint <> '' then Xml.setAttribute('KDR_CODE', edtKDR.Text);
    if edtKIF.Hint <> '' then Xml.setAttribute('KIF_ID', edtKIF.Text);

    // exchange #2465
    // добавлено поле кода цели в отчетный сервер EXCHEXPENSEDATA
    // тут нужно передавать список идентификаторов, а он лежит в свойстве Hint!
    if vEdtPurpFulGr.Hint <> ''
      then Xml.setAttribute('PURPOSEFULGRANT_ID', vEdtPurpFulGr.Hint);

    Xml.setAttribute('OPERPLAN127', edtExpAssignment.Hint);
    Xml.setAttribute('OPERUPDATE128', edtExpAssignmentChange.Hint);
    Xml.setAttribute('WOCOMMITCHANGES', IfThen(cbxWoCommit.Text = '', 'WOCOMMITCHANGES_ALL',
      IfThen(cbxWoCommit.Text = 'Да', 'WOCOMMITCHANGES_ON', 'WOCOMMITCHANGES_OFF')));

    Xml := Xml.ownerDocument;
    Form.SimpleText := 'Запрос к серверу приложений ...';
    WriteLog(Form.SimpleText); WriteLog(Trim(Xml.Xml));
    Xml.loadXml(ExecXml(Xml.xml));
    Xml := Xml.documentElement.childNodes;
    ProgressBar.Max := Xml.length;
    if Xml.length = 0 then
    begin
      MessageDlg('Нет данных по условиям', mtInformation, mbOK, 0);
      WriteLog('Нет данных по условиям ...');
      Exit;
    end;
    Form.SimpleText := 'Формирование файла экспорта ...';
    WriteLog(Form.SimpleText);
    ResXml := CreateOleObject('Microsoft.XmlDom');
    ResXml := ResXml.appendChild(ResXml.createElement('PLANEXPENSEEXPORT'));
    ResXml.setAttribute('FINYEAR', FormatDateTime('yyyy', dtDate.Date));
    ResXml.setAttribute('FILEDATE', FormatDateTime('yyyy-mm-dd', dtDate.Date));
    ResXml.setAttribute('FILEVER', FFileVer);
    ResXml.setAttribute('FILEGUID', FFileGuid);
    for i := 0 to Xml.length - 1 do
    begin
      Node := Xml.item[i];
      ResXml := ResXml.appendChild(ResXml.parentNode.createElement('PLANEXPENSE'));
      ResXml := ResXml.appendChild(ResXml.parentNode.parentNode.createElement('ESTIMATE'));
      ResXml.setAttribute('ID', Node.getAttribute('ESTIMATE_ID'));
      if cdsEst.Locate('Id', Node.getAttribute('ESTIMATE_ID'), nil) then
      begin
        ResXml.setAttribute('CAPTION', cdsEst.FieldByName('Caption').AsString);
        ResXml.setAttribute('KIF_ID', cdsEst.FieldByName('FinSource_Id').AsString);
        ResXml.setAttribute('ESTKIND_ID', cdsEst.FieldByName('EstKind_Id').AsString);
        ResXml.setAttribute('ESTKIND_CAPTION', cdsEst.FieldByName('EstKind_Caption').AsString);
      end;
      ResXml := ResXml.parentNode;
      ResXml := ResXml.appendChild(ResXml.parentNode.parentNode.createElement('ORG'));
      ResXml.setAttribute('ID', Node.getAttribute('ORG_ID'));
      if cdsOrg.Locate('Id', Node.getAttribute('ORG_ID'), nil) then
      begin
        ResXml.setAttribute('CAPTION', cdsOrg.FieldByName('Caption').AsString);
        ResXml.setAttribute('DESCRIPTION', cdsOrg.FieldByName('Description').AsString);
        ResXml.setAttribute('TAXCODE', cdsOrg.FieldByName('TaxCode').AsString);
        ResXml.setAttribute('KPP', cdsOrg.FieldByName('Kpp').AsString);
        ResXml.setAttribute('OKATO', cdsOrg.FieldByName('Okato').AsString);
      end;
      ResXml := ResXml.parentNode;
      ResXml := ResXml.appendChild(ResXml.parentNode.parentNode.createElement('RECIPIENT'));
      ResXml.setAttribute('ID', Node.getAttribute('RECIPIENT_ID'));
      if cdsOrg.Locate('Id', Node.getAttribute('RECIPIENT_ID'), nil) then
      begin
        ResXml.setAttribute('CAPTION', cdsOrg.FieldByName('Caption').AsString);
        ResXml.setAttribute('DESCRIPTION', cdsOrg.FieldByName('Description').AsString);
        ResXml.setAttribute('TAXCODE', cdsOrg.FieldByName('TaxCode').AsString);
        ResXml.setAttribute('KPP', cdsOrg.FieldByName('Kpp').AsString);
        ResXml.setAttribute('OKATO', cdsOrg.FieldByName('Okato').AsString);
      end;
      ResXml := ResXml.parentNode;
      ResXml := ResXml.appendChild(ResXml.parentNode.parentNode.createElement('TERRITORY'));
      ResXml.setAttribute('ID', Node.getAttribute('TERRITORY_ID'));
      if cdsTer.Locate('Id', Node.getAttribute('TERRITORY_ID'), nil) then
      begin
        ResXml.setAttribute('CODE', cdsTer.FieldByName('Code').AsString);
        ResXml.setAttribute('OKATO', cdsTer.FieldByName('Okato').AsString);
        ResXml.setAttribute('CAPTION', cdsTer.FieldByName('Caption').AsString);
      end;
      ResXml := ResXml.parentNode;
      ResXml := ResXml.appendChild(ResXml.parentNode.parentNode.createElement('OPERTYPE'));
      ResXml.setAttribute('ID', Node.getAttribute('OPERTYPE_ID'));
      if cdsOperType.Locate('Id', Node.getAttribute('OPERTYPE_ID'), nil) then
        ResXml.setAttribute('CAPTION', cdsOperType.FieldByName('Caption').AsString);
      ResXml := ResXml.parentNode;
      ResXml := ResXml.appendChild(ResXml.parentNode.parentNode.createElement('KBK'));
      ResXml.setAttribute('KFSR_CODE', Node.getAttribute('KFSR_CODE'));
      ResXml.setAttribute('KCSR_CODE', Node.getAttribute('KCSR_CODE'));
      ResXml.setAttribute('KVR_CODE', Node.getAttribute('KVR_CODE'));
      ResXml.setAttribute('KADMR_CODE', Node.getAttribute('KADMR_CODE'));
      ResXml.setAttribute('KESR_CODE', Node.getAttribute('KESR_CODE'));
      if KDFNull.IndexOf(Node.getAttribute('KDF_CODE')) < 0 then
        ResXml.setAttribute('KDF_CODE', Node.getAttribute('KDF_CODE'))
      else
        ResXml.setAttribute('KDF_CODE', 0);
      if KDENull.IndexOf(Node.getAttribute('KDE_CODE')) < 0 then
        ResXml.setAttribute('KDE_CODE', Node.getAttribute('KDE_CODE'))
      else
        ResXml.setAttribute('KDE_CODE', 0);
      if KDRNull.IndexOf(Node.getAttribute('KDR_CODE')) < 0 then
        ResXml.setAttribute('KDR_CODE', Node.getAttribute('KDR_CODE'))
      else
        ResXml.setAttribute('KDR_CODE', 0);
      ResXml.setAttribute('KIF_ID', Node.getAttribute('KIF_ID'));

      // exchange #2465
      // добавлено поле кода цели. на всякий случай, если версия отчетов
      // не совпадет с нужной, это поле не будет заполнено, но сбоя быть
      // не должно.
      ResXml.setAttribute( 'PURPOSEFULGRANT_ID',
                            VarToStr( Node.getAttribute('PURPOSEFULGRANT_ID')));

      ResXml := ResXml.parentNode;
      ResXml := ResXml.appendChild(ResXml.parentNode.parentNode.createElement('AMOUNT'));
      ResXml.setAttribute('PLANYEAR1', Node.getAttribute('PLANYEAR1'));
      ResXml.setAttribute('PLANYEAR2', Node.getAttribute('PLANYEAR2'));
      ResXml.setAttribute('PLANYEAR3', Node.getAttribute('PLANYEAR3'));
      ResXml.setAttribute('PLANONDATE', Node.getAttribute('PLANONDATE'));
      ResXml.setAttribute('UPDATEYEAR1', Node.getAttribute('UPDATEYEAR1'));
      ResXml.setAttribute('UPDATEYEAR2', Node.getAttribute('UPDATEYEAR2'));
      ResXml.setAttribute('UPDATEYEAR3', Node.getAttribute('UPDATEYEAR3'));
      ResXml.setAttribute('UPDATEONDATE', Node.getAttribute('UPDATEONDATE'));
      ResXml.setAttribute('EXEC', Node.getAttribute('EXEC'));
      ResXml := ResXml.parentNode;
      ResXml := ResXml.parentNode;
      ProgressBar.Position := i + 1;
    end;
    ResXml := ResXml.parentNode.documentElement;
    Xml := CreateOleObject('Microsoft.XmlDom');
    Xml.LoadXml(RunQuery('Select B.Caption Budget_Caption, B.Org_id' +
      ', B.Caption Org_Caption , O.Description Org_Description, b.territory_id ' +
      ' From Budget B Left Join Org O On O.Id = B.Org_Id Where B.Id = ' + Budget_Id));
    Xml := Xml.documentElement.ChildNodes.item[0];
    ResXml.setAttribute('BUDGET_ID', Budget_Id);
    ResXml.setAttribute('BUDGET_CAPTION', Xml.getAttribute('BUDGET_CAPTION'));
    ResXml.setAttribute('ORG_ID', Xml.getAttribute('ORG_ID'));
    ResXml.setAttribute('ORG_CAPTION', Xml.getAttribute('ORG_CAPTION'));
    ResXml.setAttribute('ORG_DESCRIPTION', Xml.getAttribute('ORG_DESCRIPTION'));
    ResXml.setAttribute('TERRITORY_ID', Xml.getAttribute('TERRITORY_ID'));

    ResXml := ResXml.parentNode;
    Form.SimpleText := 'Сохранение файла экспорта ...';
    WriteLog(Form.SimpleText);
    if FFormatXML then
      ResXml.loadXml('<?xml version="1.0" encoding="Windows-1251"?>' +
        FormatXmlData(ResXml.xml));
    ResXml.save(ResFile);
    WriteLog('Файл экспорта: ' + ResFile);
    WriteLog('Экспортированно: ' + IntToStr(ProgressBar.Max) + ' строк');
    MessageDlg('Файл экспорта: ' + ResFile, mtInformation, mbOK, 0);
    except
      WriteLog(LastException.Message);
      raise(LastException.Message);
    end;
  finally
    KDFNull.Free;
    KDENull.Free;
    KDRNull.Free;
    WriteLog(' ==== ЗАВЕРШЕНИЕ ЭКСПОРТА ====');
    Form.SimpleText := '';
    ProgressBar.Position := 0;
    SetAppEnable;
  end;
end; {End actExecuteExecute}

var
  Xml: Variant;

begin
  FAzkIsLogin := AzkIsLogin;
  FDebuger := True;
  Xml := CreateOleObject('Microsoft.XmlDom');
  if not FileExists('C:\Temp\PlanExpenseExport.Xml') then
  begin
    ShowMessage('Не найден тестовый пример: C:\Temp\PlanExpenseExport.Xml');
    Exit;
  end;
  if not Xml.Load('C:\Temp\PlanExpenseExport.Xml') then
  begin
    ShowMessage('Ошибка при загрузке: C:\Temp\PlanExpenseExport.Xml');
    Exit;
  end;
  if not AzkIsLogin then
    if not AzkLogin then
      Exit;
  try
    Main(Xml);
  finally
    if not FAzkIsLogin then
      AzkLogout;
  end;
end. {End Start}