procedure CopyFromDataset(ASource, ADest: TDataSet; CopyData: Boolean);
const
UseStreams = ftBlobTypes;
var
I: Integer;
F,F1,F2: TField;
L1,L2: TList;
N: String;
OriginalPosition: TBookMark;
S: TMemoryStream;
minFieldNo: Integer;
fieldNo: Integer;
begin
ADest.Close;
ADest.Fields.Clear;
ADest.FieldDefs.Clear;
minFieldNo := MaxInt;
for I:=0 to ASource.FieldCount-1 do
begin
F := ASource.Fields[i];
if F.FieldNo < minFieldNo then
minFieldNo := F.FieldNo;
end;
for I:=0 to ASource.FieldCount-1 do
begin
F := ASource.Fields[I];
fieldNo := F.FieldNo;
if minFieldNo = 0 then inc(fieldno);
TFieldDef.Create(ADest.FieldDefs, F.FieldName, F.DataType, F.Size, F.Required, fieldno);
end;
if (ADest is TBufDataset) then
TBufDataset(ADest).CreateDataset
else
raise Exception.Create('Destination dataset type not supported.');
L1 := nil;
L2 := nil;
S := nil;
if CopyData then
try
L1:=TList.Create;
L2:=TList.Create;
ADest.Open;
for I:=0 to ADest.FieldDefs.Count-1 do
begin
N := ADest.FieldDefs[I].Name;
F1 := ADest.FieldByName(N);
F2 := ASource.FieldByName(N);
L1.Add(F1);
L2.Add(F2);
If (ADest.FieldDefs[I].DataType in UseStreams) and (S=Nil) then
S := TMemoryStream.Create;
end;
OriginalPosition := ASource.GetBookmark;
try
ASource.Open;
ASource.First;
while not ASource.EOF do
begin
ADest.Append;
for I:=0 to L1.Count-1 do
begin
F1 := TField(L1[i]);
F2 := TField(L2[I]);
if not F2.IsNull then
case F1.DataType of
ftFixedChar,
ftString : F1.AsString:=F2.AsString;
ftFixedWideChar,
ftWideString : F1.AsWideString:=F2.AsWideString;
ftBoolean : F1.AsBoolean:=F2.AsBoolean;
ftFloat : F1.AsFloat:=F2.AsFloat;
ftAutoInc,
ftSmallInt,
ftInteger : F1.AsInteger:=F2.AsInteger;
ftLargeInt : F1.AsLargeInt:=F2.AsLargeInt;
ftDate : F1.AsDateTime:=F2.AsDateTime;
ftTime : F1.AsDateTime:=F2.AsDateTime;
ftTimestamp,
ftDateTime : F1.AsDateTime:=F2.AsDateTime;
ftCurrency : F1.AsCurrency:=F2.AsCurrency;
ftBCD,
ftFmtBCD : F1.AsBCD:=F2.AsBCD;
else
if (F1.DataType in UseStreams) then
begin
S.Clear;
TBlobField(F2).SaveToStream(S);
S.Position := 0;
TBlobField(F1).LoadFromStream(S);
end
else
F1.AsString := F2.AsString;
end;
end;
try
ADest.Post;
except
ADest.Cancel;
raise;
end;
ASource.Next;
end;
finally
ASource.GotoBookmark(OriginalPosition); //Return to original record
end;
finally
L2.Free;
l1.Free;
S.Free;
end;
end;