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

时间:2017-06-23 01:53:17

标签: delphi firedac

我尝试在运行时在TFDMemTable内创建一个新字段,该字段必须是Combobox,我想查找Combobox的项目从第二个TFDMemTable开始 我怎样才能做到这一点?
这是我需要的样本,我有一个主表和一个辅助表,我试图在主表中有一个字段,其中包含来自辅助表的项目。
我尝试过这样的事情:

//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不存在,即使我们排除错误,这种方法是否正确?这是这样做的方法吗?

1 个答案:

答案 0 :(得分:4)

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

要创建LoockUp字段,必须关闭数据集,并且关闭的数据集具有空字段列表,但在创建查找字段时需要填写字段!因此,您应该为封闭的数据集手动创建字段列表,如下所示:

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;