Показаны сообщения с ярлыком Delphi. Показать все сообщения
Показаны сообщения с ярлыком Delphi. Показать все сообщения

6 февр. 2015 г.

Lazarus. Файловый монитор.

Была тут такая задача. Есть папки, в которые попадают графические файлы. Для упрощения, можно считать, что файлы со сканера. Потом те файлы, которые оказываются нужными, необходимо сохранить, ставшие не нужными - удалить. Главное, чтобы файлы не оставались в исходной папке, т.к. уже через день никто не может сказать, нужны они кому-то, или их просто забыли удалить. Что собственно и происходит сейчас. Решил оказать помощь, написать программу, которая будет автоматизировать процесс, "заставляя" пользователя, в т.ч. и с помощью модальных окон, чистить от картинок папку в которую они попадают.
В качестве инструмента решил попробовать Lazarus. С удивлением обнаружил, что с его помощью можно писать программы. Т.е. стабильность достигла приличного уровня, юзабельность - вполне на уровне. VCL с множеством компонент. Столкнулся, правда, с парой глюков, но их удалось обойти.

В общем, просто супер, разработчики Lazarus - крутые. Уже можно школьников обучать.
Программу мою, правда, уже две недели тот, кому она была нужна, не смотрит. Как впрочем многое из того, что я делаю здесь. Исходники хотя бы надо куда-нибудь выложить.
Выложил. Вот

18 мар. 2013 г.

Загрузка в Диасофт FA# 5NT из 4х4 с поиском фамилий и счетов регэкспами

Программка берет из командной строки имя файла, в котором содержатся платежи в формате Диасофт 4х4. Загружает их, находит в назначении платежа с помощью регулярных выражений (библиотека Copyright (c) 1999-2004 Andrey V. Sorokin, St.Petersburg, Russia) ФИО, номер счета. Затем выгружает текстовые файлы, пригодные к загрузке в Диасофт FA# 5NT, в каталоги, необходимые для последующей загрузки.
Основное назначение - автоматизировать зачисление пришедших на физиков платежей с реквизитами счетов в назначении платежа.
unit SDIMAIN; 

interface 

uses Windows, Classes, Graphics, Forms, Controls, Menus, 
  Dialogs, StdCtrls, Buttons, ExtCtrls, ComCtrls, ImgList, StdActns, 
  ActnList, ToolWin, Grids, SysUtils, StrUtils, RegExpr; 

type 
  TMyGrid=class(TCustomGrid); 

  TSDIAppForm = class(TForm) 
    OpenDialog: TOpenDialog; 
    SaveDialog: TSaveDialog; 
    ToolBar1: TToolBar; 
    ToolButton1: TToolButton; 
    SaveButton: TToolButton; 
    ActionList1: TActionList; 
    FileNew1: TAction; 
    FileOpen1: TAction; 
    FileSave1: TAction; 
    FileSaveAs1: TAction; 
    FileExit1: TAction; 
    EditCut1: TEditCut; 
    EditCopy1: TEditCopy; 
    EditPaste1: TEditPaste; 
    HelpAbout1: TAction; 
    StatusBar: TStatusBar; 
    ImageList1: TImageList; 
    Panel1: TPanel; 
    StringGrid1: TStringGrid; 
    DelBtn: TBitBtn; 
    ToolButton3: TToolButton; 
    BtnSaveToCard: TBitBtn; 
    procedure BtnSaveToCardClick(Sender: TObject); 
  
    procedure DelBtnClick(Sender: TObject); 
    function  ToOEM(S:String):String; 
    function  ToAnsi(S:String):String; 
    function  LeftPad(S: string; Ch: Char; Len: Integer): string; 
    function  RightPad(S: string; Ch: Char; Len: Integer): string; 
    procedure LoadInFile(); 
    procedure FormShow(Sender: TObject); 
    procedure FileNew1Execute(Sender: TObject); 
    procedure FileOpen1Execute(Sender: TObject); 
    procedure FileSave1Execute(Sender: TObject); 
    procedure FileExit1Execute(Sender: TObject); 
    procedure DeleteARow(Grid: TStringGrid; ARow: Integer); 
  private 
    { Private declarations } 
  public 
    { Public declarations } 
  end; 

var 
  SDIAppForm: TSDIAppForm; 
  STag,Val: String; 
  SIn,SOut: String; 
  FamilyName,FirstName,SurName: String; 
  InFile,OutFile: TextFile; 
  TagLength:  Integer; 
  RegExp: TRegExpr; 
  Colwidths: array[0..6] of integer = (25,18,18,3,20,31,250); 
  // !!! This for 5NT File, don't touch 
implementation 


{$R *.dfm} 



procedure TSDIAppForm.DelBtnClick(Sender: TObject); 
begin 
  DeleteARow(StringGrid1, StringGrid1.Row); 
end; 

procedure TSDIAppForm.DeleteARow(Grid: TStringGrid;   ARow: Integer); 
begin 
  TMyGrid(Grid).DeleteRow(ARow); 
end; 

procedure TSDIAppForm.FileNew1Execute(Sender: TObject); 
begin 
  { Do nothing } 
end; 

procedure TSDIAppForm.FileOpen1Execute(Sender: TObject); 
begin 
  OpenDialog.Execute; 
  SDIAppForm.caption:='Зачисление переводов - '+ OpenDialog.Filename; 
  if OpenDialog.Filename<>'' then 
  begin 
    DelBtn.Enabled:=false; 
    SaveButton.Enabled:=false; 
    BtnSaveToCard.Enabled:=false; 
    LoadInFile; 
    if (StringGrid1.RowCount > 1) and (StringGrid1.Cells[6,1] <> '') then 
    begin 
      SaveButton.Enabled:=true; 
      BtnSaveToCard.Enabled:=true; 
      Delbtn.Enabled:=true; 
    end; 
  end; 
end; 

procedure TSDIAppForm.LoadInFile; 
var 
  col,row:Integer; 
begin 
  AssignFile(InFile,OpenDialog.Filename); 
  Reset(InFile); 
  StringGrid1.RowCount:=2; 
  row:=0; 
  for col := 0 to 6 do {clear second line} 
  begin 
       StringGrid1.Cells[col,1]:=''; 
  end; 
  while not Eof(InFile) do 
  begin 
    Readln(InFile, SIn); 
    SOut:=ToAnsi(SIn); 
    TagLength:=AnsiPos(':',SIn)-1; 
    if TagLength=-1 then 
    begin 
      STag:=SOut; 
    end 
    else 
    begin 
      STag:=MidStr(SOut,1,TagLength); 
      Val:=MidStr(SOut,TagLength+2,Length(SOut)-TagLength-1); 
    end; 
    if STag='%МЕЖБНКДОК' then 
    begin 
      row:=row+1; 
      if row>1 then 
          StringGrid1.RowCount:=row+1; 
    end; 
    if STag='ВАЛЮТА    ' then 
      StringGrid1.Cells[3,row]:=Val; 
    if STag='СУММА     ' then 
      StringGrid1.Cells[5,row]:=Val; 
    if (midstr(STag,1,4)='ПРИМ') and (length(Val)<>0) then 
      StringGrid1.Cells[6,row]:=StringGrid1.Cells[6,row]+Val; 
    if (midstr(STag,1,4)='%END') then 
    begin 
      try 
        RegExp := TRegExpr.Create; 
        RegExp.Expression := '[А-Я]{1}[а-я]{2,}\s[А-Я]{1}[а-я]{2,}\s[А-Я]{1}[а-я]{2,}'; 
        if RegExp.Exec(StringGrid1.Cells[6,row]) then 
        begin 
          RegExp.Expression := '[А-Я]{1}[А-Яа-я]{2,}'; 
          RegExp.Exec(RegExp.Match[0]); 
          StringGrid1.Cells[0,row]:=RegExp.Match[0]; 
          RegExp.ExecNext; 
          StringGrid1.Cells[1,row]:=RegExp.Match[0]; 
          RegExp.ExecNext; 
          StringGrid1.Cells[2,row]:=RegExp.Match[0]; 
        end; 
        RegExp.Expression := '(40817|42301|42302|42303|42304|42305|42306|42307)[0-9]{15}'; 
        if RegExp.Exec(StringGrid1.Cells[6,row]) then 
        begin 
          StringGrid1.Cells[4,row]:=RegExp.Match[0]; 
        end; 
     finally 
       RegExp.Free; 
     end; 
    end; 
  end; 
  CloseFile(InFile); 
end; 

procedure TSDIAppForm.FileSave1Execute(Sender: TObject); 
  var i,j:Integer; 
      S,Today:string; 
begin 
  Today:=DateTimeToStr(Now); 
  SaveDialog.FileName:='b'+Midstr(Today,9,2)+Midstr(Today,4,2)+Midstr(Today,1,2)+'a.777'; 
  SaveDialog.InitialDir:='c:\ObmenPC40\Dividend\'; 
  SaveDialog.Execute; 
  Rewrite(OutFile,SaveDialog.FileName); 
  for i := 1 to StringGrid1.RowCount - 1 do 
  begin 
      for j := 0 to StringGrid1.ColCount - 1 do 
      begin 
         S:=Trim(Midstr(StringGrid1.Cells[j,i],1,Colwidths[j])); 
         if Colwidths[j]>length(S) then 
            S:=LeftPad(S,' ',Colwidths[j]); 
         Write(OutFile,'  '+ToOEM(S));//!!! 

      end; 
      Write(OutFile,''#13+#10); 
  end; 
  Flush(OutFile); 
  CloseFile(OutFile); 

end; 

procedure TSDIAppForm.BtnSaveToCardClick(Sender: TObject); 
  var i,j:Integer; 
      Today:string; 
begin 
  Today:=DateTimeToStr(Now); 
  SaveDialog.FileName:='b'+Midstr(Today,9,2)+Midstr(Today,4,2)+Midstr(Today,1,2)+'a.777'; 
  SaveDialog.InitialDir:='c:\ObmenPC40\Card\'; 
  SaveDialog.Execute; 
  Rewrite(OutFile,SaveDialog.FileName); 
  for i := 1 to StringGrid1.RowCount - 1 do 
  begin 
      Write(OutFile,Trim(IntToStr(i))); 
      Write(OutFile,'^777'); 
      for j := 0 to StringGrid1.ColCount - 1 do 
      begin 
         Write(OutFile,'^'+ToOEM(Trim(StringGrid1.Cells[j,i])));//!!! 
      end; 
      Write(OutFile,''#13+#10); 
  end; 
  Flush(OutFile); 
  CloseFile(OutFile); 
end; 

procedure TSDIAppForm.FormShow(Sender: TObject); 
var 
   col: Integer; 
begin 
   StringGrid1.ColCount:=7; 
   StringGrid1.RowCount:=2; 
   StringGrid1.FixedRows:=1; 
   StringGrid1.ColWidths[0]:=90;   StringGrid1.Cells[0,0]:='Фамилия'; 
   StringGrid1.ColWidths[1]:=90;  StringGrid1.Cells[1,0]:='Имя'; 
   StringGrid1.ColWidths[2]:=90;   StringGrid1.Cells[2,0]:='Отчество'; 
   StringGrid1.ColWidths[3]:=20;   StringGrid1.Cells[3,0]:='Вал'; 
   StringGrid1.ColWidths[4]:=105;  StringGrid1.Cells[4,0]:='Номер счета'; 
   StringGrid1.ColWidths[5]:=70;   StringGrid1.Cells[5,0]:='Сумма'; 
   StringGrid1.ColWidths[6]:=1180;   StringGrid1.Cells[6,0]:='Примечание'; 
   for col := 0 to 6 do {clear second line} 
   begin 
       StringGrid1.Cells[col,1]:=''; 
   end; 
   DelBtn.Enabled:=false; 
   SaveButton.Enabled:=false; 
   BtnSaveToCard.Enabled:=false; 
   OpenDialog.FileName:= ParamStr(1); 
   SDIAppForm.Caption:='Зачисление переводов - '+ ParamStr(1); 
   if ParamStr(1) <> '' then 
   begin 
     LoadInFile; 
     if (StringGrid1.RowCount > 1) and (StringGrid1.Cells[6,1] <> '') then 
     begin 
       SaveButton.Enabled:=true; 
       BtnSaveToCard.Enabled:=true; 
       Delbtn.Enabled:=true; 
     end; 
   end; 
end; 

procedure TSDIAppForm.FileExit1Execute(Sender: TObject); 
begin 
  Close; 
end; 


function TSDIAppForm.ToOEM(S:String):String; 
{ ConvertAnsiToOem translates a string into the OEM-defined character set } 
{$IFNDEF WIN32} 
var 
  Source, Dest : array[0..255] of Char; 
{$ENDIF} 
begin 
  {$IFDEF WIN32} 
  SetLength(Result, Length(S)); 
  if Length(Result) > 0 then 
    AnsiToOem(PChar(S), PChar(Result)); 
  {$ELSE} 
  if Length(Result) > 0 then 
  begin 
    AnsiToOem(StrPCopy(Source, S), Dest); 
    Result := StrPas(Dest); 
  end; 
  {$ENDIF} 
end; { ConvertAnsiToOem } 

function TSDIAppForm.ToAnsi(S:String):String; 
{ ConvertOemToAnsi translates a string into the OEM-defined character set } 
{$IFNDEF WIN32} 
var 
  Source, Dest : array[0..255] of Char; 
{$ENDIF} 
begin 
  {$IFDEF WIN32} 
  SetLength(Result, Length(S)); 
  if Length(Result) > 0 then 
    OemToAnsi(PChar(S), PChar(Result)); 
  {$ELSE} 
  if Length(Result) > 0 then 
  begin 
    OemToAnsi(StrPCopy(Source, S), Dest); 
    Result := StrPas(Dest); 
  end; 
  {$ENDIF} 
end; { ConvertOemToAnsi } 

function TSDIAppForm.LeftPad(S: string; Ch: Char; Len: Integer): string; 
 var 
   RestLen: Integer; 
 begin 
   Result  := S; 
   RestLen := Len - Length(s); 
   if RestLen < 1 then Exit; 
   Result := S + StringOfChar(Ch, RestLen); 
 end; 

 function TSDIAppForm.RightPad(S: string; Ch: Char; Len: Integer): string; 
 var 
   RestLen: Integer; 
 begin 
   Result  := S; 
   RestLen := Len - Length(s); 
   if RestLen < 1 then Exit; 
   Result := StringOfChar(Ch, RestLen) + S; 
 end; 

end.

18 февр. 2013 г.

Доработка файлов по 365-П (GUID, переименование, поиск ошибок и т.д.)


unit main; 

interface 

uses 
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, StdCtrls, StrUtils, DateUtils, ComCtrls, ExtCtrls, ToolWin; 

type 
  TForm1 = class(TForm) 
    Go_Button:   TButton; 
    OpenDialog1: TOpenDialog; 
    OpenButton:  TButton; 
    SaveDialog1: TSaveDialog; 
    BtnRe: TButton; 
    ToolBar1: TToolBar; 
    Panel1: TPanel; 
    StatusBar1: TStatusBar; 
    ProgressBar1: TProgressBar; 
    SrcOpenDialog: TOpenDialog; 
    MProtocol: TRichEdit; 
    procedure FormCreate(Sender: TObject); 
    procedure BtnReClick(Sender: TObject); 
    procedure OpenButtonClick(Sender: TObject); 
    procedure Go_ButtonClick(Sender: TObject); 
    function  ToOEM(S:String):String; 
    function  ToAnsi(S:String):String; 
    function  WriteLog(Level:Integer; S:String):String; 
    function  FileSizeByName(Name:String): Integer; 
    function  isNum(const st:string): boolean; 

  private 
    { Private declarations } 
  public 
    { Public declarations } 
  end; 
const 
  OstPref='BOS1_'; 
  OstSrcPref='RBN'; 
  OperPref='BV100_'; 
  OperSrcPref='ZNO'; 
  NalschPref='BNS1_'; 
  NalschSrcPref='ZNO'; 
  ReceiptPref='PB1_'; 
  ChunkLimit=470000;    //524288 - 512К 
  Bic='10813823'; 
  INN='7744001497'; 
  ERR=0; 
  WARN=1; 
  INFO=2; 

var 
  Form1: TForm1; 
  InFile,OutFile: TextFile; 
  CurrentFileNum,NumOutFiles,OutFileSize: Integer; 
  SIn,SOut: String; 
  InFileSize, InFilePosition: Integer; 
  DateZapr,KodNO,NomZapr,NomResh,DateResh :String; 
  NumericTags: TStringList; 

implementation 

{$R *.dfm} 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
  DateZapr:=''; 
  NomZapr:=''; 
  NomResh:=''; 
  DateResh:=''; 
  NumericTags := TStringList.Create; 
  NumericTags.Add('ИННКО'); 
  NumericTags.Add('КППКО'); 
  NumericTags.Add('БИК'); 
  NumericTags.Add('ИНННП'); 
  NumericTags.Add('КППНП'); 
  NumericTags.Add('НомСчПП'); 
  NumericTags.Add('НомСч'); 
  NumericTags.Add('БИКБП'); 
  NumericTags.Add('НомКоррСч'); 
  NumericTags.Add('НомДок'); 
  NumericTags.Sort; //for Find method! 
end; 

procedure TForm1.OpenButtonClick(Sender: TObject); 
begin 
  OpenDialog1.execute; 
  DateZapr:=''; 
  NomZapr:=''; 
  NomResh:=''; 
  DateResh:=''; 
  MProtocol.Text:=''; 
  WriteLog(INFO,'Файл к обработке: '+OpenDialog1.Filename+''#13+#10); 
end; 

procedure TForm1.BtnReClick(Sender: TObject); 
var 
  FileName,DateStr: String; 
  NameLength: Integer; 
  Today: TDateTime; 
begin 
//Формирование подтерждения по заданному файлу 
//ZNO10813823_774820120203_000594### 
//10@@@ 
//2012-02-06@@@ 
//10:35:37@@@ 
//=== 
    if (AnsiPos('.',ExtractFileName(OpenDialog1.FileName))<>0) then 
      SaveDialog1.FileName:=ReceiptPref+MidStr(ExtractFileName(OpenDialog1.FileName),1,AnsiPos('.',ExtractFileName(OpenDialog1.FileName))-1)+'.TXT'
    else 
      SaveDialog1.FileName:=ReceiptPref+ExtractFileName(OpenDialog1.FileName)+'.TXT'; 
    SaveDialog1.Execute; 
    WriteLog(INFO,'Имя файла подтверждения: '+SaveDialog1.FileName+''#13+#10); 
    Rewrite(OutFile,SaveDialog1.FileName); 
    FileName:=ExtractFileName(OpenDialog1.FileName); 
    Writelog(INFO,''#13+#10); // empty line before receipt 
    Write(OutFile,MidStr(FileName,1,Length(FileName)-4)+'###'+''#13+#10); 
    WriteLog(INFO,MidStr(FileName,1,Length(FileName)-4)+'###'+''#13+#10); 
    Write(OutFile,'10@@@'+''#13+#10); 
    Writelog(INFO,'10@@@'+''#13+#10); 
    DateStr:=DateToStr(Now); 
    Write(OutFile,MidStr(DateStr,7,4)+'-'+MidStr(DateStr,4,2)+'-'+MidStr(DateStr,1,2)+'@@@'+''#13+#10); 
    Writelog(INFO,MidStr(DateStr,7,4)+'-'+MidStr(DateStr,4,2)+'-'+MidStr(DateStr,1,2)+'@@@'+''#13+#10); 
    Write(OutFile,TimeToStr(Now)+'@@@'+''#13+#10); 
    Writelog(INFO,TimeToStr(Now)+'@@@'+''#13+#10); 
    Write(OutFile,'==='+''#13+#10); 
    Writelog(INFO,'==='+''#13+#10); 
    Flush(OutFile); 
    CloseFile(OutFile); 
end; 

procedure TForm1.Go_ButtonClick(Sender: TObject); 
var 
  Id: TGUID; 
  StringNo, StringCount,Code: Integer; 
  Tag,Val,HeaderTag,HeaderVal,StrNo,StrFileNo,StrNumOutFiles,DateForName,NomForName, InfType, Pref:  String; 
  TagLength,HeaderTagLength,i:  Integer; 
  RetCode:Boolean; 
  TopHeader,ThirdHeader: Array of String; 
  TopHeaderLength,ThirdHeaderLength,HeaderState: Integer; 
  Index: Integer; 
begin 
  CurrentFileNum:=1; 
  OutFileSize:=0; 
  InFilePosition:=0; 
  MProtocol.Text:=''; 
  WriteLog(INFO,'Файл к обработке: '+OpenDialog1.Filename+''#13+#10); 
  if not (FileExists(OpenDialog1.Filename)) then  exit; 
  InFileSize:=FileSizeByName(OpenDialog1.Filename); 
  ProgressBar1.Min:=0; 
  ProgressBar1.Max:=InFileSize; 
  ProgressBar1.Position:=0; 
  AssignFile(InFile,OpenDialog1.Filename); 
//  Rewrite(OutFile, OpenDialog1.Filename+'.chk1'); 
  Rewrite(OutFile, OpenDialog1.Filename+'.chk'+Format('%.2d',[CurrentFileNum])); 
  Reset(InFile); 
  if InFileSize > ChunkLimit then 
  begin 
    WriteLog(WARN,'Размер файла больше предельного размера одной части'#13+#10); 
    NumOutFiles:=(InFileSize div ChunkLimit)+1; 
    Str(NumOutFiles,StrNumOutFiles); 
  end; 
  HeaderState:=0; 
  TopHeaderLength:=0; 
  ThirdHeaderLength:=0; 
  while not Eof(InFile) do 
  begin 
    Readln(InFile, SIn); 
    SOut:=ToAnsi(SIn); 
    if HeaderState < 3 then //Еще не считали все заголовки 
    begin 
      if HeaderState=0 then 
      begin //read top header 
        TopHeaderLength:=TopHeaderLength+1; 
        SetLength(TopHeader,TopHeaderLength); 
        TopHeader[TopHeaderLength-1]:=SOut; 
      end; 
      if HeaderState=2 then 
      begin //read 3rd header 
        ThirdHeaderLength:=ThirdHeaderLength+1; 
        SetLength(ThirdHeader,ThirdHeaderLength); 
        ThirdHeader[ThirdHeaderLength-1]:=SOut; 
      end; 
      if SOut='###' then HeaderState:=HeaderState+1; 
    end; 
    StringNo:=StringNo+1; 
    Str(StringNo,StrNo); 
    TagLength:=AnsiPos(':',SOut)-1; 
    if TagLength<>-1 then 
    begin 
      Tag:=MidStr(SOut,1,TagLength); 
      Val:=MidStr(SOut,TagLength+2,Length(SOut)-TagLength-1); 
      if (Tag = 'НомСч') and (HeaderState >=3) then // found new 3rd header when already read top 3 headers 
      begin 
        HeaderState:=2;   //return to 3rd header mode 
        ThirdHeaderLength:=1; //set 1st line of 3rd header 
        ThirdHeader[ThirdHeaderLength-1]:=SOut; // write it down 
        WriteLog(INFO,'Строка '+StrNo+' - Найдено:'+SOut); 
      end; 
      if Tag = 'ТипИнф' then 
      begin 
          InfType:=Val; 
          WriteLog(INFO,'Строка '+StrNo+' - Найден ТипИнф:'+InfType); 
      end; 
      if Tag = 'ИдФайл' then 
      begin 
          CreateGUID(Id); 
          SOut:='ИдФайл:'+ Val + MidStr(GUIDToString(Id),2,36); 
          WriteLog(INFO,'Строка '+StrNo+' - Добавлен GUID к ИдФайл'); 
      end; 
      if Tag = 'КодНО' then 
      begin 
          KodNO:=Val; 
          WriteLog(INFO,'Строка '+StrNo+' - Найден  КодНО:'+KodNO); 
      end; 
      if Tag = 'ИдДок' then 
      begin 
          CreateGUID(Id); 
          SOut:='ИдДок:'+ MidStr(GUIDToString(Id),2,36); 
          WriteLog(INFO,'Строка '+StrNo+' - добавлен GUID к ИдДок'); 
      end; 
      if (Tag = 'НомЧасти') and (InFileSize <= ChunkLimit) then 
      begin 
          SOut:=''; 
          WriteLog(INFO,'Строка '+StrNo+' - Удален НомЧасти'); 
      end; 
      if (Tag = 'КолДок') and (InFileSize > ChunkLimit) then 
      begin 
          SOut:='КолДок:'+StrNumOutFiles; 
          WriteLog(INFO,'Строка '+StrNo+' - КолДок исправлен'); 
      end; 
      if Tag = 'НомЗапр' then 
      begin 
        NomZapr:=''; 
        for i := length(Val) to 6 - 1 do   NomZapr:=NomZapr+'0'; 
          NomZapr:=NomZapr+Val; 
          WriteLog(INFO,'Строка '+StrNo+' - Найден НомЗапр:'+NomZapr); 
      end; 
      if Tag = 'ДатаЗапр' then 
      begin 
          DateZapr:=MidStr(Val,7,4)+MidStr(Val,4,2)+MidStr(Val,1,2); 
          WriteLog(INFO,'Строка '+StrNo+' - Найдена ДатаЗапр:'+DateZapr); 
      end; 
      if Tag = 'НомРеш' then 
      begin 
        NomResh:=''; 
        for i := length(Val) to 6 - 1 do   NomResh:=NomResh+'0'; 
          NomResh:=NomResh+Val; 
          WriteLog(INFO,'Строка '+StrNo+' - Найден НомРеш:'+NomResh); 
      end; 
      if Tag = 'ДатаРеш' then 
      begin 
          DateResh:=MidStr(Val,7,4)+MidStr(Val,4,2)+MidStr(Val,1,2); 
          WriteLog(INFO,'Строка '+StrNo+' - Найдена ДатаРеш:'+DateResh); 
      end; 
      if (NumericTags.Find(Tag,index)) then // Проверка корректности значений числовых тегов 
      begin 
          if not isNum(Val) then 
            WriteLog(ERR,'Строка '+StrNo+' - Ошибка: Не числовые значения:'+Tag+':'+Val); 
      end; 
      if (Val='') and (Tag<>'ИдДок') then // Только последним, после обработки других 
      begin 
          WriteLog(WARN,'Строка '+StrNo+' - Обнаружен пустой тег:'+Tag); 
      end; 
    end 
    else //No tags found! 
    begin 
      if (AnsiPos('Ошибка',SOut))<>0 then 
      begin 
          WriteLog(ERR,'Строка '+StrNo+' - Найдена ошибка: '+SOut); 
      end; 
      if (AnsiPos('Ожидается',SOut))<>0 then 
      begin 
          WriteLog(ERR,'Строка '+StrNo+' - Найдена ошибка: '+SOut); 
      end; 
    end; 
    if SOut<>'' then 
    begin 
      Writeln(OutFile,ToOEM(SOut)); 
      OutFileSize:=OutFileSize+Length(SOut); 
      InFilePosition:=InFilePosition+Length(SOut); 
      ProgressBar1.Position:=InFilePosition; 
      if  (OutFileSize > ChunkLimit) and (TagLength =-1) then 
      //достигли предела и не в середине документа 
      begin 
          Writeln(OutFile,'@@@'); 
          Writeln(OutFile,'==='); 
          OutFileSize:=0; 
          Flush(OutFile); 
          CloseFile(OutFile); 
          CurrentFileNum:=CurrentFileNum+1; 
          StrFileNo:=Format('%.2d',[CurrentFileNum]);  // for filename - with leading zero's 
          WriteLog(INFO,'Строка '+StrNo+' - Начало части '+StrFileNo); 
          Rewrite(OutFile, OpenDialog1.Filename+'.chk'+StrFileNo); 
          Str(CurrentFileNum,StrFileNo);              // for tag in the file - without leading zeros 
          for i:=0 to TopHeaderLength - 1 do 
          begin 
            HeaderTagLength:=AnsiPos(':',TopHeader[i])-1; 
            HeaderTag:=MidStr(TopHeader[i],1,HeaderTagLength); 
            HeaderVal:=MidStr(TopHeader[i],HeaderTagLength+2,Length(TopHeader[i])-HeaderTagLength-1); 
            if HeaderTag='ИдФайл' then 
              TopHeader[i]:='ИдФайл:'+ MidStr(HeaderVal,1,29) + MidStr(GUIDToString(Id),2,36); 
            if HeaderTag='НомЧасти' then 
              TopHeader[i]:='НомЧасти:'+ StrFileNo; 
            if HeaderTag='КолДок' then 
              TopHeader[i]:='КолДок:'+ StrNumOutFiles; 
            Writeln(OutFile,ToOEM(TopHeader[i])); 
          end; 
          Writeln(OutFile,ToOEM('@@@')); // добавить недостающие собаки после первого заголовка 
          for i:=0 to ThirdHeaderLength - 1 do 
            Writeln(OutFile,ToOEM(ThirdHeader[i])); 
      end; 
    end; 
  end; 
  Flush(OutFile); 
  CloseFile(OutFile); 
  SaveDialog1.FileName:=''; 
  if MessageDlg('Исходный запрос был получен электронно?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then 
  begin 
     SrcOpenDialog.Title:='Выберите файл исходного запроса'; 
     SrcOpenDialog.Execute(); 
     SaveDialog1.FileName:=MidStr(ExtractFileName(SrcOpenDialog.FileName),1,AnsiPos('.',ExtractFileName(SrcOpenDialog.FileName))-1); 
     if (InfType='ОСТАТКИ')      then Pref:=OstPref; 
     if (InfType='ОПЕРАЦИИПОСЧ') then Pref:=OperPref; 
     if (InfType='НАЛСЧЕТОВ')    then Pref:=NalschPref; 
     SaveDialog1.FileName:=Pref+SaveDialog1.FileName; 
  end 
  else // create name from file contents 
  begin 
     if (InfType='ОСТАТКИ')      then 
      SaveDialog1.FileName:=OstPref+OstSrcPref+Bic+'_'+KodNO+DateResh+'_'+NomResh; 
     if (InfType='ОПЕРАЦИИПОСЧ') then 
    SaveDialog1.FileName:=OperPref+OperSrcPref+Bic+'_'+KodNO; 
     if (InfType='НАЛСЧЕТОВ')  then 
    SaveDialog1.FileName:=NalschPref+NalschSrcPref+Bic+'_'+KodNO; 
     if ((InfType='ОПЕРАЦИИПОСЧ') or (InfType='НАЛСЧЕТОВ')) then 
    SaveDialog1.FileName:=SaveDialog1.FileName+DateZapr+'_'+NomZapr; 
  end; 
  SaveDialog1.FileName:=SaveDialog1.FileName+'.TXT'; 
  ProgressBar1.Position:=0; 
  if SaveDialog1.Execute then 
  begin 
    if NumOutFiles > 1 then 
    begin // больше чем один файл - нумеруем с "1" 
      for i := 1 to NumOutfiles do 
      begin 
//      Str(i,StrFileNo); 
        StrFileNo:=Format('%.2d',[i]); 
        RetCode:=RenameFile(OpenDialog1.Filename+'.chk'+StrFileNo, ReplaceStr(SaveDialog1.FileName,'BV100','BV1'+StrFileNo)); 
        if RetCode=false then 
          MessageDlg('Невозможно сохранить файл '+ReplaceStr(SaveDialog1.FileName,'BV100','BV1'+StrFileNo), mtError,[mbOk], 0, mbOk) 
        else 
          MessageDlg('Файл сохранен как: '+ReplaceStr(SaveDialog1.FileName,'BV100','BV1'+StrFileNo),mtInformation,[mbOk], 0, mbOk); 
      end; 
    end 
    else // один файл нумеруется с "0" 
    begin 
      StrFileNo:='01'; 
      RetCode:=RenameFile(OpenDialog1.Filename+'.chk'+StrFileNo,SaveDialog1.FileName); 
      if RetCode=false then 
        MessageDlg('Невозможно сохранить файл '+SaveDialog1.FileName, mtError,[mbOk], 0, mbOk) 
      else 
        MessageDlg('Файл сохранен как: '+SaveDialog1.FileName,mtInformation,[mbOk], 0, mbOk); 
    end; 
  end; 
end; 

function TForm1.WriteLog(Level:Integer; S:String):String; 
var 
  AColor:Integer; 
begin 
  case Level of 
    ERR : AColor := clRed; 
    INFO: AColor := clLime; 
    WARN: AColor := clYellow; 
  else 
    AColor := clLime; 
  end; 
  with MProtocol do 
   begin 
     SelStart := Length(Text); 
     SelAttributes.Color := AColor; 
     Lines.Add(S); 
   end; 
  MProtocol.SelStart := MaxInt; 
  SendMessage(MProtocol.handle, EM_SCROLLCARET,0,0); 
  Result:=S; 
end; 

function TForm1.ToOEM(S:String):String; 
{ ConvertAnsiToOem translates a string into the OEM-defined character set } 
{$IFNDEF WIN32} 
var 
  Source, Dest : array[0..255] of Char; 
{$ENDIF} 
begin 
  {$IFDEF WIN32} 
  SetLength(Result, Length(S)); 
  if Length(Result) > 0 then 
    AnsiToOem(PChar(S), PChar(Result)); 
  {$ELSE} 
  if Length(Result) > 0 then 
  begin 
    AnsiToOem(StrPCopy(Source, S), Dest); 
    Result := StrPas(Dest); 
  end; 
  {$ENDIF} 
end; { ConvertAnsiToOem } 

function TForm1.ToAnsi(S:String):String; 
{ ConvertOemToAnsi translates a string into the OEM-defined character set } 
{$IFNDEF WIN32} 
var 
  Source, Dest : array[0..255] of Char; 
{$ENDIF} 
begin 
  {$IFDEF WIN32} 
  SetLength(Result, Length(S)); 
  if Length(Result) > 0 then 
    OemToAnsi(PChar(S), PChar(Result)); 
  {$ELSE} 
  if Length(Result) > 0 then 
  begin 
    OemToAnsi(StrPCopy(Source, S), Dest); 
    Result := StrPas(Dest); 
  end; 
  {$ENDIF} 
end; { ConvertOemToAnsi } 

function  TForm1.FileSizeByName(Name:String): Integer; 
var 
  F: File of byte; 
begin 
  AssignFile(F, Name); 
  Reset(F); 
  Result:=FileSize(F); 
  CloseFile(F); 
end; 

function TForm1.isNum(const st:string): boolean; 
var 
  i: Integer; 
begin 
  isNum:=True; 
  for i := 1 to Length(st) do 
    if not (st[i] in ['0'..'9']) then isNum:=False; 
end; 

end.