How to detect user either in DBGrid or ClientDataset has deleted data in a cell at runtime?

308 Views Asked by At

I have a procedure that needs to be triggered/fired by a user deletion of data in a cell. Looks like ClientDataset.Delete is not appropriate for this case.

My data structure are:

TADOConnection -> TADOQuery -> TDataSetProvider -> TClientDataSet -> TDataSource -> TDBGRidEh (descendant of TDBGrid)

Do I need to create a procedure to detect the deletion or is there already an event or properties ready to use for this purpose?

1

There are 1 best solutions below

3
MartynA On BEST ANSWER

The code below should detect when a given field - Customer in this example - of your CDS has been modified so that either its AsString property is an empty string or the Field's value has been set to Null, but, in either case, only if the Field had a non-Null, non-empty value previously.

It uses a custom descendant of a TFieldDataLink to do the detection and handle the dsFieldChange event. This will only fire immediately while the Post method is executing and has not yet returned.

type
  TMyFieldDataLink = class(TFieldDataLink)
    procedure DataEvent(Event: TDataEvent; Info: Integer); override;
  end;

type
  TForm1 = class(TForm)
    ClientDataSet1: TClientDataSet;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    ADOConnection1: TADOConnection;
    ADOQuery1: TADOQuery;
    DataSetProvider1: TDataSetProvider;
    DBNavigator1: TDBNavigator;
    DBEdit1: TDBEdit;
    procedure FormCreate(Sender: TObject);
  private
    FieldDataLink : TFieldDataLink;
  end;
[...]
procedure TForm1.FormCreate(Sender: TObject);
begin
  FieldDataLink := TMyFieldDataLink.Create;
  FieldDataLink.DataSource := DataSource1;
  FieldDataLink.FieldName := 'Company';
end;

{ TMyFieldDataLink }

procedure TMyFieldDataLink.DataEvent(Event: TDataEvent; Info: Integer);
var
  S : String;
  V : Variant;
begin
  inherited;

  if Event = deFieldChange then begin
    V :=  Field.OldValue;
    if not VarIsNull(V) then begin
      S := V;
      if (S <> '') and (Field <> Nil) and (Field.IsNull or (Field.AsString = '')) then begin
        ShowMessage('Field: ' + Field.FieldName + ' emptied');
      end;
    end;
  end;
end;

To use, cut & paste into a new VCL project.

Btw, for a problem like this, it's best to start by looking at it from the point of view of the dataset rather than a particular component like a DBGrid.