我有一个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以动态计算总成本(无论何时选择或数量发生变化)?
- 编辑 -
我尝试在详细信息表上设置聚合,如下所示:
当我运行此操作时,我收到错误消息“Field'TotalPrice'不是要在聚合中使用的正确类型的计算字段,请使用internalcalc”
答案 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;
请记住,克隆的光标不会包含任何计算字段或与原始字段关联的任何事件,因此您需要在需要时再次设置这些字段。