如何通过ZeosLib在Delphi 6 TZTable中找出哪个字段已更改

3
我是一名有用的助手,可以为您进行文本翻译。以下是需要翻译的内容:

我现在有一个绑定到DBGrid的TZTable(使用ZEOSlib),现在我需要知道用户更改了哪个特定的TField。

我尝试过使用

if NOT (taPositionenArtNrGH.NewValue = taPositionenArtNrGH.OldValue) then
    ShowMessage('ArticleNumber changed');

我把代码放在以下三处:
  • BeforePost
  • OnUpdateRecord
  • AfterPost
但在调试器中,旧值始终等于新值。我该如何检查哪个字段已更改?

1
顺便提一下,你的问题是关于查询一个特定的TField。如果你实际上想知道哪个字段被更改了,那么你需要循环遍历所有的TFields。请注意,你的问题不是非常精确,有几个人不得不要求澄清(并编辑它)。 - Jan Doggen
请提供更多细节:TClientDataSet 是否连接到 TDataSetProvider,而 TDataSetProvider 又是否连接到实际的 TDataSeet(例如 TSQLQuery)? - mjn
感谢您编辑我的问题并使事情更加清晰。不幸的是,我的不精确用语让大家走了一条错误的路线 :( - Michael
2
从现在开始,;-) 始终提及您的数据类型,并且始终将您的评论答案编辑到问题文本中。评论会消失,问题需要包含所有必要信息。 - Jan Doggen
这吸引了一些有趣的回答(不包括我的,我已经删除了),所以+1。 - MartynA
3个回答

3
您可以使用UpdateStatus : TUpdateStatus来实现这一点。例如:
  1. Set ZTable.CachedUpdates to true;
  2. Create new calculated field named "Status".
  3. To show old value for example of field "FNAME" create new calculate field named "FNameOldValue"
  4. In OnCalcFields event use:

    procedure TDM1.ZTable1CalcFields(DataSet: TDataSet);
    begin
      if ZTable1.UpdateStatus in [usModified] then
        begin
          ZTable1Status.value := 'Modified';
          ZTable1FNameOldValue.value := ZTable1FNAME.OldValue;
        end
      else
        ZTable1Status.value := 'UnModified'
    end;
    

结果:

在此输入图片描述

编辑:

您可以检测字段级别的更改,例如:

if ZTable1.UpdateStatus in [usModified] then
  begin
    for I := 0 to ZTable1.Fields.Count - 1 do
      begin
        if ZTable1.Fields[i].OldValue <> ZTable1.Fields[i].NewValue  then
          -- do something with this field
      end;
   end; 

1
根据文档所述:

只有在使用TClientDataSet组件或启用了缓存更新时,NewValue属性才可用于访问数据。


我现在已经启用了CachedUpdates,但依然没有改变。我该如何实现检测哪个字段被修改的目标?我能否询问DBGrid哪个字段被修改了? - Michael
你读过http://docwiki.embarcadero.com/RADStudio/Seattle/zh/Overview_of_Using_Cached_Updates和http://docwiki.embarcadero.com/RADStudio/Seattle/zh/Choosing_the_Type_of_Dataset_for_Caching_Updates吗?似乎并不是所有的数据集都支持缓存更新(我通常只使用TClientDataSet)。 - mjn
我只有非常老的 Delphi 6,不认为 Embarcadero 会对我有文档。 - Michael
@Michael,自Delphi 6以来,TClientDataSet并没有太多变化,因此当前的文档仍然有效且有帮助。 - mjn
抱歉让你走了错误的路线,mjn。我不太熟悉这些术语,请查看我的更新问题。 - Michael

1
如果你只想知道哪些字段已更改,为什么不使用TField.OnChange事件?你可以在此事件中填充字段名称列表,并在OnAfterPost中清除它。但是,Modified属性确实非常有用;奇怪的是它尚未被实现。

好点子,+1。如果你的数据集类型支持在 GetStateFieldValue(例如 TAdoDataSet)中,你可以在 OnChange 中获取字段的 OldValue,除了获取 FieldName 和已更改的值之外。此外,你可以将相同的 OnChange 处理程序分配给数据集的所有字段。 - MartynA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接