3

I have a TZTable (ZEOSlib) bound to a DBGrid now I need to know which particular TField was changed by the user.

I tried with

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

I placed the code in

  • BeforePost, OnUpdateRecord, AfterPost

But in the Debugger OldValue is always NewValue. How do I check which field was changed?

Jan Doggen
  • 8,799
  • 13
  • 70
  • 144
Michael
  • 328
  • 2
  • 18
  • 1
    BTW Your question is about querying one particular TField. If you actually want to know *which field was changed* you would loop over all TFields. Please note that your question is not very precise and that several people have had to to ask for clarifications (and edit it) – Jan Doggen Jan 29 '16 at 10:13
  • Please include more details: is the TClientDataSet connected to a TDataSetProvider which is connected to the actual TDataSeet (for example a TSQLQuery)? – mjn Jan 29 '16 at 10:15
  • Thanks for editing my question and makes things more Clear. Unfortunatly I lead you on the wrong track with my unprecise language guys :( – Michael Jan 29 '16 at 10:27
  • 2
    So from now on ;-) *always* mention your data types, and *always* edit your comment answers into the question text as well. Comments disappear and the question needs to contain all essential information. – Jan Doggen Jan 29 '16 at 13:18
  • This has attracted some interesting answers (not including mine, which I've taken down) so +1. – MartynA Jan 29 '16 at 17:59

3 Answers3

3

You can use UpdateStatus : TUpdateStatus for this. For example:

  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;
    

Result :

enter image description here

Edit:

You can detect field level changes like:

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; 
Val Marinov
  • 2,705
  • 17
  • 22
1

As per documentation:

The NewValue property is only usable when the data is accessed using a TClientDataSet component or cached updates is enabled.

mjn
  • 36,362
  • 28
  • 176
  • 378
  • I've enabled CachedUpdates now. But still the same. How can I achieve my goal to detect which field is changed. Can I ask the DBGrid which field was modified? – Michael Jan 29 '16 at 10:05
  • Have you read http://docwiki.embarcadero.com/RADStudio/Seattle/en/Overview_of_Using_Cached_Updates and http://docwiki.embarcadero.com/RADStudio/Seattle/en/Choosing_the_Type_of_Dataset_for_Caching_Updates? It seems that not all datasets support cached updates (I usually work only with TClientDataSet) – mjn Jan 29 '16 at 10:10
  • Have only the very old Delphi 6 don't think embarcadero Have docu for me – Michael Jan 29 '16 at 10:16
  • @Michael not very much has changed since Delphi 6 for TClientDataSet so the current docs are still valid and helpful – mjn Jan 29 '16 at 10:21
  • Sorry for leading you on the wrong track mjn I'm not very used to the terms pls see my updated question. – Michael Jan 29 '16 at 10:29
1

If you just want to know what fields have been changed, why not use TField.OnChange event? You could fill a list of field names in this event and clear it in OnAfterPost. But the Modified property would be very useful indeed; it's odd that it haven't been implemented yet.

Fr0sT
  • 2,959
  • 2
  • 25
  • 18
  • Good point, +1. Might be worth mentioning that if your dataset type supports it in GetStateFieldValue (e.g. TAdoDataSet), you can pick up the Field's OldValue in OnChange, in addition to the FieldName and changed value. Also, you can assign the same OnChange handler to all the dataset's fields. – MartynA Jan 29 '16 at 18:31