做一个TClientDataSet影像

来源:互联网 发布:c windows repair 编辑:程序博客网 时间:2024/04/29 17:01

 做一个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;

end;
原创粉丝点击