如何在 运行 时间在 TFdMemTable 中创建查找字段

How to create a look up field in TFdMemTable at run time

我正在尝试在 运行 时在 TFDMemTable 中创建一个新字段,该字段必须是 Combobox,我想查找 Combobox 从秒 TFDMemTable.
我怎样才能做到这一点?
这是我需要的示例,我有一个主要 table 和一个次要 table,我试图在主要 table 中有一个字段,其中包含次要 [=24] 中的项目=].
我尝试做这样的事情:

//First i try creating the second table with the values for the combobox
FDMemTableQualityLiterals.FieldDefs.Add('QualityID', ftInteger, 0, false);
FDMemTableQualityLiterals.FieldDefs.Add('IdValue', ftString, 20, false);
FDMemTableQualityLiterals.CreateDataSet;

FDMemTableQualityLiterals.Open;
FDMemTableQualityLiterals.AppendRecord([1, '480p']);
FDMemTableQualityLiterals.AppendRecord([2, '720p']);
FDMemTableQualityLiterals.AppendRecord([3, '1080p']);


// then i try to create the main table with a few field including the qualityID field
FDMemTable1.FieldDefs.Add('ID', ftInteger, 0, false);
FDMemTable1.FieldDefs.Add('Name', ftString, 30, false);
FDMemTable1.FieldDefs.Add('QualityID', ftInteger, 0, false);
FDMemTable1.CreateDataSet;
FDMemTable1.Close;
//i try to link/create a new field like qualityID that has literal values instead of an id
CreateLookupField(TDataset(FDMemTable1), 'QualityLookup', TDataset(FDMemTableQualityLiterals), 'QualityID', 'QualityID', 'IdValue');
FDMemTable1.CreateDataSet;

FDMemTable1.open;
FDMemTable1.AppendRecord([0, 'item1', 1]);
FDMemTable1.AppendRecord([1, 'item2', 2]);
FDMemTable1.AppendRecord([2, 'item3', 3]);
// i use this code to show the result in devExpress
cxGrid1DBTableView1.DataController.DataSource := DataSource1;
cxGrid1DBTableView1.DataController.CreateAllItems();


Procedure TForm1.CreateLookupField( ATable: TDataSet; AFieldName: String; ALookupDataset: TDataset; AKeyfields: String; ALookupKeyfields: String; ALookupResultField : String);
Var
  I : Integer;
  NewField : TField;
Begin
  with ATable do begin
    if FieldDefs.Updated = False then
      FieldDefs.Update;
    If FindField(AFieldName) = Nil then
    begin
      NewField := TStringField.Create(ATable);
      NewField.FieldName := AFieldName;
      NewField.KeyFields := AKeyFields;
      NewFIeld.LookupDataSet := ALookupDataset;
      NewField.LookupKeyFields := ALookupKeyFields;
      NewField.LookupResultField := ALookupResultField;
      NewField.FieldKind := fkLookup;
      NewField.Dataset := ATable;
    end;
  end;
End;

但它不起作用,我收到一条错误消息说 qualityID 不存在,即使我们排除了错误,这种方法是否正确?这是这样做的方法吗?

TFieldDefs 是字段定义列表而不是字段列表,CreateDataSet 方法从 TFieldDefs 创建字段列表,但是当您关闭数据集时,字段列表将被清除。

要创建查找字段,数据集必须关闭,关闭的数据集有一个空字段列表,但您在创建查找字段时需要这些字段!。所以你应该为一个封闭的数据集手动创建你的字段列表,这样做:

var
 I : Integer;
begin
  FDMemTable1.FieldDefs.Add('ID', ftInteger, 0, false);
  FDMemTable1.FieldDefs.Add('name', ftString, 30, false);
  FDMemTable1.FieldDefs.Add('QualityID', ftInteger, 0, false);

  FDMemTable1.CreateDataSet; //This is unnecessary
  FDMemTable1.Close;

  for I := 0 to FDMemTable1.FieldDefs.Count - 1 do
   begin
    if FDMemTable1.FindField(FDMemTable1.FieldDefs[i].Name) = Nil then
     FDMemTable1.FieldDefs.Items[i].CreateField(FDMemTable1);
   end;

  CreateLookupField(TDataset(FDMemTable1), 'QualityLookup', TDataset(FDMemTableQualityLiterals), 'QualityID', 'QualityID', 'IdValue');
  FDMemTable1.CreateDataSet;



  //FDMemTable1.open; //not need to `FDMemTable1.open` after `FDMemTable1.CreateDataSet`, `CreateDataSet` method sets Active = True 
  FDMemTable1.AppendRecord([0, 'Ali', 1]);
  FDMemTable1.AppendRecord([1, 'Ali2', 2]);
  FDMemTable1.AppendRecord([2, 'Ali3', 3]);
  //FDMemTable1.AppendRecord([1, 'Ali', 1, 1]);
  //FDMemTable1.AppendRecord([1, 'Ali']);
  //FDMemTable1.Close;

//  FDMemTable1.CreateDataSet;
//  cxGrid1DBTableView1.DataController.DataSource := DataSource1;

  //FDMemTable1.Active := true;
//  cxGrid1DBTableView1.DataController.CreateAllItems();
end;