English 中文(简体)
Delphi - TDataSet确定,在插入/插入国家时是否修改过。
原标题:Delphi - TDataSet determine if it was modified when is in insert/edit state
最佳回答

You could hack the DataSet to change it s Modified property on AfterInsert/AfterEdit (and set initial/default values) and later test for DataSet.Modified (e.g. on before post).
To determine which specific fields were modified, I hold a copy of the initial record e.g.:

type
  TDataRecord = array of record
    FieldName: string;
    Value: Variant;
  end;

type
  TForm1 = class(TForm)
    ... 
  private
    FInitRecord, FPostRecord: TDataRecord;
  end;

function GetDataRecord(DataSet: TDataSet): TDataRecord;
var
  I: Integer;
begin
  Result := nil;
  if Assigned(DataSet) then begin
    SetLength(Result, DataSet.FieldCount);
    for I := 0 to DataSet.FieldCount - 1 do begin
      Result[I].FieldName := DataSet.Fields[I].FieldName;
      Result[I].Value := DataSet.Fields[I].Value;
    end;
  end;
end;

type
  TDataSetAccess = class(TDataSet);

procedure TForm1.ADODataSet1AfterInsert(DataSet: TDataSet);
begin
  // set initial values 
  ADODataSet1.FieldByName( PK ).Value := GetMyPKValue;
  ADODataSet1.FieldByName( DateCreated ).AsDateTime := Now(); 
  // un-modify
  TDataSetAccess(ADODataSet1).SetModified(False);
  // save initial record
  FInitRecord := GetDataRecord(ADODataSet1);
end;    

procedure TForm1.ADODataSet1BeforePost(DataSet: TDataSet);
var
  I: Integer;
begin
  if ADODataSet1.Modified then
  begin
    FPostRecord := GetDataRecord(ADODataSet1);
    Memo1.Lines.Clear;
    for I := 0 to Length(FPostRecord) - 1 do begin
      if FPostRecord[I].Value <> FInitRecord[I].Value then
        Memo1.Lines.Add(Format( Field %s was modified , [FPostRecord[I].FieldName]));
    end;
  end;
end;

水井 它是一条抽象的想法。 您可以像我一样,将下级,并在构成部分内直接落实这一特征。

问题回答

当国家使用假肢时:

VarCompareValue(Field.NewValue, Unassigned) = vrNotEqual;

dsEdit use:

OldValue <> Value;

如数字领域0所示,在数字状态中不使用这种数据等于:

Field.NewValue <> Unassigned

Until now I found a solution, which seems to work. Solution consist in: - link a datasource to the tdataset descendant - a global boolean variable is set to false on the dataset OnAfterScroll event, and true on the datasources s OnDataChange event.

从我对申请进行的测试到现在,似乎这项工作正在进行。 现在,我需要调查发生和需要特殊处理的所有事件,以免改变这一进程中全球变量的状况。

欢迎任何其他想法。

procedure Tsomeform.MyDatasetBeforeInsert(DataSet: TDataSet);
begin
  MyDataset.Tag := 0;
end;

procedure Tsomeform.MyDatasetBeforeEdit(DataSet: TDataSet);
begin
  MyDataset.Tag := 0;
end;

procedure Tsomeform.SetIsDirty(Sender: TField; const Text: string);
begin
  if VarToStr(Sender.Value)<>Text then 
    MyDataset.Tag := 1;
end;

procedure Tsomeform.FormShow(Sender: TObject); 
var i: integer;
begin
  for i := 0 to MyDataset.FieldCount-1 do
  begin
    MyDataset.Fields[i].OnSetText := SetIsDirty;
  end;
end;
//The tag from the dataset will be 1 if the dataset has become dirty :)

type
  Tsomeform = class(TForm)
  //...
private
afs: array of TFieldSetTextEvent;
public

end;

procedure Tsomeform.FormCreate(Sender: TObject);
begin
  SetLength(afs,MyDataset.FieldCount);
end;

procedure Tsomeform.FormShow(Sender: TObject); 
var i: integer;
begin
  for i := 0 to MyDataset.FieldCount-1 do
  begin
    afs[i] := MyDataset.Fields[i].OnSetText;
    MyDataset.Fields[i].OnSetText := SetIsDirty;
    MyDataset.Fields[i].Tag := i;
  end;
end;

procedure Tsomeform.MyDatasetBeforeInsert(DataSet: TDataSet);
    begin
      MyDataset.Tag := 0;
    end;
    
    procedure Tsomeform.MyDatasetBeforeEdit(DataSet: TDataSet);
    begin
      MyDataset.Tag := 0;
    end;
    
    procedure Tsomeform.SetIsDirty(Sender: TField; const Text: string);
    begin
      //Execute any potential TFieldSetTextEvent in any field of MyDataset
      if Assigned(afs[Sender.Tag]) then
        afs[Sender.Tag](Sender,Text);
      if VarToStr(Sender.Value)<>Text then 
        MyDataset.Tag := 1;
      Sender.Value := Text;//It is important to enable change
    end;
//The tag from the dataset will be 1 if the dataset has become dirty :)

type
  Tsomeform = class(TForm)
  //...
  MyDataset: TClientDataSet;
private
  afs: array of TFieldSetTextEvent;
public
  procedure SetIsDirty(Sender: TField; const Text: string);
end;

procedure Tsomeform.FormCreate(Sender: TObject);
begin
  SetLength(afs,MyDataset.FieldCount);
end;

procedure Tsomeform.FormShow(Sender: TObject); 
var i: integer;
begin
  for i := 0 to MyDataset.FieldCount-1 do
  begin
    afs[i] := MyDataset.Fields[i].OnSetText;
    MyDataset.Fields[i].OnSetText := SetIsDirty;
    MyDataset.Fields[i].Tag := i;
  end;
end;

procedure Tsomeform.MyDatasetBeforeInsert(DataSet: TDataSet);
    begin
      MyDataset.Tag := 0;
    end;
    
    procedure Tsomeform.MyDatasetBeforeEdit(DataSet: TDataSet);
    begin
      MyDataset.Tag := 0;
    end;
    
    procedure Tsomeform.SetIsDirty(Sender: TField; const Text: string);
    begin
      //Execute any potential TFieldSetTextEvent in any field of MyDataset
      if Assigned(afs[Sender.Tag]) then
        afs[Sender.Tag](Sender,Text);
      if VarToStr(Sender.Value)<>Text then 
        MyDataset.Tag := 1;
      Sender.Value := Text;//It is important to enabling the change.
    end;




相关问题
determining the character set to use

my delphi 2009 app has a basic translation system that uses GNUGetText. i had used some win API calls to prepare the fonts. i thought it was working correctly until recently when someone from Malta ...

Help with strange Delphi 5 IDE problems

Ok, I m going nuts here. For the last (almost) four years, I ve been putting up with some extremely bad behavior from my Delphi 5 IDE. Problems include: Seemingly random errors in coride50.bpl ...

How to write a Remote DataModule to run on a linux server?

i would like to know if there are any solution to do this. Does anyone? The big picture: I want to access data over the web, using my delphi thin clients. But i´would like to keep my server/service ...

How convert string to integer in Oxygene

In Delphi, there is a function StrToInt() that converts a string to an integer value; there is also IntToStr(), which does the reverse. These functions doesn t appear to be part of Oxygene, and I can ...

Quick padding of a string in Delphi

I was trying to speed up a certain routine in an application, and my profiler, AQTime, identified one method in particular as a bottleneck. The method has been with us for years, and is part of a "...

热门标签