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。