Thursday 5 March 2009

Delphi TDBGrid Add Duplicate Row

Recently I had to develop a delphi method that would allow users to select one or more rows in a DBGrid and create duplicates of the selected rows in the same grid.


The factors that made this non trivial were the facts that you had to add the rows to the same grid as the source rows, there was a auto incrementing field in the grid and some of the field had to be left blank in the duplicate rows.


Things that I had to think about


I tried to get all the values into an array. This was fine but when I tried to use the array as the parameter for Dataset.AppendRecord, I got a compile error which stated that it was looking for an Array but was given a dynamic array. So I had to change the way I did it and had to add another forloop to insert all the values from the source row to the duplicate row.


I had to move the Auto Incrementing field to the end of the the clientdataset so that I didn't have to specify a value for it. If I tried to specify a value for it or tried to assign 'null' to it, then the code didn't compile. This is the reason for -2 in the for loop.


Here is the code


procedure TFrmFoodDetails.ActionCreateSampleExecute(Sender: TObject);
var
I, J : Integer;
ArRec : Array of Variant;
begin

for I := 0 to DbgResults.SelectedRows.Count -1 do
begin
SetLength(ArRec,CdsResults.FieldCount); // set length of array to number of fields in client dataset
CdsResults.GotoBookmark(Pointer(DbgResults.SelectedRows.Items[i]));
// For loop with -2 as need to ignore 'AutoInc' field
// Double forloop one to get cell values and one to insert cell values
for J := 0 to CdsResults.Fields.Count -2 do
begin
ArRec[J] := CdsResults.Fields[J].Value;
end;
// second for loop
CdsResults.Append;
for J := 0 to CdsResults.Fields.Count -2 do
begin
CdsResults.Fields[J].Value := ArRec[J];
end;

// Remove information that will be different in new record
CdsResultsResultNum.Clear;
CdsResultsResultString.Clear;
CdsResultsValidReport.Clear;
CdsResultsPartNo.Clear;

// End insert
CdsResults.Post;

// Remeber to release resources
ArRec := nil;
end;
end;



This may not be the best way to do it but it worked for me. If you have any comment s then let me know

No comments: