如何在运行时向客户端数据集添加字段?

发布于 2024-10-16 13:42:52 字数 523 浏览 5 评论 0原文

我有一个 TClientDataSet,它由 TTable 的数据集提供。 数据集有两个字段:邮政编码(字符串,5)和街道(字符串,20)。

在运行时,我想显示第三个字段(字符串,20)。该字段的例程是获取邮政编码作为参数,并返回属于该邮政编码的城市。

问题只是将计算字段添加到已有的字段中。填充数据本身不是问题。

我尝试过:

  cds.SetProvider(Table1);
  cds.FieldDefs.Add('city', ftString, 20);

  cds.Open;

  cds.Edit;
  cds.FieldByName('city').AsString := 'Test';  // --> errormessage (field not found)
  cds.Post;

cds是我的clientdataset,Table1是一个悖论表,但问题与其他数据库相同。

提前致谢

I have a TClientDataSet, which is provided by a TTable’s dataset.
The dataset has two fields: postalcode (string, 5) and street (string, 20)

At runtime I want to display a third field (string, 20). The routine of this field is getting the postalcode as a parameter and gives back the city belongs to this postalcode.

The problem is only about adding a calculated field to the already existing ones. Filling the data itself is not the problem.

I tried:

  cds.SetProvider(Table1);
  cds.FieldDefs.Add('city', ftString, 20);

  cds.Open;

  cds.Edit;
  cds.FieldByName('city').AsString := 'Test';  // --> errormessage (field not found)
  cds.Post;

cds is my clientdataset, Table1 is a paradox Table, but the problem is the same with other databases.

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

面如桃花 2024-10-23 13:42:52

如果您想要添加除基础数据中存在的字段之外的其他字段,您还需要手动添加现有字段。添加字段时需要关闭数据集,但如果您不想手动跟踪所有字段详细信息,则可以使用 FieldDefs.Update 获取必要的元数据。基本上是这样的:

var
  i: Integer;
  Field: TField;
begin    
  cds.SetProvider(Table1);

  // add existing fields
  cds.FieldDefs.Update;
  for i := 0 to cds.FieldDefs.Count - 1 do 
    cds.FieldDefs[i].CreateField(cds);

  // add calculated field
  Field := TStringField.Create(cds);
  Field.FieldName := 'city';
  Field.Calculated := True;
  Field.DataSet := cds;

  cds.Open;
end;

另请参阅优秀文章,作者:卡里·詹森

If you want to add additional fields other than those exist in the underlying data, you need to also add the existing fields manually as well. The dataset needs to be closed when you're adding fields, but you can have the necessary metadata with FieldDefs.Update if you don't want to track all field details manually. Basically something like this:

var
  i: Integer;
  Field: TField;
begin    
  cds.SetProvider(Table1);

  // add existing fields
  cds.FieldDefs.Update;
  for i := 0 to cds.FieldDefs.Count - 1 do 
    cds.FieldDefs[i].CreateField(cds);

  // add calculated field
  Field := TStringField.Create(cds);
  Field.FieldName := 'city';
  Field.Calculated := True;
  Field.DataSet := cds;

  cds.Open;
end;

Also see this excellent article by Cary Jensen.

呆° 2024-10-23 13:42:52

好吧,我找到了一个更简单的解决方案,因为我的 sql 中有 24 个字段,我不想手动添加它们,所以我向 sql 语句添加了一个虚拟字段,例如:

select '      ' as city, the rest of the fields ... 

我可以在程序 OnAfterOpen 事件中修改它。

好吧,我必须在 sql 中定义该字段应该有多长,留足够的空格,例如 5 个空格代表 5 个字符,所以我必须知道城市名称可以有多长。

Well i found a simpler solution, as i have 24 fields in my sql i didnt wanted to add them all manually so i added a dummy field to the sql statement instead like:

select '      ' as city, the rest of the fields ... 

which i can modify in my program OnAfterOpen event.

Well i had to define in the sql how long that field should be by leaving enough empty spaces, for instance 5 empty spaces for 5 characters, so i must know how long the city name could be.

时光与爱终年不遇 2024-10-23 13:42:52

您应该在添加字段后使用 CreateDataset

cds.SetProvider(Table1);
cds.FieldDefs.Add('city', ftString, 20);
cds.CreateDataset; 

cds.Open;
cds.Edit;
cds.FieldByName('city').AsString := 'Test';  
cds.Post;

You should use CreateDataset after add field:

cds.SetProvider(Table1);
cds.FieldDefs.Add('city', ftString, 20);
cds.CreateDataset; 

cds.Open;
cds.Edit;
cds.FieldByName('city').AsString := 'Test';  
cds.Post;
甜警司 2024-10-23 13:42:52

希望分享更准确的不存在字段的查询。我敢打赌最好使用强制转换,而不是空格!

select E.NAME, E.SURNAME, cast(null as varchar(20)) as CITY
from EMPLOYEE E

例如 <代码>|马克奥 |马球| <空> |

更准确,可以明确看到字段大小,易懂、简单、安全!

Would like to share more accurate Query for unexisting fields. I bet it's better to use cast, neither spaces!

select E.NAME, E.SURNAME, cast(null as varchar(20)) as CITY
from EMPLOYEE E

e.g. | Marc'O | Polo | <NULL> |

It's more accurate, can definetly see field size, understandable, easy, safe!

茶底世界 2024-10-23 13:42:52

如果您想将现有的“动态”数据字段(来自提供者端)与其他客户端持久字段(计算、查找、内部计算、聚合)相结合,您应该子类化 CDS。只需引入额外的布尔属性CombineFields,并使用以下行覆盖BindFields(在较新的delphi版本中)或整个InternalOpen(就像我在d2006/2007中所做的那样)

if DefaultFields or CoupleFields then CreateFields; { TODO -ovavan -cSIC :如果 JointFields 为 true,则持久字段将与默认字段共存 }

这将允许您避免 FieldDefs/CreateField 的所有运行时混乱

if you want to combine already existing "dynamic" data fields (from provider side) with additional client side persistent fields (calculated, lookup, internalcalc, aggregate) you should subclass CDS. just introduce extra boolean property CombineFields and either override BindFields (in newer delphi versions) or the entire InternalOpen (as I did in d2006/2007) with the following line

if DefaultFields or CombineFields then CreateFields; { TODO -ovavan -cSIC : if CombineFields is true then persistent fields will coexist with Default ones }

that will allow you to avoid all that runtime mess with FieldDefs/CreateField

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文