delphitclientdatasetdelphi-12-athens

Nested datasets: TClientDataSet.DataSetField empty after CreateDataSet; nested set inactive after LoadFromFile


Old situation: Design time two nested TClientDataSets VertaalData and VertaalRegelsData, with field definitions etc., populated using LoadFromFile

New situation: Create the structure for these design time sets (now no properties filled in) at runtime, then use LoadFromFile with the same file. Code:

  with VertaalData do         // Nested dataset    https://stackoverflow.com/a/76337090/512728
  begin
     if Active then Close;
     FieldDefs.Clear;
     FieldDefs.Add(sVersion,ftString,11,false);  // s... are fieldname constants
     with FieldDefs.AddFieldDef do
     begin
        Name     := sTranslate;
        DataType := ftDataSet;
        ChildDefs.Add(sID,ftInteger);
        ChildDefs.Add(sTranslate,ftBoolean);
        ChildDefs.Add(STT_NL,ftString,250,false);   // STT also field name constants
        ChildDefs.Add(STT_EN,ftString,250,false);
        ChildDefs.Add(STT_DE,ftString,250,false);
        ChildDefs.Add(STT_XX,ftString,250,false);
     end;
     CreateDataSet;
     LoadFromFile(LLanguageFileName);
  end;  

What's different from the design time situation:

I added

VertaalRegelsData.DataSetField := TDataSetField(VertaalData.FieldByName(sTranslate));

behind the CreateDataSet ('field not known' if I try before), but that does not help for the state:
After the LoadFromFile, the top dataset is positioned at the first (and only) record and is in dsBrowse state, but the nested VertaalRegelsData is still dsInactive.

I tried (after the LoadFromFile):

Any suggestions?

This is a 64 bit Delphi 12 VCL app. Sample file is here (exp. 30 days)

Added 15 Aug:

FWIW The file was created in another program with:

     NewLanguageData.Post;  // In dsEdit state after conversion
     NewLanguageLineData.DisableControls;
     NewLanguageData.MergeChangeLog;
     NewLanguageData.SaveToFile(ChangeFileExt(SaveDialogLanguage.FileName, '.lng'));

I have another utility program to view these TClientDataSet saved files, that also chokes on the nested dataset not being open after LoadFromFile.


Solution

  • As long as you don't need to populate the datasets by code and always call LoadFromFile, you can omit all the code to create the field defs as well as the CreateDataSet call. The LoadFromFile will create the appropriate fields from the file content.

    To get both datasets populated, you create an AfterOpen event handler for the master dataset, which sets the DataSetField for for the detail dataset. Then simply call LoadFromFile.

    I achieved the desired result by dropping two TClientDataSet on a form and added these lines of code:

    procedure TForm860.Button1Click(Sender: TObject);
    begin
      VertaalData.LoadFromFile('c:\Users\Uwe\Downloads\TTTranslate.lng');
    end;
    
    procedure TForm860.VertaalDataAfterOpen(DataSet: TDataSet);
    begin
      VertaalRegelsData.DataSetField := VertaalData.FieldByName('TT_TRANSLATE') as TDataSetField;
    end;