Właśnie to sprawdzanie na razie realizowane w ten sposób:
Kopiuj
procedure TForm1.FWypelnijMemoClick(Sender: TObject);
unit Menu;
{$H-}
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ActnList,
TpPol, TACCESS;
type
TForm1 = class(TForm)
Memo1: TMemo;
Fzapisz: TButton;
ActionList1: TActionList;
ActionESC: TAction;
FWypelnijMemo: TButton;
procedure FzapiszClick(Sender: TObject);
procedure ActionESCExecute(Sender: TObject);
procedure FWypelnijMemoClick(Sender: TObject);
private
A1: array[1..300] of string;
Ind:word;
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ActionESCExecute(Sender: TObject);
begin
close;
end;
procedure TForm1.FWypelnijMemoClick(Sender: TObject);
const
AngStr : ShortString = 'A'+ 'C'+ 'E'+ 'L'+ 'N'+ 'O'+ 'S'+ 'Z'+ 'Z'+ 'a'+ 'c'+ 'e'+ 'l'+ 'n'+ 'o'+ 's'+ 'z'+ 'z';
IsoStr : ShortString = #161+#198+#202+#163+#209+#211+#166+#172+#175+#177+#230+#234+#179+#241+#243+#182+#188+#191;
WinStr : ShortString = #165+#198+#202+#163+#209+#211+#140+#143+#175+#185+#230+#234+#179+#241+#243+#156+#159+#191;
LatStr : ShortString = #164+#143+#168+#157+#227+#224+#151+#141+#189+#165+#134+#169+#136+#228+#162+#152+#171+#190;
MazStr : ShortString = #143+#149+#144+#156+#165+#163+#152+#160+#161+#134+#141+#145+#146+#164+#162+#158+#166+#167;
AngStrA : AnsiString = 'A'+ 'C'+ 'E'+ 'L'+ 'N'+ 'O'+ 'S'+ 'Z'+ 'Z'+ 'a'+ 'c'+ 'e'+ 'l'+ 'n'+ 'o'+ 's'+ 'z'+ 'z';
IsoStrA : AnsiString = #161+#198+#202+#163+#209+#211+#166+#172+#175+#177+#230+#234+#179+#241+#243+#182+#188+#191;
WinStrA : AnsiString = #165+#198+#202+#163+#209+#211+#140+#143+#175+#185+#230+#234+#179+#241+#243+#156+#159+#191;
LatStrA : AnsiString = #164+#143+#168+#157+#227+#224+#151+#141+#189+#165+#134+#169+#136+#228+#162+#152+#171+#190;
MazStrA : AnsiString = #143+#149+#144+#156+#165+#163+#152+#160+#161+#134+#141+#145+#146+#164+#162+#158+#166+#167;
type
MyAnsi= type AnsiString(1250);
TX_rec = record
ch1:char;
ch2:char;
ss1:string[30];
end;
TCharRec = record
case integer of
1:(Len:byte;
AA :array[1..255] of byte;
);
2:(
Tekst:string[255];
);
end;
function XXXXX(a:ShortString):ShortString;
begin
Result:='';
end;
var
ss,ss2: string;
p:byte;
X_rec:TX_rec;
CharRec:TCharRec;
ch:char;
nn:word;
zz:longint;
ss1:string[100];
ssU:UnicodeString;
ssA:MyAnsi;
ssS:string[100];
begin
fillChar(A1, sizeOf(A1),0);
ind:=1;
Memo1.Clear;
Memo1.Lines.Add('Polskie litery ĄĘŚŻŹĆÓŁŃ ąęśżźćółń - wpis wprost z kodu');
A1[ind]:='Polskie litery ĄĘŚŻŹĆÓŁŃ ąęśżźćółń - wpis wprost z kodu'; inc(ind);
ss :='Polskie litery ĄĘŚŻŹĆÓŁŃ ąęśżźćółń - string';
ssU:='Polskie litery ĄĘŚŻŹĆÓŁŃ ąęśżźćółń - UnicodeString';
ssA:='Polskie litery ĄĘŚŻŹĆÓŁŃ ąęśżźćółń - AnsiString';
ssS:='Polskie litery ĄĘŚŻŹĆÓŁŃ ąęśżźćółń - ShortString [100]';
Memo1.Lines.Add(ss);
A1[ind]:=ss; inc(ind);
Memo1.Lines.Add(ssU);
A1[ind]:=ssU; inc(ind);
Memo1.Lines.Add(ssA);
A1[ind]:=ssA; inc(ind);
Memo1.Lines.Add(ssS);
A1[ind]:=ssS; inc(ind);
Memo1.Lines.Add('1234567890123456789012345678901234567890');
A1[ind]:='1234567890123456789012345678901234567890'; inc(ind);
p:=Pos('ą',ss);
Memo1.Lines.Add('Poz litery "ą" w string = '+IntToStr(p) );
A1[ind]:='Poz litery "ą" w string = '+IntToStr(p); inc(ind);
p:=Pos('ą',ssU);
Memo1.Lines.Add('Poz litery "ą" w UnicodeString = '+IntToStr(p) );
A1[ind]:='Poz litery "ą" w UnicodeString = '+IntToStr(p); inc(ind);
p:=Pos('ą',ssA);
Memo1.Lines.Add('Poz litery "ą" w AnsiString = '+IntToStr(p) );
A1[ind]:='Poz litery "ą" w AnsiString = '+IntToStr(p); inc(ind);
p:=Pos('ą',ssS);
Memo1.Lines.Add('Poz litery "ą" w ShortString = '+IntToStr(p) );
A1[ind]:='Poz litery "ą" w ShortString = '+IntToStr(p); inc(ind);
Memo1.Lines.Add('----- const ShortString ------');
A1[ind]:='----- const ShortString ------'; inc(ind);
Memo1.Lines.Add('Ang='+AngStr);
A1[ind]:='Ang='+AngStr; inc(ind);
Memo1.Lines.Add('Win='+WinStr);
A1[ind]:='Win='+WinStr; inc(ind);
Memo1.Lines.Add('Iso='+IsoStr);
A1[ind]:='Iso='+IsoStr; inc(ind);
Memo1.Lines.Add('----- const AnsiString ------');
A1[ind]:='----- const AnsiString ------'; inc(ind);
Memo1.Lines.Add('Ang='+AngStrA);
A1[ind]:='Ang='+AngStrA; inc(ind);
Memo1.Lines.Add('Win='+WinStrA);
A1[ind]:='Win='+WinStrA; inc(ind);
Memo1.Lines.Add('Iso='+IsoStrA);
A1[ind]:='Iso='+IsoStrA; inc(ind);
Memo1.Lines.Add('----- ss (string) ------');
A1[ind]:='----- ss (string) ------'; inc(ind);
ss1:='';
ss2:='';
for nn := 1 to length(ss) do begin
ch:=ss[nn];
zz:=Ord(Ch);
Memo1.Lines.Add(ch+', sizeOf:'+IntToStr(sizeOf(ss[nn]))+', Ord:'+IntToStr(zz)+', Chr:'+Chr(zz) );
A1[ind]:=ch+', sizeOf:'+IntToStr(sizeOf(ss[nn]))+', Ord:'+IntToStr(zz)+', Chr:'+Chr(zz); inc(ind);
ss1:=ss1+ch;
ss2:=ss2+ch;
end;
Memo1.Lines.Add('----- ssA (Ansi) ------');
A1[ind]:='----- ssA (Ansi) ------'; inc(ind);
for nn := 1 to length(ssA) do begin
Memo1.Lines.Add(ssA[nn]+
', sizeOf:'+IntToStr(sizeOf(ssA[nn]))+
', Ord:'+IntToStr(Ord(ssA[nn]))+
', Chr:'+Chr(Ord(ssA[nn]))+
', ChrA:'+MyAnsi(AnsiChar(ssA[nn])) );
A1[ind]:=ssA[nn]+
', sizeOf:'+IntToStr(sizeOf(ssA[nn]))+
', Ord:'+IntToStr(Ord(ssA[nn]))+
', Chr:'+Chr(Ord(ssA[nn]))+
', ChrA:'+MyAnsi(AnsiChar(ssA[nn])); inc(ind);
end;
Memo1.Lines.Add('Code Page:'+IntToStr(StringCodePage(ssA)) );
A1[ind]:='Code Page:'+IntToStr(StringCodePage(ssA)); inc(ind);
Memo1.Lines.Add('----- ssS (Short) ------');
A1[ind]:='----- ssS (Short) ------'; inc(ind);
for nn := 1 to length(ssS) do begin
Memo1.Lines.Add(ssS[nn]+
', sizeOf:'+IntToStr(sizeOf(ssS[nn]))+
', Ord:'+IntToStr(Ord(ssS[nn]))+
', Chr:'+Chr(Ord(ssS[nn]))
);
A1[ind]:=ssS[nn]+
', sizeOf:'+IntToStr(sizeOf(ssS[nn]))+
', Ord:'+IntToStr(Ord(ssS[nn]))+
', Chr:'+Chr(Ord(ssS[nn])); inc(ind);
end;
Memo1.Lines.Add('Code Page:'+IntToStr(StringCodePage(ssS)) );
A1[ind]:='Code Page:'+IntToStr(StringCodePage(ssS)); inc(ind);
Memo1.Lines.Add('ss1: '+ss1+', '+IntToStr(sizeOf(ss1))+', Length='+IntToStr(Length(ss1))+', bytelength='+IntToStr(ByteLength(ss1)) );
A1[ind]:='ss1: '+ss1+', '+IntToStr(sizeOf(ss1))+', Length='+IntToStr(Length(ss1))+', bytelength='+IntToStr(ByteLength(ss1)); inc(ind);
Memo1.Lines.Add('ss2: '+ss2+', '+IntToStr(sizeOf(ss2))+', Length='+IntToStr(Length(ss2))+', bytelength='+IntToStr(ByteLength(ss2)) );
A1[ind]:='ss2: '+ss2+', '+IntToStr(sizeOf(ss2))+', Length='+IntToStr(Length(ss2))+', bytelength='+IntToStr(ByteLength(ss2)); inc(ind);
Memo1.Lines.Add('---------');
A1[ind]:='---------'; inc(ind);
FillChar(X_rec, sizeOf(X_rec),0);
X_rec.ch1:='Ą';
X_rec.ch2:='A';
X_rec.ss1:='ĄĘŚŻŹĆÓŁŃąęśżźćółń';
Memo1.Lines.Add( IntToStr(Length(X_rec.ss1)) );
A1[ind]:=IntToStr(Length(X_rec.ss1)); inc(ind);
Memo1.Lines.Add( IntToStr(Length(X_rec.Ch1)) );
A1[ind]:=IntToStr(Length(X_rec.Ch1)); inc(ind);
Memo1.Lines.Add( IntToStr(Length(X_rec.Ch2)) );
A1[ind]:=IntToStr(Length(X_rec.Ch2)); inc(ind);
Memo1.Lines.Add( IntToStr(sizeOf(X_rec)) );
A1[ind]:=IntToStr(sizeOf(X_rec)); inc(ind);
Memo1.Lines.Add( IntToStr(sizeOf(X_rec.ch1)) );
A1[ind]:=IntToStr(sizeOf(X_rec.ch1)); inc(ind);
Memo1.Lines.Add( IntToStr(sizeOf(X_rec.ch2)) );
A1[ind]:=IntToStr(sizeOf(X_rec.ch2)); inc(ind);
Memo1.Lines.Add( IntToStr(sizeOf(X_rec.ss1)) );
A1[ind]:=IntToStr(sizeOf(X_rec.ss1)); inc(ind);
Memo1.Lines.Add('---------');
A1[ind]:='---------'; inc(ind);
Memo1.Lines.Add(copy(ss,1,20));
A1[ind]:=copy(ss,1,20); inc(ind);
ss2:='';
ss1:='';
Memo1.Lines.Add('---------');
A1[ind]:='---------'; inc(ind);
CharRec.Len:=5;
CharRec.AA[1]:=65;
CharRec.AA[2]:=66;
CharRec.AA[3]:=67;
CharRec.AA[4]:=68;
CharRec.AA[5]:=69;
ss:=CharRec.Tekst;
ss1:=CharRec.Tekst;
Memo1.Lines.Add(ss);
A1[ind]:=ss; inc(ind);
Memo1.Lines.Add(ss1);
A1[ind]:=ss1; inc(ind);
end;
procedure TForm1.FzapiszClick(Sender: TObject);
var
Lstr:TstringList;
FF : TextFile;
nn : longint;
begin
Memo1.Lines.SaveToFile('xxx.txt');
AssignFile(FF,'zzz.txt');
Rewrite(FF);
for nn := 0 to Memo1.Lines.Count - 1 do WriteLn(FF,Memo1.Lines[nn]);
CloseFile(FF);
AssignFile(FF,'yyy.txt');
Rewrite(FF);
for nn := 1 to ind do WriteLn(FF,A1[nn]);
CloseFile(FF);
end;
powoduje moje pytania.
Jeśli chodzi o bazę, to nie wnikając w szczegóły dlaczego, operacje na niej wykonywane są poprzez niskopoziomową funkcję BTRCALL o składni
FUNCTION BTRCALL(
operation : WORD;
VAR posblk;
VAR databuf;
VAR datalen : longInt;
VAR keybuf;
keylen : BYTE;
keynum : SHORTINT ) : SMALLINT; FAR; STDCALL;
Ten sposób obsługi powoduje, że muszę znać wielkość rekordu oraz jego bajtowe rozłożenie, ze względu na budowę indeksów. Indeksy są budowane poprzez wskazanie typu indeksu (integer, string itp), jego początku w strukturze bajtowej i długości. Na pytanie odnośnie komponentów, dlaczego nie są stosowane, odpowiedź jest taka, że do każdej wersji bazy (7.xx -11.xx) były one za każdym razem inne, bez zachowania wstecznej kompatybilności. Dlatego ich stosowanie w sytuacji, gdy użytkownicy mają całe spektrum wersji, nie wchodziło w grę, zwłaszcza, że koszt aktualizacji bazy przeważnie wynosił 70% ceny nowego produktu. Natomiast same bazy w tej technologii były zakładane od 1994 roku.
Ale nie chciałbym, aby temat zszedł na bazę danych, bo nie o to pytałem. Wątek rozpocząłem z przykładem pliku binarnego o zdefiniowanej strukturze, bo oddaje on sedno sprawy.
Oczywiście przeprowadzę jeszcze testy na konkretnych plikach utworzonych za pomocą BDS2006, aby wiedzieć jak się one zachowają pod D2010.
Na chwilę obecną wygląda na to, że:
- Trzeba zwrócić uwagę na pola typu Char w rekordzie i albo zamienić je na AnsiChar, albo na byte. Sam AnsiChar wymaga jeszcze sprawdzenia dla kodów ASCII powyżej 127.
- Definicja
ss:string[100];
powoduje zachowanie wielkości i typu zmiennej jako ShortString. Nie ma natomiast pewności jak zostaną w nim zapisane znaki ASCII >127
- Przypisanie ShortString-a lub AnsiStringa do Stringa powoduje uwagę kompilatora odnośnie możliwości utraty danych podczas konwersji.
Pozdrawiam