如何在数据集已处于插入状态时找出数据感知组件字段是否已被修改?我想知道一个字段是否真的被“修改”了。 (我不在乎用户是否在某个字段中输入了某些东西,然后擦除所有内容,这意味着发生了修改)。
DataSet.Modified,DataSet.UpdateStatus或ChangeCount无法解决我的问题。
LE:让我更深入地解释一下。所以,初始数据集看起来像
-------------------------------------
|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 |
-------------------------------------
答案 0 :(得分:8)
你可以在DataSet
/ Modified
上修改AfterInsert
AfterEdit
属性(并设置初始/默认值),然后测试DataSet.Modified
(例如在发布之前)
为了确定修改了哪些特定字段,我保留了初始记录的副本,例如:
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;
嗯,无论如何,这是抽象的想法。您可以像我一样对TDataSet
进行细分,并直接在TDataSet
组件中实现此功能。
答案 1 :(得分:3)
当状态为dsInsert时使用:
VarCompareValue(Field.NewValue, Unassigned) = vrNotEqual;
dsEdit使用:
OldValue <> Value;
不要在dsInsert状态下使用它,因为数字字段0等于未分配:
Field.NewValue <> Unassigned
答案 2 :(得分:0)
直到现在我找到了一个似乎有效的解决方案。解决方案包括: - 将数据源链接到tdataset后代 - 数据集OnAfterScroll事件的全局布尔变量设置为false,数据源的OnDataChange事件设置为true。
从我在应用程序上执行的测试到目前为止,似乎这种解决方法正在发挥作用。我现在需要调查所有发生的事件,并且需要特殊处理,以便不改变过程中全局变量的状态。
欢迎任何其他想法