I am designing a program using a three level clientdataset, top level: cdsMaster with two nested levels: cdsTables & cdsNotes. In use the program should create the structure and post one record in cdsmaster at runtime. My intent is that the user will then populate the cdsTables and cdsNotes fields either by providing input in a DBgrid or by selecting previously saved files using cdsTables.LoadFromFile & cdsSavetoFile methods. I want to skip the Master level data and save/load the records at the cdsTables level (including its cdsNotes) with each Table being stored in a separate file. Each time a user selected a file containing the cdsTables w/ nested cdsNotes data, it must be added to the cdsMaster as a new cdsTables record. A sample of the clientdataset structure follows, but does not include the many fields actually contained in the nested levels.
unit datamod_u;
interface
uses
System.SysUtils, System.Classes, Data.DB, Datasnap.DBClient;
type
TDataMod = class(TDataModule)
cdsMaster: TClientDataSet;
cdsTable: TClientDataSet;
cdsNotes: TClientDataSet;
procedure DataModuleCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure DefinecdsMaster;
procedure DefineCdsTable;
procedure LoadTable (fname: string);
procedure SaveTable (fname: string);
end;
var
DataMod: TDataMod;
implementation
{%CLASSGROUP 'Vcl.Controls.TControl'}
{$R *.dfm}
procedure TDataMod.DefineCdsMaster;
begin
with TstringField.Create(Self) do
begin
Name := 'cdsMstrName';
FieldKind := fkData;
FieldName := 'Name';
DataSet := cdsMaster;
end;
with TDataSetField.Create(Self) do
begin
Name := 'cdsMstrTbls';
FieldKind := fkData;
FieldName := 'Tables';
DataSet := cdsMaster;
// Required := True;
Visible := false;
end;
end;
procedure TDataMod.DefineCdsTable;
begin
cdsTable.DataSetField := TDataSetField(cdsMaster.FieldByName('Tables'));
with TstringField.Create(Self) do
begin
Name := 'cdsTblName';
FieldKind := fkData;
FieldName := 'Tbl Name';
DataSet := cdsTable;
Required := false;
end;
with TDataSetField.Create(Self) do
begin
Name := 'cdsTblNotes';
FieldKind := fkData;
FieldName := 'Notes';
DataSet := cdsTable;
end;
cdsNotes.DataSetField := TDataSetField(cdsTable.FieldByName('Notes'));
with TstringField.Create(Self) do
begin
Name := 'cdsNote';
FieldKind := fkData;
FieldName := 'Note';
DataSet := cdsNotes;
end;
end;
procedure TDataMod.DataModuleCreate(Sender: TObject);
begin
DefineCdsMaster;
DefineCdsTable;
cdsMaster.CreateDataSet;
cdsMaster.edit;
cdsMaster.FieldByName('Name').AsString := 'MasterList';
cdsMaster.post;
end;
end.
Cary Jensen's book 'Delphi in Depth, Clientdatsets 2nd Edition' indicates that the SavetoFile and LoadfromFile methods can only be used at the top level not the nested levels. So the question becomes how to best save/load the nested level data to files. One method may be to create a temporary clientdataset with the same structure as the nested levels (cdsTables & cdsNotes) of the cdsMaster and copy each record field to the temporary component so that I can then use the SavetoFile/LoadfromFile methods. That seems a bit inelegant. I have been unable to find examples that illustrate this type of operation in practice. Can anyone provide an example of how this could be done?