做一个TClientDataSet影像
unit DataSetShadow;
interface
Uses
DB, DBClient, Variants, SysUtils, Dialogs, MConnect, StdCtrls, Classes,
Controls, Forms, ShellAPI, Windows;
Type
TDataSetShadow = Class(TObject) //DataSet影子
Private
FDataSet: TClientDataSet;
Public
Constructor Create(DataSet: TClientDataSet);
destructor Destroy; Override;
procedure Clear;
Procedure AddRecord(DataSet: TClientDataSet);
Procedure AddRecords(DataSet: TClientDataSet);
Procedure RestoreRecord(DataSet: TClientDataSet; ID: Integer; IgnoreFields: String='');
Procedure RestoreRecords(DataSet: TClientDataSet; IgnoreFields: String='');
End;
implementation
{ TDataSetShadow }
//DataSet - 要求做影像的DataSet
constructor TDataSetShadow.Create(DataSet: TClientDataSet);
var
i: Integer;
begin
Inherited Create;
FDataSet := TClientDataSet.Create(nil);
for i := 0 to DataSet.FieldCount - 1 do
FDataSet.FieldDefs.add(DataSet.Fields[i].FieldName, DataSet.Fields[i].DataType, DataSet.Fields[i].Size);
FDataSet.CreateDataSet;
FDataSet.Active := True;
end;
destructor TDataSetShadow.Destroy;
begin
FDataSet.Close;
FreeAndNil(FDataSet);
inherited;
end;
procedure TDataSetShadow.Clear;
begin
With FDataSet do
begin
if Active then
While not eof do
Delete;
end;
end;
procedure TDataSetShadow.AddRecord(DataSet: TClientDataSet);
var
i: Integer;
begin
FDataSet.Append;
for i := 0 to DataSet.FieldCount - 1 do
FDataSet.Fields[i].Value := DataSet.Fields[i].Value;
FDataSet.Post;
end;
procedure TDataSetShadow.AddRecords(DataSet: TClientDataSet);
var
i: Integer;
begin
With DataSet do
begin
First;
While Not Eof do
begin
AddRecord(DataSet);
Next;
end;
end;
end;
procedure TDataSetShadow.RestoreRecord(DataSet: TClientDataSet;
ID: Integer; IgnoreFields: String='');
var
i: Integer;
begin
IgnoreFields := FormatFields(IgnoreFields);
if FDataSet.Locate('ID', ID, []) then
begin
DataSet.Edit;
for i := 0 to DataSet.FieldCount - 1 do
begin
if IncludeField(DataSet.Fields[i].FieldName, IgnoreFields) then
Continue;
if (DataSet.Fields[i].FieldKind <> fkCalculated) And
(DataSet.Fields[i].FieldKind <> fkInternalCalc) And
(DataSet.Fields[i].Value <> FDataSet.Fields[i].Value) then
begin
DataSet.Fields[i].Value := FDataSet.Fields[i].Value;
end;
end;
DataSet.Post;
//
FDataSet.Delete;
end;
end;
procedure TDataSetShadow.RestoreRecords(DataSet: TClientDataSet; IgnoreFields: String='');
var
i: integer;
begin
IgnoreFields := FormatFields(IgnoreFields);
With FDataSet do
begin
First;
While Not Eof do
begin
if not DataSet.Locate('ID', FieldByName('ID').AsInteger, []) then
DataSet.Append
else
DataSet.Edit;
for i := 0 to DataSet.FieldCount - 1 do
begin
if IncludeField(DataSet.Fields[i].FieldName, IgnoreFields) then
Continue;
if (DataSet.Fields[i].FieldKind <> fkCalculated) And
(DataSet.Fields[i].FieldKind <> fkInternalCalc) And
(DataSet.Fields[i].Value <> FDataSet.Fields[i].Value) then
begin
DataSet.Fields[i].Value := FDataSet.Fields[i].Value;
end;
end;
DataSet.Post;
Next;
end;
end;
end;
end.
【例子】:
procedure TfrmOrd.aCheckExecute(Sender: TObject);
var
dsShadow: TDataSetShadow;
begin
if Application.MessageBox('確定對當前生產單進行生產復核嗎?',
'系統提示', MB_YESNO + MB_ICONQUESTION + MB_DEFBUTTON2) = IDYES then
begin
Screen.Cursor := crHourglass;
ShowWaiting('處理數據');
//建立影像对象
dsShadow := TDataSetShadow.Create(dsJbzl);
//记下当前记录的影像
dsShadow.AddRecord(dsJbzl);
Try
Try
dsJbzl.Edit;
dsJbzl.FieldByName('Held').AsBoolean := True;
dsJbzl.FieldByName('HeldBy').AsString := pstrUserName;
dsJbzl.FieldByName('HeldDate').AsDateTime := Now();
dsJbzl.Post;
SaveHeld; //数据提交
Except
//提交失败,利用RestoreRecord恢复提交前的数据
dsShadow.RestoreRecord(dsJbzl,dsJbzl.FieldByName('ID').AsInteger);
dsAfterScroll(dsJbzl);
End;
Finally
//释放影像对象
FreeAndNil(dsShadow);
CloseWaiting;
Screen.Cursor := crDefault;
end;
Application.MessageBox(Pchar('已成功復核當前生產單!'), '系統提示', MB_OK + MB_ICONWARNING);
end;