⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udatacopy.pas

📁 抽象三层访问数据库示例
💻 PAS
字号:
{*******************************************************}
{       软件名称: --通用--                              }
{       单元名称: DataCopy.pas                          }
{       中文名称: 数据复制类                            }
{       单元描述:                                       }
{       创    建: SamonHua                              }
{       创建日期: 2007-12-18                            }
{       修    改: 参见VSS记录                           }
{       版权所有 (C)2002-2007 深圳壹平台信息技术有限公司}
{*******************************************************}
unit uDataCopy;

interface

uses
  SysUtils, Classes, DB, Variants, uCommon;

type
  TDataCopy = class(TComponent)
  private
    FTargetKey: string;
    FSourceKey: string;
    FTargetDataSet: TDataSet;
    FSourceDataSet: TDataSet;
    FAllowNoneKeyField: Boolean;
    FBeforeCopyData: TNotifyEvent;
    FAfterCopyData: TNotifyEvent;
    FBeginCopyData: TNotifyEvent;
    FEndCopyData: TNotifyEvent;
    FAutoLocateRecord: boolean;
    FAutoDisablePostEvent: Boolean;
    FAutoDisableInsertEvent: Boolean;
    FAutoDisableEditEvent: Boolean;
    FUnallowModifyTargetStatus: Boolean;
    { Private declarations }
  protected
    { Protected declarations }
    function LocateSourceDataSet: boolean;
    function LocateTargetDataSet: boolean;
  public
    procedure CopyCurrentData;//复制当前记录
    procedure CopyAllData;//复制所有记录
    procedure CloneAllData;//复制所有记录,使两个数据集数据一模一样
    { Public declarations }
  published
    property SourceDataSet: TDataSet read FSourceDataSet write FSourceDataSet;
    property TargetDataSet: TDataSet read FTargetDataSet write FTargetDataSet;
    property SourceKey: string read FSourceKey write FSourceKey;
    property TargetKey: string read FTargetKey write FTargetKey;
    property AllowNoneKeyField: Boolean read FAllowNoneKeyField write FAllowNoneKeyField default False;
    property BeginCopyData: TNotifyEvent read FBeginCopyData write FBeginCopyData;
    property EndCopyData: TNotifyEvent read FEndCopyData write FEndCopyData;
    property BeforeCopyData: TNotifyEvent read FBeforeCopyData write FBeforeCopyData;
    property AfterCopyData: TNotifyEvent read FAfterCopyData write FAfterCopyData;
    property AutoLocateRecord: boolean read FAutoLocateRecord write FAutoLocateRecord default false;
    property AutoDisableInsertEvent: Boolean read FAutoDisableInsertEvent write FAutoDisableInsertEvent default true;
    property AutoDisableEditEvent: Boolean read FAutoDisableEditEvent write FAutoDisableEditEvent default true;
    property AutoDisablePostEvent: Boolean read FAutoDisablePostEvent write FAutoDisablePostEvent default true;
    property UnallowModifyTargetStatus: Boolean read FUnallowModifyTargetStatus write FUnallowModifyTargetStatus default False;
    constructor Create(AOwner: TComponent); override;
    { Published declarations }
  end;

//procedure Register;

implementation

{procedure Register;
begin
  RegisterComponents('Egov', [TDataCopy]);
end;}

{ TDataCopy }

procedure TDataCopy.CloneAllData;
var
  tmpBookmark1, tmpBookmark2: TBookmark;
  tmpBeforeScroll1, tmpBeforeScroll2, tmpAfterScroll1, tmpAfterScroll2,
    tmpBeforeInser, tmpAfterInsert, tmpBeforeEdit, tmpAfterEdit,
    tmpBeforeDelete1, tmpBeforePost, tmpAfterPost: TDataSetNotifyEvent;
  i: integer;
  strKeyValue: string;
begin
  if Assigned(FBeginCopyData) then
    FBeginCopyData(self);
  FTargetDataSet.DisableControls;
  FSourceDataSet.DisableControls;
  tmpBookmark1 := FTargetDataSet.GetBookmark;
  tmpBeforeScroll1 := FTargetDataSet.BeforeScroll;
  tmpBeforeDelete1 := FTargetDataSet.BeforeDelete;
  tmpAfterScroll1 := FTargetDataSet.AfterScroll;
  FTargetDataSet.BeforeScroll := nil;
  FTargetDataSet.AfterScroll := nil;
  FTargetDataSet.BeforeDelete := nil;
  tmpBookmark2 := FSourceDataSet.GetBookmark;
  tmpBeforeScroll2 := FSourceDataSet.BeforeScroll;
  tmpAfterScroll2 := FSourceDataSet.AfterScroll;
  FSourceDataSet.BeforeScroll := nil;
  FSourceDataSet.AfterScroll := nil;
  if FAutoDisableInsertEvent then
  begin
    tmpBeforeInser := FTargetDataSet.BeforeInsert;
    tmpAfterInsert := FTargetDataSet.AfterInsert;
    FTargetDataSet.BeforeInsert := nil;
    FTargetDataSet.AfterInsert := nil;
  end;
  if FAutoDisableEditEvent then
  begin
    tmpBeforeEdit := FTargetDataSet.BeforeEdit;
    tmpAfterEdit := FTargetDataSet.AfterEdit;
    FTargetDataSet.BeforeEdit := nil;
    FTargetDataSet.AfterEdit := nil;
  end;
  if FAutoDisablePostEvent then
  begin
    tmpBeforePost := FTargetDataSet.BeforePost;
    tmpAfterPost := FTargetDataSet.AfterPost;
    FTargetDataSet.BeforePost := nil;
    FTargetDataSet.AfterPost := nil;
  end;
  try
    strKeyValue := '';
    if (FSourceKey <> '') and (FSourceDataSet.FieldList.IndexOf(FSourceKey) <> -1) then
      strKeyValue := FSourceDataSet.FieldByName(FSourceKey).AsString;
    FTargetDataSet.First;
    while not FTargetDataSet.Eof do
      if not LocateSourceDataSet then
        FTargetDataSet.Delete
      else
        FTargetDataSet.Next;
    FSourceDataSet.First;
    while not FSourceDataSet.Eof do
    begin
      if Assigned(FBeforeCopyData) then
        FBeforeCopyData(self);
      if LocateTargetDataSet then
        FTargetDataSet.Edit
      else
        FTargetDataSet.Append;
      for i := 0 to FSourceDataSet.FieldCount - 1 do
        if FTargetDataSet.FieldList.IndexOf(FSourceDataSet.Fields[i].FieldName) <> -1 then
          FTargetDataSet.FieldByName(FSourceDataSet.Fields[i].FieldName).Value := FSourceDataSet.Fields[i].Value;
      FTargetDataSet.Post;
      if Assigned(FAfterCopyData) then
        FAfterCopyData(self);
      FSourceDataSet.Next;
    end;
  finally
    FTargetDataSet.BeforeScroll := tmpBeforeScroll1;
    FTargetDataSet.AfterScroll := tmpAfterScroll1;
    FTargetDataSet.BeforeDelete := tmpBeforeDelete1;
    //FTargetDataSet.GotoBookmark(tmpBookmark1);
    //FTargetDataSet.FreeBookmark(tmpBookmark1);
    FSourceDataSet.BeforeScroll := tmpBeforeScroll2;
    FSourceDataSet.AfterScroll := tmpAfterScroll2;
    FSourceDataSet.GotoBookmark(tmpBookmark2);
    FSourceDataSet.FreeBookmark(tmpBookmark2);
    if FAutoDisableInsertEvent then
    begin
      FTargetDataSet.BeforeInsert := tmpBeforeInser;
      FTargetDataSet.AfterInsert := tmpAfterInsert;
    end;
    if FAutoDisableEditEvent then
    begin
      FTargetDataSet.BeforeEdit := tmpBeforeEdit;
      FTargetDataSet.AfterEdit := tmpAfterEdit;
    end;
    if FAutoDisablePostEvent then
    begin
      FTargetDataSet.BeforePost := tmpBeforePost;
      FTargetDataSet.AfterPost := tmpAfterPost;
    end;
    FTargetDataSet.EnableControls;
    FSourceDataSet.EnableControls;
    if FAutoLocateRecord then
      FTargetDataSet.Locate(FTargetKey, strKeyValue, [loCaseInsensitive]);
    if Assigned(FEndCopyData) then
      FEndCopyData(self);
  end;
end;

procedure TDataCopy.CopyAllData;
var
  tmpBookmark1, tmpBookmark2: TBookmark;
  tmpBeforeScroll1, tmpBeforeScroll2, tmpAfterScroll1, tmpAfterScroll2,
    tmpBeforeInser, tmpAfterInsert, tmpBeforeEdit, tmpAfterEdit,
    tmpBeforePost, tmpAfterPost: TDataSetNotifyEvent;
  i: integer;
  strKeyValue: string;
begin
  if Assigned(FBeginCopyData) then
    FBeginCopyData(self);
  FTargetDataSet.DisableControls;
  FSourceDataSet.DisableControls;
  tmpBookmark1 := FTargetDataSet.GetBookmark;
  tmpBeforeScroll1 := FTargetDataSet.BeforeScroll;
  tmpAfterScroll1 := FTargetDataSet.AfterScroll;
  FTargetDataSet.BeforeScroll := nil;
  FTargetDataSet.AfterScroll := nil;
  tmpBookmark2 := FSourceDataSet.GetBookmark;
  tmpBeforeScroll2 := FSourceDataSet.BeforeScroll;
  tmpAfterScroll2 := FSourceDataSet.AfterScroll;
  FSourceDataSet.BeforeScroll := nil;
  FSourceDataSet.AfterScroll := nil;
  if FAutoDisableInsertEvent then
  begin
    tmpBeforeInser := FTargetDataSet.BeforeInsert;
    tmpAfterInsert := FTargetDataSet.AfterInsert;
    FTargetDataSet.BeforeInsert := nil;
    FTargetDataSet.AfterInsert := nil;
  end;
  if FAutoDisableEditEvent then
  begin
    tmpBeforeEdit := FTargetDataSet.BeforeEdit;
    tmpAfterEdit := FTargetDataSet.AfterEdit;
    FTargetDataSet.BeforeEdit := nil;
    FTargetDataSet.AfterEdit := nil;
  end;
  if FAutoDisablePostEvent then
  begin
    tmpBeforePost := FTargetDataSet.BeforePost;
    tmpAfterPost := FTargetDataSet.AfterPost;
    FTargetDataSet.BeforePost := nil;
    FTargetDataSet.AfterPost := nil;
  end;
  try
    strKeyValue := '';
    if (FSourceKey <> '') and (FSourceDataSet.FieldList.IndexOf(FSourceKey) <> -1) then
      strKeyValue := FSourceDataSet.FieldByName(FSourceKey).AsString;
    FSourceDataSet.First;
    while not FSourceDataSet.Eof do
    begin
      if Assigned(FBeforeCopyData) then
        FBeforeCopyData(self);
      if LocateTargetDataSet then
        FTargetDataSet.Edit
      else
        FTargetDataSet.Insert;
      for i := 0 to FSourceDataSet.FieldCount - 1 do
        if FTargetDataSet.FieldList.IndexOf(FSourceDataSet.Fields[i].FieldName) <> -1 then
          FTargetDataSet.FieldByName(FSourceDataSet.Fields[i].FieldName).Value := FSourceDataSet.Fields[i].Value;
      FTargetDataSet.Post;
      if Assigned(FAfterCopyData) then
        FAfterCopyData(self);
      FSourceDataSet.Next;
    end;
  finally
    FTargetDataSet.BeforeScroll := tmpBeforeScroll1;
    FTargetDataSet.AfterScroll := tmpAfterScroll1;
    //FTargetDataSet.GotoBookmark(tmpBookmark1);
    //FTargetDataSet.FreeBookmark(tmpBookmark1);
    FSourceDataSet.BeforeScroll := tmpBeforeScroll2;
    FSourceDataSet.AfterScroll := tmpAfterScroll2;
    FSourceDataSet.GotoBookmark(tmpBookmark2);
    FSourceDataSet.FreeBookmark(tmpBookmark2);
    if FAutoDisableInsertEvent then
    begin
      FTargetDataSet.BeforeInsert := tmpBeforeInser;
      FTargetDataSet.AfterInsert := tmpAfterInsert;
    end;
    if FAutoDisableEditEvent then
    begin
      FTargetDataSet.BeforeEdit := tmpBeforeEdit;
      FTargetDataSet.AfterEdit := tmpAfterEdit;
    end;
    if FAutoDisablePostEvent then
    begin
      FTargetDataSet.BeforePost := tmpBeforePost;
      FTargetDataSet.AfterPost := tmpAfterPost;
    end;
    FTargetDataSet.EnableControls;
    FSourceDataSet.EnableControls;
    if FAutoLocateRecord then
      FTargetDataSet.Locate(FTargetKey, strKeyValue, [loCaseInsensitive]);
    if Assigned(FEndCopyData) then
      FEndCopyData(self);
  end;
end;

procedure TDataCopy.CopyCurrentData;
var
  i: Integer;
  tmpBeforeInser, tmpAfterInsert, tmpBeforeEdit, tmpAfterEdit,
    tmpBeforePost, tmpAfterPost: TDataSetNotifyEvent;
begin
  if Assigned(FBeginCopyData) then
    FBeginCopyData(self);
  FTargetDataSet.DisableControls;
  if FAutoDisableInsertEvent then
  begin
    tmpBeforeInser := FTargetDataSet.BeforeInsert;
    tmpAfterInsert := FTargetDataSet.AfterInsert;
    FTargetDataSet.BeforeInsert := nil;
    FTargetDataSet.AfterInsert := nil;
  end;
  if FAutoDisableEditEvent then
  begin
    tmpBeforeEdit := FTargetDataSet.BeforeEdit;
    tmpAfterEdit := FTargetDataSet.AfterEdit;
    FTargetDataSet.BeforeEdit := nil;
    FTargetDataSet.AfterEdit := nil;
  end;
  if FAutoDisablePostEvent then
  begin
    tmpBeforePost := FTargetDataSet.BeforePost;
    tmpAfterPost := FTargetDataSet.AfterPost;
    FTargetDataSet.BeforePost := nil;
    FTargetDataSet.AfterPost := nil;
  end;
  try
    if Assigned(FBeforeCopyData) then
      FBeforeCopyData(self);
    if LocateTargetDataSet then
      FTargetDataSet.Edit
    else
      FTargetDataSet.Insert;
    for i := 0 to FSourceDataSet.FieldCount - 1 do
      if FTargetDataSet.FieldList.IndexOf(FSourceDataSet.Fields[i].FieldName) <> -1 then
        FTargetDataSet.FieldByName(FSourceDataSet.Fields[i].FieldName).Value := FSourceDataSet.Fields[i].Value;
    FTargetDataSet.Post;
    if Assigned(FAfterCopyData) then
      FAfterCopyData(self);
  finally
    if FAutoDisableInsertEvent then
    begin
      FTargetDataSet.BeforeInsert := tmpBeforeInser;
      FTargetDataSet.AfterInsert := tmpAfterInsert;
    end;
    if FAutoDisableEditEvent then
    begin
      FTargetDataSet.BeforeEdit := tmpBeforeEdit;
      FTargetDataSet.AfterEdit := tmpAfterEdit;
    end;
    if FAutoDisablePostEvent then
    begin
      FTargetDataSet.BeforePost := tmpBeforePost;
      FTargetDataSet.AfterPost := tmpAfterPost;
    end;
    FTargetDataSet.EnableControls;
    if Assigned(FEndCopyData) then
      FEndCopyData(self);
  end;
end;

constructor TDataCopy.Create(AOwner: TComponent);
begin
  inherited;
  FAutoLocateRecord := false;
  FAutoDisableInsertEvent := true;
  FAutoDisableEditEvent := true;
  FAutoDisablePostEvent := true;
  FUnallowModifyTargetStatus := false;
end;

function TDataCopy.LocateSourceDataSet: boolean;
var
  strFieldName: string;
  i: integer;
  varLocateValues: Variant;
begin
  Result := False;
  if FSourceKey = '' then
    if FAllowNoneKeyField then
      exit
    else
      raise Exception.Create('未设置关键字段,不能正确定位记录。');
  if Pos(';', FSourceKey) = 0 then
    Result := FSourceDataSet.Locate(FSourceKey, FTargetDataSet.FieldByName(FTargetKey).AsString, [])
  else
  begin
    if SubStrCount(FSourceKey) <> SubStrCount(FTargetKey) then
      raise Exception.Create('来源和目的数据集关键字段数量不一致,不能正确定位记录。');
    varLocateValues := VarArrayCreate([0, SubStrCount(FTargetKey)], varVariant);
    for i := 0 to SubStrCount(FTargetKey) do
    begin
      strFieldName := CopySubStr(FTargetKey, i);
      varLocateValues[i] := VarToStr(FTargetDataSet.FieldByName(strFieldName).Value);
    end;
    result := FSourceDataSet.Locate(FSourceKey, varLocateValues, [loCaseInsensitive]);
  end;
end;

function TDataCopy.LocateTargetDataSet: boolean;
var
  strFieldName: string;
  i: integer;
  varLocateValues: Variant;
begin
  Result := false;
  if FTargetKey = '' then
    if FAllowNoneKeyField then
      exit
    else
      raise Exception.Create('未设置关键字段,不能正确定位记录。');
  if Pos(';', FTargetKey) = 0 then
    Result := FTargetDataSet.Locate(FTargetKey, FSourceDataSet.FieldByName(FSourceKey).AsString, [])
  else
  begin
    if SubStrCount(FSourceKey) <> SubStrCount(FTargetKey) then
      raise Exception.Create('来源和目的数据集关键字段数量不一致,不能正确定位记录。');
    varLocateValues := VarArrayCreate([0, SubStrCount(FSourceKey)], varVariant);
    for i := 0 to SubStrCount(FSourceKey) do
    begin
      strFieldName := CopySubStr(FSourceKey, i);
      varLocateValues[i] := VarToStr(FSourceDataSet.FieldByName(strFieldName).Value);
    end;
    result := FTargetDataSet.Locate(FTargetKey, varLocateValues, [loCaseInsensitive]);
  end;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -