17 июл. 2014 г.

Настройка rsync для репликации между двумя windows серверами (без использования cwRsync)

Чтобы настроить репликацию между двумя серверами windows, используя rsync нужно сначала установить cygwin. В сети есть различные варианты урезанной установки, т.е. только rsync + dll для того, чтобы она запустилась, но я не стал заморачиваться и поставил базовую систему cygwin и дополнительно rsync, ssh, openssl - из комплекта cygwin. Устанавливал из Интернета. Зато теперь у меня полно всяких unix-утилит, от bash и sed до perl. Мегабайт на 200.

Устанавливаем систему на оба сервера. Тот, что будет являться источником информации, будет запускать rsync в режиме демона. Тот, который будет забирать файлы - будет запускать свою rsync из планировщика.

На источнике с помощью vi ;-) создаем /etc/rsyncd.conf
use chroot=false
strict modes=false
uid=%RSYNC_USER_NAME%
gid=*
hosts allow = 192.168.0.1
transfer logging=yes
log format=%h %o %f %l %b
log flie=/var/log/rsync.log
motd file=/etc/rsync.motd

[Section]
path=/cygdrive/c/Новая папка/
transfer logging=yes

Можно использовать пробелы и русские буквы - текущая версия cygwin это позволяет, она в UTF-8. Но файл нужно создавать vi, тогда все ок. По поводу пробелов много обсуждения в сети. Резюме - все работает, только в конце не забываем слэш. Кавычек ни одинарных, ни двойных не нужно. А вот конечные пробелы удаляются.

Потом на источнике запускаем команду, которая вставляет запуск rsync в сервисы.
cygrunsrv --install "rsyncd" --path /usr/bin/rsync --args "--daemon --no-detach" \
--desc "Starts a rsync daemon for accepting incoming rsync connections" --disp "Rsync Daemon" --type auto

Ну, на получателе информации запускаем нечто вроде:
rsync --verbose --delete --progress -a --bwlimit=50K 192.168.0.100::Section "/cygdrive/c/Data/Куда сохранять/"


Вот тут кавычки нужны, двойные.

Ну и отдельная песня, как это запустить из планировщика. У меня получилось через cmd, запускающего bash c параметрами.
По-хорошему, нужно установить еще и cron, т.к. он удобнее и гибче и может запускать rsync нативно.

25 мар. 2014 г.

Password never expires will override any password expiration policy

Enabling "Password never expires" will override any password expiration policy you configure in Group Policy.
But you can configure this setting much faster, without using dsa.msc.
To list all user accounts with "Password never expires" set:
dsquery *  -filter "(&(objectCategory=person)
(userAccountControl:1.2.840.113556.1.4.803:=65536))" -limit 0
To disable the setting for these users:
dsquery *  -filter "(&(objectCategory=person)
(userAccountControl:1.2.840.113556.1.4.803:=65536))" -limit 0 |
 dsmod user -pwdneverexpires no

(c) serverfault.com

Important:
When Basic authentication or forms-based authentication is used with Outlook Web App, the Change Password feature may not work correctly when a user uses a password that includes extended ASCII or Unicode characters. This happens because passwords that use extended ASCII or Unicode characters aren't transmitted correctly between IIS and some Web browsers. We recommend that Outlook Web App users use only ASCII characters if they'll be using the Change Password feature in Outlook Web App.

7 нояб. 2013 г.

Перестановка колонок, выделение Ф.И.О из ФИО

Фокус еще в том, что исходный файл был DBF-ом, поэтому данные с 3 строки попадают в 1-ю в назначение (чтобы не трогать заголовки колонок)
Sub ConvertDBF()
    Sheets("DST").Columns("A:A").ColumnWidth = 3
    Sheets("DST").Columns("B:B").ColumnWidth = 5
    Sheets("DST").Columns("B:B").NumberFormat = "@"
    Sheets("DST").Columns("C:C").ColumnWidth = 5
    Sheets("DST").Columns("D:D").ColumnWidth = 6
    Sheets("DST").Columns("E:E").ColumnWidth = 8
    Sheets("DST").Columns("F:F").ColumnWidth = 23
    Sheets("DST").Columns("G:G").ColumnWidth = 23
    Sheets("DST").Columns("H:H").ColumnWidth = 23
    Sheets("DST").Columns("I:I").ColumnWidth = 21
    Sheets("DST").Columns("J:J").ColumnWidth = 12
    i = 3
    Do
        If Sheets("SRC").Cells(i, 5).Value = "" Then
            Exit Do
        End If
        Sheets("DST").Cells(i - 2, 1) = Sheets("SRC").Cells(i, 4)
        Sheets("DST").Cells(i - 2, 2) = "002"
        Sheets("DST").Cells(i - 2, 3) = "21"
        Sheets("DST").Cells(i - 2, 4) = Sheets("SRC").Cells(i, 6)
        Sheets("DST").Cells(i - 2, 5) = Sheets("SRC").Cells(i, 7)
        FIO = Trim(Sheets("SRC").Cells(i, 5))
        FirstSpacePos = InStr(1, FIO, " ", vbTextCompare)
        If FirstSpacePos > 0 Then
              Sheets("DST").Cells(i - 2, 6) = Left(FIO, FirstSpacePos - 1)
        End If
        SecondSpacePos = InStr(FirstSpacePos + 1, FIO, " ", vbTextCompare)
        If SecondSpacePos > 0 Then
              Sheets("DST").Cells(i - 2, 7) = Mid(FIO, FirstSpacePos + 1, SecondSpacePos - FirstSpacePos)
              Sheets("DST").Cells(i - 2, 8) = Mid(FIO, SecondSpacePos + 1)
        End If
        Sheets("DST").Cells(i - 2, 9) = Sheets("SRC").Cells(i, 14)
        Sheets("DST").Cells(i - 2, 10) = Sheets("SRC").Cells(i, 12)
    

        i = i + 1
    Loop
End Sub

2 сент. 2013 г.

Эвакуация автомобиля с Амуркабеля

Вот так теперь выглядит ГСК дяди Коли. Едва уговорили вывезти машину к нам.
Воды по край сапог. Пробираться можно только по краю.
В воде лежит шланг от помпы. Мы думали, что это они нам накачали. Нет. Это Красная речка к нам пришла. За гаражами речка вровень с двором ГСК.
Качают из канализации дома вдоль ул.Союзная (под 90 градусов к дому дяди Коли). Палатка стоит. В ней место для отдыха помпосмотрителя.
В подвале, видимо, полно воды, т.к. на улице сидели 2 белые кошки. Когда мы подошли - замяукали жалобно, но не убежали. Видимо, слегка одурели от того, что дома у них внезапно не стало. Машину своим ходом выгонять не рискнули, Никита вытащил Деликой. Пробег, кстати у нее меньше 1500 км - новая (но дверьми хлопать надо все равно сильно - автоВАЗ). А цвет ГИБДД определил как серо-сине-зеленый. Привет Люсе в алмазах!

1 авг. 2013 г.

Округление в выделенном диапазоне, Excel

Sub MyRoundRange()
    For Each cell In Selection
        cell.Value = WorksheetFunction.Round(cell.Value, 0)
    Next cell
End Sub

19 июн. 2013 г.

Вывод из Excel в файл

Любят бухгалтера все делать в Excel.А Диасофт 4х4 грузит из текстовых файлов.
Const BASE = 9000

Sub Макрос1()
    Dim fs, f
    Set fs = CreateObject("Scripting.FileSystemObject")
    Set f = fs.OpenTextFile("c:\clients.txt", 2, 8)

    i = 1
    Do
        If Cells(i, 1).Value = "" Then
            Exit Do
        End If
        f.WriteLine ("%КЛИЕНТ")
        f.WriteLine ("ИМЯ1      :" + Mid(Cells(i, 1).Value, 1, 40))
        f.WriteLine ("ИМЯ2      :" + Mid(Cells(i, 1).Value, 41, 40))
        f.WriteLine ("ИМЯ3      :" + Mid(Cells(i, 1).Value, 81, 40))
        f.WriteLine ("ИМЯ4      :" + Mid(Cells(i, 1).Value, 121, 40))
        f.WriteLine ("ТИП       :Ю")
        f.WriteLine ("АДРЕС1    :")
        f.WriteLine ("АДРЕС2    :")
        f.WriteLine ("ТЕЛЕФОН1  :")
        f.WriteLine ("ТЕЛЕФОН2  :")
        f.WriteLine ("КОД       :" + Trim(Str(i + BASE)))
        f.WriteLine ("ИНН       :" + Trim(Str(Cells(i, 2).Value)))
        f.WriteLine ("КПП       :" + Trim(Str(Cells(i, 3).Value)))
        f.WriteLine ("ГРУППА    :Юридические лица")
        f.WriteLine ("ДЕЙСТВИЕ  :Add")
        f.WriteLine ("%END")
        i = i + 1
    Loop
    f.Close
End

End Sub

5 июн. 2013 г.

ED206 - поиск внутри файла

Ищем внутри файлов слово ED206, те файлы, в которых находим, копируем в специально отведенное место.
grep -c "ED206" *.ED0| gawk "{print \"cp \"$1\" ED206/\"$1 }" |
 sed -e "/........\....:0/d" -e "s/\(........\....\)\(:1\)/\1/g"|
 cmd.exe

29 апр. 2013 г.

Открытие сезона. Мост на Уссурийский остров.

Открыл сезон, прокатив первые 50 километров, съездил к новому мосту. Моста еще нет, но опоры уже стоят. Постоянно по новой дороге ездит народ, интересуется. На указателе уже "Пограничный переход" - только речку надо перепрыгнуть.
Указатель в никуда

Дорога в никуда

Опоры моста

А тут был наплавной мост.

Excel из PHP

Есть система ведения распоряжений по курсам валют в обменниках. Обеспечивает ввод, печать, подтверждение курсов. Внезапно старшие товарищи решили нас осчастливить и обеспечить "автоматическую" загрузку курсов в Диасофт 5NT. Пришлось для получения требуемого к загрузке файла в формате MS Excel научиться изготавливать из CSV XLS.
 include_once "Spreadsheet/Excel/Writer.php";
 $xls =& new Spreadsheet_Excel_Writer();

 $name=$_GET['rasp'];
 $xls->send("KURS_".substr($name,0,3)."_".substr($name,7).".xls");
 $f = fopen($name, "rt") or die("Ошибка!");
 $sheet =& $xls->addWorksheet('Распоряжение');
 $format =& $xls->addFormat();
 $format->setColor("black");
 $dateFmt =& $xls->addFormat();
 $dateFmt->setColor("black");
 $dateFmt->setNumFormat("D MMMM,YYYY");
 $sheet->setColumn(0,5,20);
 for ($i=0; $data=fgetcsv($f,1000,","); $i++){
        $sheet->writeString(2, 0, "Филиал банка в г.Москве", $format);
        $sheet->writeString(4, 0, "Приказ № ".$data[0], $format);
        $sheet->writeString(6, 3, $data[2], $dateFmt);
        $sheet->writeString(12, 0, "Доллары США:", $format);
 $sheet->writeString(13, 0, "покупка -", $format);
 $sheet->writeString(13, 1, $data[3], $format);
 $sheet->writeString(13, 3, "продажа -", $format);
 $sheet->writeString(13, 4, $data[4], $format);
 $sheet->writeString(15, 0, "Евро:", $format);
 $sheet->writeString(16, 0, "покупка -", $format);
 $sheet->writeString(16, 1, $data[6], $format);
 $sheet->writeString(16, 3, "продажа -", $format);
 $sheet->writeString(16, 4, $data[7], $format);
 $sheet->writeString(18, 0, "Английские фунты стерлингов:", $format);
 $sheet->writeString(19, 0, "покупка -", $format);
 $sheet->writeString(19, 1, $data[9], $format);
 $sheet->writeString(19, 3, "продажа -", $format);
 $sheet->writeString(19, 4, $data[10], $format);
 $sheet->writeString(21, 0, "Швейцарские франки:", $format);
 $sheet->writeString(22, 0, "покупка -", $format);
 $sheet->writeString(22, 1, $data[12], $format);
 $sheet->writeString(22, 3, "продажа -", $format);
 $sheet->writeString(22, 4, $data[13], $format);
 $sheet->writeString(26, 1, "USD", $format);
 $sheet->writeString(26, 2, "EUR", $format);
 $sheet->writeString(26, 3, "GBP", $format);
 $sheet->writeString(26, 4, "CHF", $format);
 $sheet->writeString(27, 0, "USD", $format);
 $sheet->writeString(28, 0, "EUR", $format);
 $sheet->writeString(29, 0, "GBP", $format);
 $sheet->writeString(30, 0, "CHF", $format);
 $sheet->writeString(27, 1, "X", $format);
 $sheet->writeString(27, 2, $data[16], $format); //USD-EUR
 $sheet->writeString(27, 3, "0.00", $format);
 $sheet->writeString(27, 4, "0.00", $format);
 $sheet->writeString(28, 1, $data[15], $format); //EUR-USD
 $sheet->writeString(28, 2, "X", $format);
 $sheet->writeString(28, 3, "0.00", $format);
 $sheet->writeString(28, 4, "0.00", $format);
 $sheet->writeString(29, 1, "0.00", $format);
 $sheet->writeString(29, 2, "0.00", $format);
 $sheet->writeString(29, 3, "X", $format);
 $sheet->writeString(29, 4, "0.00", $format);
 $sheet->writeString(30, 1, "0.00", $format);
 $sheet->writeString(30, 2, "0.00", $format);
 $sheet->writeString(30, 3, "0.00", $format);
 $sheet->writeString(30, 4, "X", $format);
 $sheet->writeString(35, 0, $data[17], $format);
 $sheet->writeString(35, 3, $data[18], $format);
 $sheet->writeString(36, 0, $data[19], $format);
 $sheet =& $xls->addWorksheet('Приложение');
 $sheet->writeString(0,5,$data[2]);
 for($i=0;$i<3;$i++){
         $sheet->writeString($i+2,3,$data[1]); //time of the day
 }
 $sheet->writeString(2,5,"Ф-Л");
 $sheet->writeString(3,5,"ДО 1");
 $sheet->writeString(4,5,"ДО 2");

 }
        fclose($f);
 $xls->close();
 exit;

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.