简体   繁体   English

如何在运行时创建TDataSet查找字段?

[英]How to create a TDataSet Lookup Field at runtime?

I'm using TADODataSet (D7). 我正在使用TADODataSet (D7)。
I do not create persistent fields in design-mode with my DataSet. 我没有使用我的DataSet在设计模式下创建持久字段。

dsItems.CommandText := 'select ID, ItemName, UserIDCreate from Items';
dsUsers.CommandText := 'select  ID, LoginName from Users'; // lookup dataset

If I double-click on dsItems and "Add all fileds" and then click "New filed" and define my lookup Field, everything is working fine. 如果我双击dsItems并“添加所有文件”,然后单击“新建文件”并定义我的查找字段,一切正常。 The resulting dsItems should contain: ID, ItemName, UserIDCreate, LoginName_Lookup 生成的dsItems应包含: ID, ItemName, UserIDCreate, LoginName_Lookup

How can I avoid doing all this in design-time and add a Lookup Field after/or before (? not sure) the DataSet is opened. 如何在设计时避免完成所有这些操作,并在打开DataSet之后(或不确定)之前添加查找字段。

In other words: How do I emulate "Add all fileds" and then "New filed" to add lookup filed in run-time? 换句话说:如何模拟“添加所有文件”然后“新建文件”以在运行时添加查找文件?


NOTE: I get an Exception when running John's code from the IDE. 注意:从IDE运行John的代码时出现异常。 The Exception occurs when trying to open the DataSet: EOleException with message 'An unknown error has occured' . 尝试打开DataSet时发生异常: EOleException with message 'An unknown error has occured'

function TCustomADODataSet.LocateRecord (ADODB.pas) in line if FieldCount = 1 then FLookupCursor.Find... function TCustomADODataSet.LocateRecord (ADODB.pas) if FieldCount = 1 then FLookupCursor.Find...if FieldCount = 1 then FLookupCursor.Find...

I'm accepting the answer becouse the complied program is working. 我接受答案,因为已编译的程序正在运行。
It would be nice if someone could verify getting (or not) an Exception when runing form inside the IDE. 如果有人在IDE中运行表单时可以验证是否获得异常,那将是很好的。

The dataset cannot be opened to add a lookup field at runtime. 无法打开数据集以在运行时添加查找字段。

You'll also need to add whatever other fields you'll need to access as persistent fields as well, otherwise, they will be inaccessible. 您还需要添加您需要访问的任何其他字段作为持久字段,否则,它们将无法访问。 The procedures below should work. 以下程序应该有效。 However, I recommend that if you can, use queries and join your tables - it's a lot less coding, and much cleaner in my opinion. 但是,如果可以的话,我建议你使用查询并加入你的表格 - 它的编码要少得多,而且我认为更清晰。

procedure CreatePersistentFields(ADataset: TDataset);
Var
  i: Integer;
Begin
  ADataset.FieldDefs.Update;
  for I := 0 to ADataset.FieldDefs.Count - 1 do
     if ADataset.FindField(ADataset.FieldDefs[i].Name) = Nil then
       ADataset.FieldDefs.Items[i].CreateField(ADataset);
End;

Procedure 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;

procedure TForm1.Button1Click(Sender: TObject);
begin
  AdoDataset1.Close;
  CreatePersistentFields(TDataset(AdoDataset1));
  CreateLookupField(TDataset(AdoDataset1), 'EmployeeNameLook', TDataset(EmployeeTable), 'EmployeeID', 'EmployeeID', 'EmployeeName');
end;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM