{ exchange #2994
  переработка скрипта:
  переделано сохранение/восст. параметров уровня бюджетов и счета на форме.
  параметры сохр/восст из скрытого контрола edParams на форме.
  доработаны запросы - замена на параметрические.
  добавлена отладочная информация.}
uses
  'UfebsMakeFileName',
  'UfebsConst',
  'WorkUfebsVersion.inc',
  'WorkAppVersion.inc',
  'UfebsVersionInc.inc',
  'UfebsLog',
  'Un_Log',
  'Un_Debug',
  'UfebsConst',
  'Un_Progress';

var
  Form: TForm;
  ButtonExecute, ButtonExit: TButton;
  DateED, BeginTime, EndTime: TDateTimeEh;
  CodeQuery, BudgLevel, Account: TComboBox;
  CheckBox: TCheckBox;
//  PropStorageEh: TPropStorageEh;
  InputXml, BudgLevelXml: Variant;
  // exchange #2994 - вид заполнения БИК
  cbBIC: TCheckBox;
  edBIC: TEdit;
  // список ассоциации: счет=бик в заполненном списке счетов
  vLinkBICwithACCOUNT: TStringList;
  // в этом контроле будем сохранять параметры выбора уровня бюджета и счет,
  // вместо сохраняния itemindex этих контролов. сохранять itemindex
  // безсмысленно если бд меняется.
  edParams: TEdit;
  vChoiceBudgetLevel: string;
  VOldParams: string;

procedure Main(Xml: Variant);
var
  xPropStorageEh: TPropStorageEh;
begin

  if CompareVersionEx(AppVersion, WorkAppVersion) < 0 then
    raise('Скрипты работают с AzkEchange.Exe начиная с версии: ' + WorkAppVersion +
      ''#13#10'Текущая версия AzkEchange.Exe: ' + AppVersion);
  InputXml := Xml;
  with Xml.documentElement do
  if getAttribute('TESTED') = 'True' then
  begin
    setAttribute('TESTED', 'False');
    Xml.save('C:\Temp\UfebsED210.Xml');
    ShowMessage('Тестовый пример приготовлен: C:\Temp\UfebsED210.Xml');
    Exit;
  end;
  try
    // exchange #2994
    // список ассоциаций: счек-бик
    vLinkBICwithACCOUNT:= TStringList.Create;

    Form := TForm.Create(Application);
    LoadForm(ExtractFilePath(Xml.documentElement.getAttribute('INI_FILE')) +
      '\Form\Fm_UfebsED210.dfm', Form);
    ButtonExecute := TButton(Form.FindComponent('ButtonExecute'));
    ButtonExecute.OnClick := @OnButtonExecuteClick;
    ButtonExit := TButton(Form.FindComponent('ButtonExit'));
    ButtonExit.OnClick := @OnButtonExitClick;
    DateED := TDateTimeEh(Form.FindComponent('DateED'));
    DateED.Date := Now;
    BeginTime := TDateTimeEh(Form.FindComponent('BeginTime'));
    EndTime := TDateTimeEh(Form.FindComponent('EndTime'));
    BeginTime.Time := StrToTime('07:00:00');
    EndTime.Time := Now;
    CodeQuery := TComboBox(Form.FindComponent('CodeQuery'));
    CodeQuery.OnChange := @OnCodeQueryChangeOnCheckCheckBox;

    // сортировку списка необходимо отключить !
    BudgLevel := TComboBox(Form.FindComponent('BudgLevel'));
    BudgLevel.Sorted := FALSE;
    BudgLevel.OnChange := @OnBudgLevelChange;

    // exchange #2994 - контрол хранения параметров
    edParams:= TEdit( Form.FindComponent('edParams'));

    // exchange #2994 - вид заполнения БИК
    // сортировку списка необходимо отключить !
    // это связано с заполнением ассоциации: счет-бик
    Account := TComboBox(Form.FindComponent('Account'));
    Account.Sorted := FALSE;

    CheckBox := TCheckBox(Form.FindComponent('CheckBox'));
    CheckBox.OnClick := @OnCodeQueryChangeOnCheckCheckBox;

    // exchange #2994 - вид заполнения БИК
    cbBIC := TCheckBox(Form.FindComponent('cbBIC'));
    edBIC := TEdit(Form.FindComponent('edBIC'));

    // событие выбора счета
    // только после получения контрола edBIC
    Account.OnClick := @OnChoiceAccount;

    // восстанавливаем параметры настроек в контролах
    xPropStorageEh := TPropStorageEh(Form.FindComponent('PropStorageEh'));
    xPropStorageEh.LoadProperties;
    vOldParams := edParams.Text;

    // обязательно вешать событие на открытие формы!
    // иначе никакие контролы привести в нужное состояние не получится.
    fORM.OnShow := @OnFormShow;

    // загрузка данных из БД до отображения окна
    // это дает то будет загрузка данных из бд с инициализацией контролов
    // на форме, а при открытии формы - инициализация контролов
    // из сохраненных настроек.
    LoadBudgLevel;
    LoadListAccount;
    try
      Form.ShowModal;
    except
      WriteLog(LastException.Message);
      raise(LastException.Message);
    end;
  finally
    Form.Free;
    vLinkBICwithACCOUNT.Free;       // exchange #2994
    Ufebs.VCERTUnInitialize;
  end;

end; {End Main}


{~OnFormShow
  вызывается при открытии формы.
  здесь восстанавливаем сохраненные параметры по переменной vOldParams}
procedure OnFormShow(Sender: TObject);
begin

    try
      DoRefreshParams( vOldParams);
      except
        ExceptionProc( 'OnFormShow');
    end;

end;


procedure OnButtonExecuteClick(Sender: TObject);
var
  FEDNo: Integer;
begin
  try
    Initialize(InputXml);
    
    if ((Ufebs.SignType in [stED, stPacket]) or FSigEnvelope) then
    begin
      WriteLog('Инициализация "СКАД Сигнатура"');
      Ufebs.VCERTInitialize;
    end;
    
    FEDDate := DateED.Date;
    FEDNo := 300000 + StrToInt(FormatDateTime('hhmmss', Now));
    Ufebs := CreateOleObject('Ufebs.ED210');
    Ufebs.EDNo := FEDNo;

    // exchange #3042
    // должно EDDate= значению системной даты (то есть фактическое значение
    // календарной даты, в которой формируется запрос)
    Ufebs.EDDate := NOW;

    Ufebs.EDAuthor := FEDAuthor;
    Ufebs.AbstractRequest := CodeQuery.ItemIndex + 1;
    Ufebs.AbstractDate := FEDDate;
    Ufebs.Acc := Account.Text;
    if BeginTime.Enabled then
    begin
      Ufebs.BeginTime := BeginTime.Time;
      Ufebs.EndTime := EndTime.Time;
    end;

    // exchange #2994 - заполнение БИК
    // если галка стоит - заполняем из текста редактора
    if cbBIC.Checked
      then Ufebs.BIC := edBIC.Text;
    
    WriteLog('<ЭД/Пакет ЭД> - Формирование');
    Ufebs.makeXML;
    
    MakeFileName(InputXml);
    
    Ufebs.formatXML;
    
    if Ufebs.SignType in [stED, stPacket] then
    begin
      WriteLog('<ЭД/Пакет ЭД> - Установка ЭЦП(ЗК)');
      Ufebs.Sign;
    end;
    
    if FFormatXML then
    begin
      WriteLog('<ЭД/Пакет ЭД> - Форматирование');
      Ufebs.FormatXML;
    end;
    
    WriteLog('<ЭД/Пакет ЭД> - Контроль валидности');
    if not Ufebs.Validate then
      with Ufebs.ValidateError do
        raise('<ЭД/Пакет ЭД>  - Не прошёл контроль валидности' + #13#10 +
          'Причина: ' + reason + #13#10 + 'XML: ' + srcText);
    
    if FSigEnvelope then
    begin
      FileArh := DirArh + FormatDateTime('yyyy-mm-dd', FEDDate) + '\Out\Xml\' +
        ExtractFilename(FileOut) + '.xml';
      ForceDirectories(ExtractFilePath(FileArh));
      if DirectoryExists(ExtractFilePath(FileArh)) then
        Ufebs.SaveToFile(FileArh);
    
      WriteLog('<Конверт ЭЦП(КА)> - Создание');
      Ufebs := Ufebs.makeSigEnvelope;
      WriteLog('<Конверт ЭЦП(КА)> - Формирование');
      Ufebs.makeXML;
      WriteLog('<Конверт ЭЦП(КА)> - Установка ЭЦП(КА)');
      Ufebs.Sign;
      if FFormatXML then
      begin
        WriteLog('<Конверт ЭЦП(КА)> - Форматирование');
        Ufebs.FormatXML;
      end;
      WriteLog('<Конверт ЭЦП(КА)> - Контроль валидности');
      if not Ufebs.Validate then
        with Ufebs.ValidateError do
          raise('<Конверт ЭЦП(КА)> - Не прошёл контроль валидности' + #13#10 +
            'Причина: ' + reason + #13#10 + 'XML: ' + srcText);
    end;
    
    if FEnvelope then
    begin
      WriteLog('<Служебный конверт> - Создание');
      Ufebs := Ufebs.makeEnvelope;
      WriteLog('<Служебный конверт> - Формирование');
      Ufebs.MessageInfo.SendTo := FTo;
      Ufebs.MessageInfo.SendFrom := FFrom;
      Ufebs.MessageInfo.MessageType := FMessageType;
      Ufebs.MessageInfo.Priority := FPriority;
      
      //DocInfo
      Ufebs.DocInfo.DocFormat := 1; //Всегда 1 - УФЭБС
      Ufebs.DocInfo.EDRefID.EDNo := FEDNo;
      Ufebs.DocInfo.EDRefID.EDDate := FEDDate;
      Ufebs.DocInfo.EDRefID.EDAuthor := FEDAuthor;
      
      if FTransportFileName then
        Ufebs.MessageInfo.LegacyTransportFileName := ExtractFileName(FileOut);
    
      if FMessageID then Ufebs.MessageInfo.MessageID := 'guid:' + Ufebs.genGuid;
      if FAppMessageID then Ufebs.MessageInfo.AppMessageID := 'guid:' + Ufebs.genGuid;
    
      Ufebs.makeXML;
      if FFormatXML then
      begin
        WriteLog('<Служебный конверт> - Форматирование');
        Ufebs.FormatXML;
      end;
      WriteLog('<Служебный конверт> - Контроль валидности');
      if not Ufebs.Validate then
        with Ufebs.ValidateError do
          raise('<Служебный конверт> - Не прошёл контроль валидности' + #13#10 +
            'Причина: ' + reason + #13#10 + 'XML: ' + srcText);
    end;
    
    
    try
      WriteLog('Сохранение в исходящем каталоге: ' + FileOut);
      Ufebs.SaveToFile(FileOut);
      if not FileExists(FileOut) then raise('');
    except
        raise('Ошибка сохранения: ' + FileOut);
    end;
    FileArh := DirArh + FormatDateTime('yyyy-mm-dd', FEDDate) + '\Out\' + ExtractFileName(FileOut);;
    ForceDirectories(ExtractFilePath(FileArh));
    WriteLog('Копирование в архивный каталог: ' + FileArh);
    if not DirectoryExists(ExtractFilePath(FileArh)) then
      MessageDlg('Ошибка создания архивного каталога: ' + ExtractFilePath(FileArh), mtWarning , mbCancel , 0)
    else
      CopyFile(FileOut, FileArh, False);
    if not FileExists(FileArh) then
      MessageDlg('Ошибка сохранения: ' + FileArh, mtWarning , mbCancel , 0);
    MessageDlg('Запрос выписки сформирован: ' + FileOut, mtInformation, mbOk, 0);
    WriteLog('===   ЗАВЕРШЕНИЕ ЗАПРОСА ВЫПИСКИ   ===');
  except
      WriteLog(LastException.Message);
      raise(LastException.Message);
  end;
end; {End OnButtonExecuteClick}

procedure OnButtonExitClick(Sender: TObject);
begin
  Form.modalResult := mrCancel;
end; {End OnButtonExitClick}

procedure LoadBudgLevel;
var
  i: Integer;
begin

    try
      BudgLevel.Items.Clear;
      BudgLevelXml := CreateOleObject('Microsoft.XmlDom');

      // значение уровня бюджета пока не выбрано
      vChoiceBudgetLevel := '';

      // добавлена сортировка уровней бюджетов по названию непосредственно
      // в запросе
      BudgLevelXml.loadXML(
          RunQuery(
            'Select B.Id, B.Caption From BudgLevel B order by B.Caption'));

      with BudgLevelXml.documentElement do
      for i := 0 to childNodes.length - 1 do
        BudgLevel.Items.Add(childNodes.items[i].getAttribute('CAPTION'));
      if (BudgLevel.Items.Count > 0)
        then BudgLevel.ItemIndex := 0;

      // exchange #2994
      // добавлен вызов обработчика выбора значения в списке - имитируем
      // выбор.
      OnChoiceAccount( NIL);

      except
        ExceptionProc( 'LoadBudgLevel');
    end;

end; {End LoadBudgLevel}

procedure OnBudgLevelChange(Sender: TObject);
begin

    try
      LoadListAccount;
      except
        ExceptionProc( 'OnBudgLevelChange');
    end;

end; {End OnBudgLevelChange}

// exchange #2994
// событие выбора счета из списка
// нужно подставить значение БИК в поле edBIC
procedure OnChoiceAccount(Sender: TObject);
var
  xAccount: string;
begin

    try
      if (Account.Items.Count <= 0) then begin
        edBIC.Text  := '';
        xAccount    := '';
      end else
        if (Account.ItemIndex <= -1) then begin
          edBIC.Text  := '';
          xAccount    := '';
        end else begin
          xAccount    := Account.Items.Strings[ Account.ItemIndex];
          edBIC.Text  := vLinkBICwithACCOUNT[ Account.ItemIndex];
        end;

      // переопределяем значение параметров по выбранному урвню бюджета и счету
      edParams.Text := 'BUDGLEVEL=' + vChoiceBudgetLevel
                        + #13#10
                        + 'ACCOUNT=' + xAccount;

      Application.ProcessMessages;

      except
        ExceptionProc( 'OnChoiceAccount');
    end;

end;


procedure LoadListAccount;
var
  i: Integer;
  Xml: Variant;
  Q: TRunQuery;
begin

    try
      // exchange #2994
      // при выборе счетов очищаем поле BIC на форме.
      edBIC.Text := '';
      vLinkBICwithACCOUNT.Clear;

      Account.Items.Clear;

      if (BudgLevel.Items.Count > 0) then
      if (BudgLevel.ItemIndex >= 0) then begin
        vChoiceBudgetLevel := BudgLevelXml.documentElement.ChildNodes.items[
                                    BudgLevel.ItemIndex].getAttribute('ID');


        Xml := CreateOleObject('Microsoft.XmlDom');

        // exchange #2994
        // доработан запрс - переделан на параметрический
        // добавлена сортировка счетов - именно в запросе!
      {
        sql := 'Select A.Account_Number' +
          ' From Budget B' +
          ' Left Join Org O On (O.Id = B.Org_Id)' +
          ' Left Join OrgAccount A On (A.Org_Id = O.Id And B.BudgKind = 2 And A.OrgAcctype_Id = 2)' +
          ' Where B.Id Is Not Null And A.Close_Date Is Null And B.BudgLevel_Id = ' +
          BudgLevelXml.documentElement.ChildNodes.items[BudgLevel.ItemIndex].getAttribute('ID') +
          ' Group By A.Account_Number';
        Xml.loadXML(RunQuery(sql));
        }
        Q:= TRunQuery.Create;
        try
          Q.AddStr( vChoiceBudgetLevel);
          Xml.loadXML( Q.Run(
                  ' Select distinct A.Account_Number ACC, BA.bic BIC'
                 +' From Budget B'
                 +' Left Join Org O On (O.Id = B.Org_Id)'
                 +' Left Join OrgAccount A On (A.Org_Id = O.Id And B.BudgKind = 2'
                 +' And A.OrgAcctype_Id = 2)'
                 +' left join bank BA on BA.id = A.bank_id'
                 +' Where B.Id Is Not Null And A.Close_Date Is Null'
                 +' And B.BudgLevel_Id =?'
                 +' order by A.account_number'));
          finally
            Q.Free;
        end;

        Xml := Xml.documentElement;
        for i := 0 to Xml.childNodes.length - 1 do begin
          Account.Items.Add( Xml.childNodes.items[i].GetAttribute( 'ACC'));
          //Xml.childNodes.items[i].attributes.item[0].nodeValue);
          // список ассоциаций: счет-бик заполняем паралельно списку счетов
          // в этом случае при выборе счета, индекс будет соответствовать бику.
          // так сделано потому, что возможны одинаковые счета с разными биками,
          // поэтому поиск по номеру счета не даст верного результата.
          vLinkBICwithACCOUNT.Add( Xml.childNodes.items[i].GetAttribute( 'BIC'));
        end;//for//
        if (Account.Items.Count > 0)
          then Account.ItemIndex := 0;
      end;

      // exchange #2994
      // имитируем выбор счета в списке
      OnChoiceAccount( NIL);

      ButtonExecute.Enabled := Account.Items.Count <> 0;

      except
        ExceptionProc( 'LoadListAccount');
    end;

end; {End LoadListAccount}


{~DoRefreshParams
  exchange #2994
  восстановление параметров выбора уровня бюджета и счета
  при открытии формы в первый раз.}
procedure DoRefreshParams( aParams: string);
var
  SL: TStringList;
  i: integer;
  s: string;
  xXml: variant;
begin

    try
      SL:= TStringList.Create;
      try
        SL.Text := aParams;

        // уровень бюджета
        s := SL.Values( 'BUDGLEVEL');
        if (LENGTH( s) > 0) then begin
            // ищем ид.бюджета в списке
          xXml := BudgLevelXml.documentElement;
          for i := 0 to xXml.childNodes.length - 1 do
            if (xXml.childNodes.items[i].getAttribute('ID') = s) then begin

              // выбираем сохраненный уровень бюджета и обновляем список счетов
              BudgLevel.ItemIndex := i;
              OnBudgLevelChange( NIL);
            end;
        end;

        // поиск счета
        s := SL.Values( 'ACCOUNT');
        if (LENGTH( s) > 0) then begin
          i := Account.Items.IndexOf( s);
          if (i <> -1) then begin

            Account.ItemIndex := i;
            OnChoiceAccount( NIL);
          end;
        end;
        finally
          SL.Free;
      end;
      except
        ExceptionProc( 'DoRefreshParams');
    end;

end;


procedure OnCodeQueryChangeOnCheckCheckBox(Sender: TObject);
begin
  BeginTime.Enabled := (CodeQuery.ItemIndex in [0, 2]) and CheckBox.Checked;
  EndTime.Enabled := (CodeQuery.ItemIndex in [0, 2]) and CheckBox.Checked;
end; {End OnCodeQueryChangeOnCheckCheckBox}

procedure Initialize(Xml: Variant);
var
  i: Integer;
  Nodes: Variant;
begin
  try
    Ufebs := CreateOleObject('Ufebs.ED210');
  except
    raise('Ошибка инициализации обьекта из библиотеки УФЭБС.' +
      ''#13#10'Зарегистрируйте библиотеку: regsvr32.exe Ufebs.ocx');
  end;
  if CompareVersionEx(Ufebs.Version, WorkUfebsVersion) < 0 then
    raise('Скрипты работают с Ufebs.ocx начиная с версии: ' +
      WorkUfebsVersion + ''#13#10'Текущая версия Ufebs.ocx: ' + Ufebs.Version);
  with Xml.documentElement, TStringList.Create do
  try
    FileLog := ExtractFilePath(getAttribute('INI_FILE')) + 'UfebsUnLoad.Log';
    FileInfo := ExtractFilePath(getAttribute('INI_FILE')) + 'UfebsInfo.Log';
    WriteLog('===   НАЧАЛО ЗАПРОСА ВЫПИСКИ   ===');
    WriteLog('Версия сборки импорта/экспорта формата УФЭБС: ' + UfebsVersion);
    WriteLog('Инициализация параметров конфигурации');

    with CreateOleObject('Microsoft.XmlDom') do
    begin
      if not Load(ExtractFilePath(FileLog) + 'UfebsUnload.cfg') then
        raise('Ошибка при зачитывании файла конфигурации выгрузки');
      Nodes := documentElement.childNodes;
    end;

    for i := 0 to Nodes.length - 1 do
      Add(Nodes.item[i].attributes.getNamedItem('name').nodeValue +
        '=' + Nodes.item[i].attributes.getNamedItem('value').nodeValue);

    FModuleFileName := ExtractFilePath(getAttribute('INI_FILE')) + 'UfebsFileName.pfe';
    FFunctionFileName := Trim(Values['Правило формирование имени файла']);

    DirOut := Trim(Values['Исходящий каталог']);
    if DirOut = '' then DirOut := 'Output';
    DirOut := StringReplace(DirOut + '\', '\\', '\');
    if ExtractFileDrive(DirOut) = '' then
      DirOut := ExtractFilePath(getAttribute('INI_FILE')) + DirOut;
    ForceDirectories(DirOut);
    if not DirectoryExists(DirOut) then
      raise('Ошибка при определении исходящего каталога: ' + DirOut);
    DirArh := Trim(Values['Архивный каталог']);
    if DirArh = '' then DirArh := 'Arhiv';
    DirArh := StringReplace(DirArh + '\', '\\', '\');
    if ExtractFileDrive(DirArh) = '' then
      DirArh := ExtractFilePath(getAttribute('INI_FILE')) + DirArh;
    ForceDirectories(DirArh);
    if not DirectoryExists(DirArh) then
      raise('Ошибка при определении архивного каталога: ' + DirArh);

    Ufebs.FormatVer := Trim(Values['Версия формата']);

    Ufebs.DirSchems := ExtractFilePath(getAttribute('INI_FILE')) +
      'UfebsSchems\' + Ufebs.FormatVer;

    if Trim(Values['Устанавливать ЭЦП(ЗК)']) = 'Не устанавливать' then
      Ufebs.SignType := stNone
    else if Trim(Values['Устанавливать ЭЦП(ЗК)']) = 'На каждый ЭД в пакете' then
      Ufebs.SignType := stED
    else if Trim(Values['Устанавливать ЭЦП(ЗК)']) = 'На весь пакет' then
      Ufebs.SignType := stPacket;

    FSigEnvelope := Trim(Values['Формировать конверт ЭЦП(КА)']) = 'Да';

    FEnvelope := (Trim(Values['Формировать служебный конверт']) = 'Да') And FSigEnvelope;

    Ufebs.EnvelopeCrypted := Trim(Values['Шифровать Object']) = 'Да';
    Ufebs.OIDEncrypt := Trim(Values['OID ключа адресата шифрования']);
    Ufebs.EnvelopeCompessed := Trim(Values['Упаковывать Object']) = 'Да';

    FEDAuthor := Trim(Values['Идентификатор составителя']);
    FTo := Trim(Values['Адрес получателя']);
    FFrom := Trim(Values['Адрес отправителя']);
    FSystemCode := Trim(Values['Признак системы обработки']);
    FMessageType := Trim(Values['Тип сообщения']);
    FPriority := Trim(Values['Приоритет сообщения']);
    FAppMessageID := Trim(Values['Прикладной идентификатор']) = 'Да';
    FMessageID := Trim(Values['Идентификатор сообщения']) = 'Да';
    FTransportFileName := Trim(Values['Передавать имя файла']) = 'Да';

    FFormatXML := Trim(Values['Форматировать XML']) = 'Да';

    Ufebs.NSType[nstEd] := Trim(Values['urn:cbr-ru:ed:v1.1']);
    Ufebs.NSType[nstDsig] := Trim(Values['urn:cbr-ru:dsig:v1.1']);
    Ufebs.NSType[nstDsigEnv] := Trim(Values['urn:cbr-ru:dsig:env:v1.1']);
    Ufebs.NSType[nstSoap] := Trim(Values['http://www.w3.org/2003/05/soap-envelope']);
    Ufebs.NSType[nstMsg] := Trim(Values['urn:cbr-ru:msg:props:v1.1']);

    if ((Ufebs.SignType in [stED, stPacket]) or FSigEnvelope) then
      Ufebs.VCERTLocalPath := Trim(Values['Каталог справочников ЭЦП']);

    // exchange #3032
    // совместима только с версией УФЭБС OCX не ниже 2.2.0.0.0
    // exchange #3041
    // версия шифрования не нужна в 2.38, поэтому из конфига параметр будет
    // удален, а код в скрипте останется только в режиме отладки.
    // exchange #3107
    // требуется реализовать в 2.38 и 2.38.2
    case TRIM(Values['Режим шифрования']) of
      'PKCS7':  Ufebs.EncryptParam := 1;
      else      Ufebs.EncryptParam := 0;
    end;//case//

  finally
    Free;
  end;
end; {Initialize}

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

begin
  Xml := CreateOleObject('Microsoft.XmlDom');
  if not FileExists('C:\Temp\UfebsED210.Xml') then
  begin
    ShowMessage('Не найден тестовый пример: C:\Temp\UfebsED210.Xml');
    Exit;
  end;
  if not Xml.Load('C:\Temp\UfebsED210.Xml') then
  begin
    ShowMessage('Ошибка при загрузке: C:\Temp\UfebsED210.Xml');
    Exit;
  end;
  Main(Xml);
end.
