Delphi 如何手动执行;OnCalcFields“;事件

Delphi 如何手动执行;OnCalcFields“;事件,delphi,tclientdataset,Delphi,Tclientdataset,假设在TClientDataSet上执行耗时的操作期间,我暂时想禁用onCalFields事件(例如通过设置cdsCalcFields:=nil)。当我重新附加OnCalcFields方法时,如何让TClientDataSet重新计算计算的字段 另一种可能需要手动重新计算的情况是,某些计算字段依赖于其他数据集(例如,计算字段用于临时保存其他数据集的某些聚合值)。这在大多数情况下都可以正常工作,因为执行oncalfields事件的频率足以从其他数据集中获得正确的值。但在某些情况下,需要重新计算以从

假设在TClientDataSet上执行耗时的操作期间,我暂时想禁用
onCalFields
事件(例如通过设置
cdsCalcFields:=nil
)。当我重新附加
OnCalcFields
方法时,如何让TClientDataSet重新计算计算的字段

另一种可能需要手动重新计算的情况是,某些计算字段依赖于其他数据集(例如,计算字段用于临时保存其他数据集的某些聚合值)。这在大多数情况下都可以正常工作,因为执行
oncalfields
事件的频率足以从其他数据集中获得正确的值。但在某些情况下,需要重新计算以从其他数据集中获得正确的值

AutoCalcFields
属性设置为
False
也可能会导致需要手动重新计算的情况

我已经看到了一些关于如何减少
OnCalcFields
事件执行的解释,但是我找不到一种简单的方法来执行重新计算


有什么建议吗?

当从数据库检索记录时,计算字段会被计算出来,因此在数据集上调用
刷新(或关闭->打开)以强制重新计算


(关于对问题的评论),要强制仅对一条记录重新计算,可以在数据集上调用
RefreshRecord
。如果特定的数据集子体未实现该方法,则执行
编辑
,然后执行
取消
调用将实现相同的效果。

调用刷新或关闭->会导致从数据库重新加载整个表。如果这不是您想要的,您可以调用OnCalc方法,将其自动传递给CDS。尽管您可能需要手动滑动光标

with DisplayAcctListCDS do begin
  First;
  while not Eof do begin
    Edit;
    DisplayAcctListCDSCalcFields(DisplayAcctListCDS);
    Next;
  end;
end;

假设DisplayAcctListCDS是带有计算字段的TClientDataSet,DisplayAcctListCDSCalcFields是OnCalcFields的生成事件方法。

这有点像黑客,但对我来说,这个问题的答案是100%

DBGrid.Height := 30; 
DBGrid.Height := 200; // Refresh all Rows after first
CalculatedProc(DataSet); // Refresh first calculated fields. (Write name of your calculate procedure)

看来你的问题错了。您不想执行此OnCalcFields事件。相反,您似乎希望重新计算字段。因此,我愚蠢的回答现在被删除了。@David-也许是我误解了。。。现在想一想,如果只对一条记录或整个记录集要求重新计算,这甚至不明显。@David,我想你在公式部分是对的。但是唯一可以给计算字段赋值的地方是
OnCaldFields
事件。@Sertac:我主要关心的是活动记录,所以@David的答案确实是相关的。@David-考虑到@Jorn的评论,你可能想取消删除你的答案。我认为
cds.Edit;取消-组合是最接近我所寻找的解决方案。
Refresh
-方法涉及从底层数据库进行重新读取,这是不可取的。@Jorn-
Cancel
方法与数据库同步,因此它涉及重新读取。我能想到的唯一不涉及数据检索的可能解决方案是调用受保护的方法:
THackCDS(cds.GetCalcFields(cds.ActiveBuffer)其中
THackCDS=class(TClientDataSet)
。因为我没有做足够的测试,所以我没有把它加入到答案中。+1-我不认为我会在“一般”情况下使用它,但它在TDataSet子代中作为私有方法工作得非常好。为什么不调用“刷新”如果要刷新所有行?刷新从服务器重新加载数据。当您增加网格高度时,您认为记录缓冲区在哪里检索?当网格窗口重新绘制时,计算字段将重新计算。答案中的代码将从服务器重新加载数据。所以最好叫“刷新”。使用“刷新”的一个明显优势是它不需要网格。