如何检测 DBGrid 或 ClientDataset 中的用户在运行时删除了单元格中的数据?
How to detect user either in DBGrid or ClientDataset has deleted data in a cell at runtime?
我有一个程序需要 triggered/fired 用户删除单元格中的数据。看起来 ClientDataset.Delete 不适合这种情况。
我的数据结构是:
TADOConnection -> TADOQuery -> TDataSetProvider -> TClientDataSet -> TDataSource -> TDBGRidEh (descendant of TDBGrid)
我是否需要创建一个程序来检测删除,或者是否已经准备好用于此目的的事件或属性?
下面的代码应该检测您的 CDS 的给定字段(在此示例中为 Customer
)何时被修改,因此
它的 AsString 属性 是一个空字符串,或者该字段的值已被
设置为 Null,但在任何一种情况下,前提是该字段之前具有非 Null、非空值。
它使用 TFieldDataLink 的自定义后代来进行检测和处理
dsFieldChange 事件。这只会在 Post
方法正在执行且尚未返回时立即触发。
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;
要使用,剪切并粘贴到新的 VCL 项目中。
顺便说一句,对于这样的问题,最好从数据集的角度而不是像 DBGrid 这样的特定组件开始。
我有一个程序需要 triggered/fired 用户删除单元格中的数据。看起来 ClientDataset.Delete 不适合这种情况。
我的数据结构是:
TADOConnection -> TADOQuery -> TDataSetProvider -> TClientDataSet -> TDataSource -> TDBGRidEh (descendant of TDBGrid)
我是否需要创建一个程序来检测删除,或者是否已经准备好用于此目的的事件或属性?
下面的代码应该检测您的 CDS 的给定字段(在此示例中为 Customer
)何时被修改,因此
它的 AsString 属性 是一个空字符串,或者该字段的值已被
设置为 Null,但在任何一种情况下,前提是该字段之前具有非 Null、非空值。
它使用 TFieldDataLink 的自定义后代来进行检测和处理
dsFieldChange 事件。这只会在 Post
方法正在执行且尚未返回时立即触发。
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;
要使用,剪切并粘贴到新的 VCL 项目中。
顺便说一句,对于这样的问题,最好从数据集的角度而不是像 DBGrid 这样的特定组件开始。