For the purposes of this example please assume there is no primary key or constraints on the table. In reallity you would probably want to duplicate a record then change one of the field values, before it is appended.
The problem is that to use dataset.append, dataset.setthefieldvalues, dataset.post, as soon as the append is called, you loose the current record which pointed to the record you want to duplicate. So you could use two datasets and copy one to the other, but this uses extra memory, etc. or you could copy the contents of the current record into a temporary place then call the append.
Taking this second option :
The first solution I came up with was to use VarArrayCreate, but this was slow. Another altenative was to go lower level and use the ActiveBuffer method, but then your getting into memory copies etc. and I didn`t know enough about the internal memory representation of a record.
So this is what I came up with, and has the added benefit of being faster than using the dataset.append dataset.setthefieldvalues dataset.post method. It simply copies the current record in to an array of variant (note NOT a variant array which needs redimsand the such) then uses the dataset.appendrecord method to add the record in one go.
procedure DuplicateCurrentRecord(aDataSet : TDataSet);
var
Data : array of variant;
aRecord : array of TVarRec;
i : integer;
max : integer;
begin
max := aDataSet.fields.count -1;
// set the lenghth of the arecord array to be the same as the number of
// elements in the data array
SetLength(arecord,max+1);
SetLength(data,max+1);
// set the variant type pointers to the data array
for i := 0 to max do
begin
arecord[i].VType := vtVariant;
arecord[i].VVariant := @data[i];
end;
// Copy the Record to the Array
for i := 0 to max do
Data[i] := aDataSet.fields[i].value;
// finally append the record in one go
aDataSet.AppendRecord(aRecord);
end;
One reply on “QUICK Duplicate Current Record Procedure”
Thanks for this example!!!