Delphi-TDataSet确定它是否在处于插入/编辑状态时被修改

Delphi-TDataSet确定它是否在处于插入/编辑状态时被修改,delphi,dataset,delphi-2006,Delphi,Dataset,Delphi 2006,当数据集已处于插入状态时,如何确定数据感知组件字段是否已被修改?我想知道某个字段是否“真的”被修改过。(我不在乎用户是否在字段中输入了内容,然后删除所有内容,这意味着发生了修改) ,或者没有解决我的问题 乐:让我更深入地解释一下。所以,初始数据集看起来像 ------------------------------------- |PK | Field1| Field2| Field3|Field4| ------------------------------------- | 1 |

当数据集已处于插入状态时,如何确定数据感知组件字段是否已被修改?我想知道某个字段是否“真的”被修改过。(我不在乎用户是否在字段中输入了内容,然后删除所有内容,这意味着发生了修改)

,或者没有解决我的问题

乐:让我更深入地解释一下。所以,初始数据集看起来像

-------------------------------------
|PK  | Field1| Field2| Field3|Field4|
-------------------------------------
| 1  |  a    | b     | c     | d    |  
-------------------------------------
插入后

-------------------------------------
|PK  | Field1| Field2| Field3|Field4|
-------------------------------------
| 2  |       |       |       |      |  
-------------------------------------
| 1  |  a    | b     | c     | d    |  
-------------------------------------
当数据集真正被修改时

-------------------------------------
|PK  | Field1| Field2| Field3|Field4|
-------------------------------------
| 2  | avalue|       |       |      |  
-------------------------------------
| 1  |  a    | b     | c     | d    |  
-------------------------------------

当状态为dsInsert时,请使用:

VarCompareValue(Field.NewValue, Unassigned) = vrNotEqual;
dsEdit使用:

OldValue <> Value;
OldValue;
请勿在dsInsert状态下使用此选项,因为在数字字段中0等于未赋值:

Field.NewValue <> Unassigned
Field.NewValue未赋值

您可以破解
数据集
,在
后插入
/
后编辑
(并设置初始值/默认值)上更改它的
修改
属性,然后对
数据集进行测试。已修改
(例如,在发布前打开)。
为了确定修改了哪些特定字段,我持有初始记录的副本,例如:

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;
类型
TDataRecord=记录数组
字段名:字符串;
值:变量;
结束;
类型
TForm1=类(TForm)
... 
私有的
FiniteRecord,FPostRecord:TDataRecord;
结束;
函数GetDataRecord(数据集:TDataSet):TDataRecord;
变量
I:整数;
开始
结果:=无;
如果已分配(数据集),则开始
SetLength(结果,数据集.FieldCount);
对于I:=0到DataSet.FieldCount-1,请开始
结果[I]。字段名:=数据集。字段[I]。字段名;
结果[I]。值:=数据集。字段[I]。值;
结束;
结束;
结束;
类型
TDataSetAccess=类(TDataSet);
过程TForm1.ADODataSet1AfterInsert(数据集:TDataSet);
开始
//设置初始值
ADODataSet1.FieldByName('PK')。值:=GetMyPKValue;
ADODataSet1.FieldByName('DateCreated').AsDateTime:=Now();
//取消修改
TDataSetAccess(ADODataSet1).SetModified(False);
//保存初始记录
FInitRecord:=GetDataRecord(ADODataSet1);
结束;
过程TForm1.ADODataSet1BeforePost(数据集:TDataSet);
变量
I:整数;
开始
如果ADODataSet1.Modified,则
开始
FPostRecord:=GetDataRecord(ADODataSet1);
备忘录1.线条清晰;
对于I:=0到长度(FPostRecord)-1,开始
如果FPostRecord[I].值finiteRecord[I].值,则
Memo1.Lines.Add(格式('Field%s已修改',[FPostRecord[I].FieldName]);
结束;
结束;
结束;

不管怎么说,这都是抽象的想法。您可以像我一样对
TDataSet
进行子分类,并直接在
TDataSet
组件中实现此功能。

直到现在,我找到了一个解决方案,似乎很有效。解决方案包括: -将数据源链接到tdataset子体 -全局布尔变量在dataset事件上设置为false,在datasources事件上设置为true

从我在应用程序上执行的测试到现在,这项工作似乎正在发挥作用。我现在需要调查所有发生的事件,并且需要特殊处理,以避免在这个过程中改变全局变量的状态


欢迎任何其他想法

直接向控制中心询问如何?我的意思是,例如,
TDBEdit.Modified
?请把它当作一个蹩脚的注释,我不是一个DB-aware控件用户:-)@TLama-问题是,它包含在大量使用的主窗体/框架中。因此,我试图找到一个通用的解决方案,它可以指示我,当数据集已经处于插入/编辑模式时,数据集是否真的发生了更改……没有数据集级别的方法可以做到这一点。只有一种数据感知控制方法可以做到这一点。这意味着要验证的是字段不是null…variant nully没有得到您的评论,我发布的代码必须在实际记录中进行验证,通常在BeforePost事件中,它会告诉您它是否“真的”被修改。在Post事件之后,只需检查ChangeCount。