Kann man die DBGrid, DBEdit usw. auch ohne BDE nutzen ? Ab Delphi 3 ist das ohne große Probleme möglich. Alle DBxxxx greifen auf eine TDataSet zu. Diese ist nicht zwingend mit der BDE verbunden. Eine einfache Lösung für kleine Projekte besteht in der Nutzung der TMemoryData der RxTools. TMemoryData verwaltet eine Datenbank im Speicher. Nur um das Speichern und Laden von der Platte muß man sich selbst kümmern. Die beiden Beispielroutienen zeigen das Laden bzw. Speichern einer TDataSet in einen Stream. Dabei wird sogar auch die Struktur der Datenbank gespeichert. Damit ist die spätere Erweiterung der Datenbank um Felder möglich.
const PufferGroesse = 1024 * 8;
Kennung = 'wlsoft99 Version1';
procedure DataSetSaveToStream(Stream :TStream; DataSet :TDataSet);
var r :TWriter;
z :integer;
B :TBookMark;
i :integer;
oldDisabled :boolean;
begin
DataSet.CheckBrowseMode;
oldDisabled:=DataSet.ControlsDisabled;
if not oldDisabled then
DataSet.DisableControls;
R:=TWriter.Create(Stream,PufferGroesse);
try
R.WriteString(Kennung);
i:=0;
for z:= 0 to DataSet.FieldCount-1 do
with DataSet.Fields[z] do
if FieldKind = fkData then inc(i);
R.WriteInteger(i);
for z:= 0 to DataSet.FieldCount-1 do
with DataSet.Fields[z] do
if FieldKind = fkData then begin
R.WriteString(FieldName);
i:=ord(DataType);
R.WriteInteger(i);
end;
B:=DataSet.GetBookmark;
try
DataSet.First;
r.WriteListBegin;
while not DataSet.Eof do begin
for z:= 0 to DataSet.FieldCount-1 do
with DataSet.Fields[z] do
if FieldKind = fkData then begin
r.WriteBoolean(isNull);
if not isNull then
case Datatype of
ftString : r.WriteString(trim(AsString));
ftSmallint,
ftInteger,
ftWord : r.WriteInteger(asInteger);
ftBoolean : r.WriteBoolean(asBoolean);
ftFloat : r.WriteFloat(AsFloat);
ftCurrency : r.WriteCurrency(AsCurrency);
ftDate,
ftTime,
ftDateTime : r.WriteDate(AsDateTime);
else r.WriteString('');
end;
end;
DataSet.Next;
end;
r.WriteListEnd;
finally
DataSet.GotoBookmark(B);
DataSet.FreeBookmark(B);
end;
finally
R.Free;
if not oldDisabled then
DataSet.EnableControls;
end;
end;
procedure DataSetLoadFromStream(Stream :TStream; DataSet :TDataSet);
var r :TReader;
i,
z :integer;
d :TDateTime;
w :array of Record
F :TField;
T :TFieldType;
end;
oldDisabled :boolean;
begin
DataSet.CheckBrowseMode;
oldDisabled:=DataSet.ControlsDisabled;
if not oldDisabled then
DataSet.DisableControls;
r:=TReader.Create(Stream,PufferGroesse);
try
if r.ReadString<>Kennung then
raise EStreamError.Create('Falsche Version der Datenbank');
i:=r.ReadInteger;
SetLength(w,i);
for z:=0 to i-1 do begin
w[z].F:=DataSet.FindField(r.ReadString);
w[z].T:=TFieldType(r.ReadInteger);
end;
r.ReadListBegin;
while not r.EndOfList do begin
DataSet.Append;
for z:=0 to i-1 do begin
if not r.ReadBoolean then
case w[z].T of
ftString : if w[z].F<>nil then
w[z].F.AsString:=r.readString
else
r.ReadString;
ftSmallint,
ftInteger,
ftWord : if w[z].F<>nil then
w[z].F.AsInteger:= r.readInteger
else
r.readInteger;
ftBoolean : if w[z].F<>nil then
w[z].F.AsBoolean:= r.ReadBoolean
else
r.readBoolean;
ftFloat : if w[z].F<>nil then
w[z].F.AsFloat:= r.ReadFloat
else
r.readFloat;
ftCurrency : if w[z].F<>nil then
w[z].F.AsCurrency:= r.ReadCurrency
else
r.readCurrency;
ftDate,
ftTime,
ftDateTime : begin
d:=r.ReadDate;
if (w[z].F<>nil) and (d<>0) then
w[z].F.AsDateTime:= d;
end;
else r.readString;
end;
end;
end;
r.ReadListEnd;
if DataSet.State = dsInsert then
Dataset.Post;
DataSet.First;
finally
r.Free;
if not oldDisabled then
DataSet.EnableControls;
end;
end;
|