Page 1 of 1

Saving/restoring a dataset to/from a file

Posted: 18.07.2008, 08:32
by zippo
Hi!

I wonder if is there any way to save a Zeos TZQuery in any way and later restore it back. The possible ways can be a file, a stream, a comonent... etc.

Posted: 18.07.2008, 09:10
by sandeep_c24
If you have access to Clientdataset then you can save data to a file on disk and the load it from the disk.

Sandeep

Posted: 28.07.2008, 21:57
by zippo
It works - thank you!!!

Posted: 29.07.2008, 08:27
by Michael
Hi zippo, hi sandeep_c24,

could you give us a short example on how it works for all those of our community who can't imagine how to do that :wink: ... just a little code snippet ... thist would be great.

Many thanks in advance.

Michael.

Posted: 29.07.2008, 12:52
by zippo
Sure! For now I'll post the article I started from. I will post more code in few days.

http://www.scalabium.com/faq/dct0150.htm

Posted: 29.07.2008, 15:49
by trupka
Little note for those who use ClientDataset - you must deploy midas.dll with your app or include MidasLib unit into project source (in that case midas is staticaly linked)

Look at this example ...

Posted: 29.07.2008, 20:00
by patyi
Hi All !

I made this procedures a several jears ago, and use it succesfuly ...
(saved and restored dataset must bee identical !)

procedure QSaveToFile(DataSet: TDataSet; FileName: string; Separ: char=';');
var
i, r : integer;
t, s : string;
F : TextFile;
begin
AssignFile(F, FileName);
Rewrite(F);
r := DataSet.RecNo;
DataSet.DisableControls;
DataSet.First;
while not DataSet.Eof do begin
t := '';
for i := 0 to DataSet.FieldCount-2 do begin
s := DataSet.Fields.AsString;
s := StringReplace(s, Separ, ',', [rfReplaceAll]);
t := t+s+Separ;
end;
s := DataSet.Fields[DataSet.FieldCount-1].AsString;
s := StringReplace(s, Separ, ',', [rfReplaceAll]);
t := t+s;
WriteLn(F, t);
DataSet.Next;
end;
CloseFile(F);
DataSet.RecNo := r;
DataSet.EnableControls;
end;

procedure QLoadFromFile(DataSet: TDataSet; FileName: string; Separ: char=';');
var
i : integer;
t : string;
F : TextFile;
s : TStringList;
begin
DataSet.DisableControls;
AssignFile(F, FileName);
Reset(F);
while not Eof(F) do begin
ReadLn(F, t);
t := StringReplace(t, ',', '^', [rfReplaceAll]);
t := StringReplace(t, ' ', '~', [rfReplaceAll]);
t := StringReplace(t, Separ, ',', [rfReplaceAll]);
s := TStringList.Create;
s.CommaText := t;
if s.Count > 0 then begin
DataSet.Append;
for i := 0 to s.Count-1 do begin
t := s.Strings;
t := StringReplace(t, '~', ' ', [rfReplaceAll]);
t := StringReplace(t, '^', ',', [rfReplaceAll]);
DataSet.Fields.AsString := t;
end;
DataSet.Post;
end;
s.Free;
end;
CloseFile(F);
DataSet.First;
DataSet.EnableControls;
end;

Posted: 30.07.2008, 13:59
by zippo
Brilliant! I've modified the procedure for large text fields and if you agree I'll post it here.

Posted: 30.07.2008, 21:32
by patyi
Hi Zippo !

I'm very glad that You find it useful ... and of cours I'm agree to publish changes !

Posted: 04.08.2008, 18:48
by zippo
Ok, so there's the modified code:

Saving:

Code: Select all

procedure SaveDatasetToFile(DataSet: TDataSet; FileName: string; Separ: char=';');
var i, r : integer;
    Row, Fld : string;
    F : TextFile;
begin
  AssignFile(F, FileName);
  Rewrite(F);
  r := DataSet.RecNo;
  DataSet.DisableControls;
  DataSet.First;
  while not DataSet.Eof do begin
    Row := '';
    for i := 0 to DataSet.FieldCount-1 do begin
      Fld := DataSet.Fields[i].AsString;
      Fld := StringReplace(Fld, Separ, ',', [rfReplaceAll]);
      Fld := StringReplace(Fld, #10, '', [rfReplaceAll]);
      Fld := StringReplace(Fld, #13, '|', [rfReplaceAll]);
      if i < DataSet.FieldCount-1 then
        Row := Row+Fld+Separ
      else
        Row := Row+Fld;
    end;
    Row := Row+Fld;
    WriteLn(F, Row);
    DataSet.Next;
  end;
  CloseFile(F);
  DataSet.RecNo := r;
  DataSet.EnableControls;
end;

Loading:

Code: Select all

procedure LoadDatasetFromFile(DataSet: TDataSet; FileName: string; Separ: char=';');
var i : integer;
    Row, Fld : string;
    F : TextFile;
    RowFields : TStringList;
begin
  if not FileExists(FileName) then
    exit;

  DataSet.DisableControls;

  while not DataSet.Eof do begin
    DataSet.Delete;
  end;

  AssignFile(F, FileName);
  Reset(F);
  while not Eof(F) do begin
    ReadLn(F, Row);
    Row := StringReplace(Row, ',', '^', [rfReplaceAll]);
    Row := StringReplace(Row, ' ', '~', [rfReplaceAll]);
    Row := StringReplace(Row, Separ, ',', [rfReplaceAll]);
    RowFields := TStringList.Create;
    RowFields.CommaText := Row;
    if RowFields.Count > 0 then begin
      DataSet.Append;
      for i := 0 to RowFields.Count-1 do begin
        Fld := RowFields.Strings[i];
        Fld := StringReplace(Fld, '~', ' ', [rfReplaceAll]);
        Fld := StringReplace(Fld, '^', ',', [rfReplaceAll]);
        Fld := StringReplace(Fld, '|', #13#10, [rfReplaceAll]);
        DataSet.Fields[i].AsString := Fld;
      end;
    DataSet.Post;
    end;
    RowFields.Free;
  end;
  CloseFile(F);
  DataSet.First;
  DataSet.EnableControls;
end;

Posted: 04.08.2008, 21:26
by patyi
Hi Zippo !

Very nice !
I just want to notice one mistake in code if I fallow the logic correctly:

procedure SaveDatasetToFile(DataSet: TDataSet; FileName: string; Separ: char=';');
var i, r : integer;
Row, Fld : string;
F : TextFile;
begin
AssignFile(F, FileName);
Rewrite(F);
r := DataSet.RecNo;
DataSet.DisableControls;
DataSet.First;
while not DataSet.Eof do begin
Row := '';
for i := 0 to DataSet.FieldCount-1 do begin
Fld := DataSet.Fields.AsString;
Fld := StringReplace(Fld, Separ, ',', [rfReplaceAll]);
Fld := StringReplace(Fld, #10, '', [rfReplaceAll]);
Fld := StringReplace(Fld, #13, '|', [rfReplaceAll]);
if i < DataSet.FieldCount-1 then
Row := Row+Fld+Separ // not a last field, nead separator, OK
else
Row := Row+Fld; // this is the last field and not nead separator, OK
end;
Row := Row+Fld; // !!! it seems to bee surplus, it may duplicate last field !
WriteLn(F, Row);
DataSet.Next;
end;
CloseFile(F);
DataSet.RecNo := r;
DataSet.EnableControls;
end;

Best regard, Patyi !

Posted: 04.08.2008, 22:22
by zippo
Ops! Thank you ;)