我正在为Delphi 2007编写这个问题,但我很确定这是所有语言中的常见问题.
所以,我有一个项目,我需要保存关于某些字段的旧值和新值的信息(在我正在使用的数据集的BeforePost事件中给出)并在AfterPost事件中使用它们.
目前,我一直在使用全局变量,但在项目中已经有很多这样的变量,在管理文档和/或注释时,这成为一个真正的问题.
基本上,我问是否有更好的方法(在Delphi 2007或一般情况下)保持数据集的BeforePost事件的信息并将它们返回到AfterPost事件中.
解决方法
首先创建一个新的自定义数据源
TDataRecord = array of record FieldName: string; FieldValue: Variant; end; TMyDataSource = class(TDataSource) private LastValues: TDataRecord; procedure MyDataSourceBeforePost(DataSet: TDataSet); procedure SetDataSet(const Value: TDataSet); function GetDataSet: TDataSet; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function GetLastValue(FieldName: string): Variant; property MyDataSet: TDataSet read GetDataSet write SetDataSet; end; { TMyDataSource } constructor TMyDataSource.Create(AOwner: TComponent); begin inherited Create(AOwner); end; destructor TMyDataSource.Destroy; begin SetLength(LastValues,0); inherited Destroy; end; function TMyDataSource.GetDataSet: TDataSet; begin Result := DataSet; end; procedure TMyDataSource.SetDataSet(const Value: TDataSet); begin DataSet := Value; DataSet.BeforePost := MyDataSourceBeforePost; end; procedure TMyDataSource.MyDataSourceBeforePost(DataSet: TDataSet); var i: integer; begin SetLength(LastValues,DataSet.FieldCount); for i:=0 to DataSet.FieldCount-1 do begin LastValues[i].FieldName := DataSet.Fields.Fields[i].FieldName; LastValues[i].FieldValue := DataSet.Fields.Fields[i].OldValue; end; end; function TMyDataSource.GetLastValue(FieldName: string): Variant; var i: integer; begin Result := Null; for i:=0 to Length(LastValues)-1 do if SameText(FieldName,LastValues[i].FieldName) then begin Result := LastValues[i].FieldValue; break; end; end;
并覆盖应用程序数据源
TForm1 = class(TForm) private MyDataSource: TMyDataSource; end; procedure TForm1.FormCreate(Sender: TObject); begin ADOQuery1.Active := true; MyDataSource := TMyDataSource.Create(Self); MyDataSource.MyDataSet := ADOQuery1; DBGrid1.DataSource := MyDataSource; end; procedure TForm1.FormDestroy(Sender: TObject); begin MyDataSource.Free; end; procedure TForm1.ADOQuery1AfterPost(DataSet: TDataSet); var AValue: Variant; begin AValue := MyDataSource.GetLastValue('cname'); if not VarIsNull(AValue) then; end;