How do you see if memo field content has been changed on client side for TDAMemDataTable

We have a TDAMemDataTable with some memo fields
At some point we want to see for which records this field has changed (before an apply)

We do this by comparing the value with OldValue
newvdm_info:=lWeegProtocol.vdm_Informatie.Text;
oldvdm_info:=Self.FieldByName(fld_WeegProtocolvdm_Informatie).OldValue;
if (newvdm_info<>oldvdm_info) then

However OldValue now always seem to contain null (same as Value)

I believe this used to work.

How do we achieve this?

Hi,

You can check table.Delta and table.Delta.Changes[x].
it can be easier than comparing all records in table, because it contains only changed records.

Is this something that used to work?
What is the purpose of OldValue?

I am looking at a particular record in the dataset and am only interested in one field.
Is there an easy way to see if that field of that record is changed (via your delta system)?

Hi,

we serialize Delta to stream and pass it to server when ApplyUpdate was called so it is “used to work” :slight_smile:

in some cases, you need to use old values for update/delete commands:

DELETE FROM XXX WHERE ID = :OLD_ID
UPDATE XXX SET PK=:NEW_PK WHERE PK = :OLD_PK

if you selected the required row in table, you can check it as

var
  s: TDADeltaChange;
begin
  s := table.Delta.FindChange(table.RecIDValue);
  if Assigned(s) and s.Changed['memofield'] then
    ShowMessage('Changed');

Thanks for the sample,

I am still unclear about the OldValue property

Is it something we can use on client side? When is it set? What value does it contain?
Should we check all our code for use of OldValue and replace it?

Meanwhile I have tried your approach but unfortunately it crashes.
The s.Changed throws an exception probably because the field that is modified has ‘Iog changes’ set to false. It is a field from a joined table which cannot be updated via the default RO update statement.

Hi,

Looks like default solution that was implemented in Data.DB.pas doesn’t work as expected so you can’t use it.

why you can just use fld.OnChange event and set somewhere that this record was changed?
for example

procedure TForm124.DAMemDataTable1memChange(Sender: TDACustomField);
begin
  if Sender.Value <> Sender.OldValue then 
    dictionary.AddOrSetValue(table.RecIDValue, True);
end;

?

later you can check value in this dictionary.

Evgeny,

i don’t quite follow…
you state that we can’t use the OldValue property…
and then we should use the OldValue to check if the new value is different from the old one in the onchange event??

Hi,

TDADataTable has a temporary buffer that stores old field values between Edit/Post operations:

procedure TDADataTable.InternalBeforeEdit(Sender: TDataset);
...
  SetLength(fOldValues, Fields.Count);
  for i := 0 to Length(fOldValues) -1 do
    fOldValues[i] := Fields[i].Value;
end;

Note: it isn’t original old value so it you change value twice, this OldValue will contain a value assigned in 1st edit

I have changed my code so it uses your approach.
I fill my dictionary in the BeforePost however which also seems to work.

1 Like