Delphi - TDataSet determine if it was modified when is in insert/edit state

dataset, delphi, delphi-2006

Solution

You could hack the `DataSet` to change it's `Modified` property on `AfterInsert`/`AfterEdit` (and set initial/default values) and later test for `DataSet.Modified` (e.g. on before post). To determine which specific fields were modified, I hold a copy of the initial record e.g.:

type
  TDataRecord = array of record
    FieldName: string;
    Value: Variant;
  end;

type
  TForm1 = class(TForm)
    ... 
  private
    FInitRecord, FPostRecord: TDataRecord;
  end;

function GetDataRecord(DataSet: TDataSet): TDataRecord;
var
  I: Integer;
begin
  Result := nil;
  if Assigned(DataSet) then begin
    SetLength(Result, DataSet.FieldCount);
    for I := 0 to DataSet.FieldCount - 1 do begin
      Result[I].FieldName := DataSet.Fields[I].FieldName;
      Result[I].Value := DataSet.Fields[I].Value;
    end;
  end;
end;

type
  TDataSetAccess = class(TDataSet);

procedure TForm1.ADODataSet1AfterInsert(DataSet: TDataSet);
begin
  // set initial values 
  ADODataSet1.FieldByName('PK').Value := GetMyPKValue;
  ADODataSet1.FieldByName('DateCreated').AsDateTime := Now(); 
  // un-modify
  TDataSetAccess(ADODataSet1).SetModified(False);
  // save initial record
  FInitRecord := GetDataRecord(ADODataSet1);
end;    

procedure TForm1.ADODataSet1BeforePost(DataSet: TDataSet);
var
  I: Integer;
begin
  if ADODataSet1.Modified then
  begin
    FPostRecord := GetDataRecord(ADODataSet1);
    Memo1.Lines.Clear;
    for I := 0 to Length(FPostRecord) - 1 do begin
      if FPostRecord[I].Value <> FInitRecord[I].Value then
        Memo1.Lines.Add(Format('Field %s was modified', [FPostRecord[I].FieldName]));
    end;
  end;
end;

Well, It's the abstract idea anyway. You could sub-class your `TDataSet` like I do, and implement this feature directly inside your `TDataSet` component.

Problem

how can I find out if an data-aware component field has been modified when the dataset is already in Insert state? I want to know if a field was 'really' modified. (I don't care if the user has input something in a field and after that erase everything, this mean that a modification occured). DataSet.Modified, DataSet.UpdateStatus or ChangeCount are not solving my problem. LE: let me explain more in depth this. so, initial dataset looks like ``` ------------------------------------- |PK | Field1| Field2| Field3|Field4| ------------------------------------- | 1 | a | b | c | d | ------------------------------------- ``` after insert ``` ------------------------------------- |PK | Field1| Field2| Field3|Field4| ------------------------------------- | 2 | | | | | ------------------------------------- | 1 | a | b | c | d | ------------------------------------- ``` when the dataset is really modified ``` ------------------------------------- |PK | Field1| Field2| Field3|Field4| ------------------------------------- | 2 | avalue| | | | ------------------------------------- | 1 | a | b | c | d | ------------------------------------- ```

Original source