DELPHI:使用ClientDataSet和CalcFields的Master-Detail

时间:2012-04-25 15:23:29

标签: delphi master-detail tclientdataset

我有一个master / detail 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的东西)。

如何迭代所选附加组件的DataSet以动态计算总成本(无论何时选择或数量发生变化)?

- 编辑 -

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

  • 添加了TAggregate'AggregatePrice'
  • 设置字段如下:   活跃 - 真实   名称 - AggregatePrice'   表达式 - SUM(TotalPrice)   GroupingLevel - 1   IndexName - ServiceId   可见 - 真实

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

2 个答案:

答案 0 :(得分:5)

编辑后,答案显而易见:使用InternalCalc字段而不是简单的CalcField!

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

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

作为旁注,InternalCalc字段可用于索引,但简单的CalcField不能。

答案 1 :(得分:0)

一种方法是使用Cloned Cursor来获取详细信息 - 数据集的副本与其源的内容保持同步,但可以单独导航。

例如

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;

请记住,克隆的光标不会包含任何计算字段或与原始字段关联的任何事件,因此您需要在需要时再次设置这些字段。

相关问题