2014-11-05 2 views
7

이 질문은 Delphi 2007에서 쓰고 있습니다. 그러나 모든 언어에서이 문제가 자주 발생합니다.beforepost 이벤트의 값을 afterpost 이벤트에 유지하십시오.

그래서 저는 (작업중인 데이터 세트의 BeforePost 이벤트에서 제공되는) 특정 필드의 이전 값과 새 값에 대한 정보를 유지하고 AfterPost 이벤트에서 사용하는 프로젝트가 있습니다.

지금까지 글로벌 변수를 사용했지만 이미 프로젝트에 많은 변수가있어 설명서 및/또는 의견 관리에있어 실질적인 문제가되고 있습니다.

기본적으로 데이터 집합의 BeforePost 이벤트에서 정보를 유지하고 AfterPost 이벤트로 다시 가져 오는 더 좋은 방법이 있는지 (Delphi 2007 또는 일반적으로) 묻습니다.

+0

번호 재정의 응용 프로그램 데이터 원본 후 즉 물론 그것은'TDataSet' 자손의 구현에 따라 달라집니다 (할 수 없습니다 , 의미 없음으로). 이 이벤트들 사이에서 데이터 세트는 필드 버퍼를 비우고 새로 게시 된 상태로 새로 고침하므로 이전 상태를 잃어 버리게됩니다. – TLama

+0

어떤 유형의 TDataSet을 사용하고 있습니까? 이유는 TClientDataSets를 사용하는 경우 이런 종류의 물건이 훨씬 더 간단해진다는 것입니다. – MartynA

+3

Btw, 내가 말한 것은 @TLama와 모순된다는 의미가 아닙니다. 임시 TClientDataSets가 주요 데이터 집합에서 발생하는 이벤트간에 데이터 집합 데이터를 보존하는 매우 편리한 방법을 제공하는 것입니다. 흥미로운 q, btw에 +1합니다. – MartynA

답변

0

먼저 새 사용자 정의 데이터 소스

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; 
+0

Hello @AngelsGR! 답변 주셔서 감사합니다! 불행히도 이것은 저에게 오래된 주제이기 때문에 테스트 할 수는 없습니다. 필자는 일자리를 변경하고 더 이상 Delphi를 사용하지 않습니다. 아마 나보다 다른 누군가가 이것이 작동하고 있음을 확인할 수 있습니다! 나는 이것을 지금 대답으로 표시 할 수 없다. – KeineMaster

+0

작전 10 개월 전에이 질문을 한 것을 보지 못했습니다! – AngelsGR

관련 문제