delphi – 保持beforepost事件中的值到afterpost事件

我正在为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;