【问题标题】:DELPHI: Master-Detail using ClientDataSet and CalcFieldsDELPHI:使用 ClientDataSet 和 CalcFields 的主从细节
【发布时间】:2012-04-25 15:23:29
【问题描述】:

我有一个主/详细 ClientDataSet 如下(这些是在运行时创建/填充的,并填充了从 API 调用返回的数据,没有数据库连接):

Services:
  ID
  Name
  BasePrice
  etc.

AddOns:
  Selected
  ID
  ServiceID
  Name
  Quantity
  UnitCost
  TotalCost
  etc.

我将服务显示为下拉字段,然后使用该服务的可用插件填充网格。 'TotalCost' 字段是一个计算字段,显示在网格中它自己的列中。 “已选择”字段用于跟踪网格中显示的复选框,以指示客户需要该特定插件。

这一切都按预期工作。我现在需要计算服务加上任何附加组件的总成本。我可以使用以下方式检索的服务成本:

ClientDataSetServices.FieldByName('BasePrice').Value

但是,我无法从每个选定的附加组件中检索 TotalCost。我以为我可以使用聚合字段,但在我的搜索中我发现使用主/详细设置是不可行的。我还尝试简单地遍历详细信息 ClientsDataSet,如下所示:

  (within the CalcFields method of the details ClientDataSet)
  // Add parts to parts cost
  grdMain.DataSource.DataSet.First;
  while not grdMain.DataSource.DataSet.Eof do begin

    if (grdMain.DataSource.DataSet.FieldByName('Selected').Value) then begin
      FPartsCost := FPartsCost +      
                    grdMain.DataSource.DataSet.FieldByName('TotalPrice').Value;
    end;

    grdMain.DataSource.DataSet.Next;
  end;

但这会导致无限循环。当我调试这部分代码时,我发现 ...DataSet.First 正在调用 CalcFields(或其他依次调用 CalcFields 的东西)。

How can I iterate over the DataSet of selected add-ons to calculate the total costs dynamically (whenever a selection or quantity changes)?

--编辑--

我尝试在详细信息表上设置聚合,如下所示:

  • 添加了标签“AggregatePrice”
  • 如下设置字段: 主动 - 真 名称 - AggregatePrice' 表达式 - SUM(TotalPrice) 分组级别 - 1 索引名称 - 服务 ID 可见 - 真

当我运行此程序时,我收到错误消息“字段 'TotalPrice' 不是要在聚合中使用的正确计算字段类型,请使用内部计算”

【问题讨论】:

  • > “这在使用主/详细设置时是不可行的” - 这是不正确的,您在文档中阅读过“TAggregateField”或“TAggregate”吗?
  • 在原始问题中查看我的编辑。
  • 我看不到任何编辑...

标签: delphi master-detail tclientdataset


【解决方案1】:

编辑后答案似乎很明显:使用 InternalCalc 字段而不是简单的 CalcField!

计算仍然在 OnCalcField 内完成,但您必须检查 TDataset.State 中的 dsInternalCalc。

这是必要的,因为聚合是在 dsInternalCalc 之后但在 dsCalcFields 状态之前计算的。

附带说明,InternalCalc 字段可用于索引,但简单的 CalcField 不能。

【讨论】:

  • 我没有发现太多关于使用 InternalCalc 字段的信息,所以你能告诉我这样做是否正确吗?我将 TotalPrice 更改为 InternalCalcField。我删除了 Aggregate 并在其位置创建了一个带有表达式“SUM(TotalPrice)”的 AggregateField (AggregatePrice),并在运行时将 IndexName 设置为 Field: TotalPrice 和 GroupingLevel: 1。现在唯一的问题是当调用 CalcFields 时 AggregatePrice 是始终为 Null。
  • 假设 TotalPrice 与您的问题中的 TotalCost 相同,您应该将 IndexName 设置为 Selected 而不是 TotalPrice。否则,聚合是基于 TotalPrice 的每个不同值构建的,这对我来说毫无意义。
  • 无论如何,我推荐阅读 Cary Jensens 的优秀书籍Delphi in Depth: ClientDataSets
  • 所以我将索引更改为“已选择”但 AggregatePrice 仍然为 NULL?
  • 感谢您的帮助 Uwe。我会研究你建议的书,看看我能弄清楚什么。
【解决方案2】:

一种方法是使用克隆光标获取详细信息 - 与源内容保持同步的数据集副本,但可以独立导航。

例如。

CopyCDS.CloneCursor(OriginalCDS,False); // check params in help to see options
CopyCDS.First;
while not CopyCDS.EOF do
  begin
  // do stuff to calculate what you need
  CopyCDS.Next;
  end;

请记住,克隆的光标不会有任何计算字段或任何与原始光标关联的事件,因此如果需要,您需要重新设置它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    相关资源
    最近更新 更多