【问题标题】:How to force a Client DataSet to recalculate calculated and internal calculated fields?如何强制客户端数据集重新计算计算字段和内部计算字段?
【发布时间】:2013-07-28 10:55:14
【问题描述】:

我有一个 ClientDatSet 和几个 fkInternalCalc 字段。 CDS 未链接到任何提供商;相反,它是即时填充的。如何强制 CDS 重新计算所有“可计算”字段?我不能打电话给Refresh(),因为没有提供者可以从中刷新数据。到目前为止,我使用的唯一方法是浏览所有记录,这不是最好的方法。

PS:我已经阅读了this questionthis post,但我希望有更优雅的方式。

【问题讨论】:

  • 那么,关闭-打开数据集不起作用?
  • @SertacAkyuz 我还没试过。关闭客户端数据集不会清除其中的所有数据吗?
  • @SertacAkyuz 我很害怕……Resync() 是做什么的?有什么想法吗?
  • @Iman:请解释一下为什么需要强制字段计算?每次字段更改以响应名为 deFieldChanged 的内部数据集事件时,它都会自动发生。有一个名为 TDataset.CalculateFields 的受保护方法会触发对当前记录的处理,但它不打算被 TDataset(或其子类)以外的任何代码使用。这一切都是因为,理论上,程序员不需要自己触发计算过程。
  • @AlexSC,这不适用于 fkInternalCalc 字段。

标签: delphi delphi-xe2 tclientdataset


【解决方案1】:

我通过 helper 实现了这一点(这里只删除了必要的部分),它允许调用受保护的方法而无需任何黑客攻击。确保在 OnCalcFields 中检查 DataSet.State = dsInternalCalc 以获取 fkInternalCalc 字段。

type
  TClientDataSetHelper = class helper for TClientDataSet
  public
    function AssureEditing: Boolean;
    procedure InternalCalc;
  end;

function TClientDataSetHelper.AssureEditing: Boolean;
begin
  result := not (State in [dsEdit, dsInsert]);
  if result then
    Edit;
end;

procedure TClientDataSetHelper.InternalCalc;
var
  needsPost: Boolean;
  saveState: TDataSetState;
begin
  needsPost := AssureEditing;
  saveState := setTempState(dsInternalCalc);
  try
    RefreshInternalCalcFields(ActiveBuffer);
  finally
    RestoreState(saveState);
  end;
  if needsPost then
    Post;
end;

这可以使用CalculateFields 轻松扩展为普通计算字段。虽然这不是必需的,因为只要任何其他数据字段发生更改,就会重新计算计算字段。

【讨论】:

  • 我试过这个并得到 "[dcc32 Error] dMyDataModule.pas(151): E2389 Protected member 'TDataSet.RefreshInternalCalcFields' is inaccessible here".
  • @GolezTrol,看起来像一个错误。适用于 XE3,但不适用于 XE7 和 XE8(目前无法检查 XE4 到 XE6)。其他受保护的成员完全可以访问:“setTempState”、“RestoreState”。刚刚报告为 RSP-11337。
  • 为了缩小范围,我使用的是 XE5。感谢测试!我现在使用更经典的类助手解决了它:类型转换为本地定义的THackClientDataSet = class(TClientDataSet)
【解决方案2】:

这有点小技巧,但它确实有效!

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

【讨论】:

  • 1.使用Delphi默认函数2.Shot 3.简单
  • 4.比使用更改状态更快!
  • 您介意编辑答案并在这里详细说明吗?
  • 如果要刷新所有行,为什么不调用“刷新”?
  • 从服务器刷新重载数据。
猜你喜欢
  • 1970-01-01
  • 2018-02-14
  • 2012-10-11
  • 2022-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多