Visit our Sponsor   Visit our Sponsor
delphi3000.com - the free delphi knowledge platform
delphi3000.com - the free delphi knowledge platform
Have a look at your member-status

connecting people's knowledge


  - Recent ArticlesRSS feed for Recent Articles on delphi3000.com
  - List of All Articles
  - Top Viewed Articles
  - Articles (+Attachem.)
  - Articles Of Interest
  - Categories
  - Top Uploader
  - Search
  - Index

  - My Home
  - Submit an Article
  - My Articles
  - My Personal Data
  - My Bookmarks
  - Activities
  - Login/Logout

  - Sign Up
  - Why Sign Up
  - Newsletter

  - Press
  - Advertise

  - Contact
  - Feedback





Community
Borland
ClubeDelphi
Dr. Bob
UK-BUG
Delphi Meetings
Planeta Delphi







Startblatt.de






Share this article with friendsShare this article with friends
Rate this articleRate this article - to keep the quality of delphi3000.com !
Comment this article or read through previous comments (5)


QUICK Duplicate Current Record ProcedureFormat this article printer-friendly!Bookmark function is only available for registered users!
Product:
Delphi all versions
Category:
DB-General
Skill Level:
Scoring:
Last Update:
08/29/2000
Search Keys:
delphi delphi3000 article borland vcl code-snippet copy record duplicate appendrecord dataset
Times Scored:
13
Visits:
7945
Uploader: Matt Harrison
Company:
Reference: DSpace
 
Question/Problem/Abstract:
How do you duplicate a record in a dataset ?

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 the 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 ofthe 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.

Answer:



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;





Please rate this article!
Skill level:
BeginnerExpert

Useful:
No!Very!

Overall rating:
PoorExcellent



Comments to this article
Write a new comment
How to filter readonly fields ?
    Josir Gomes (May 22 2001 2:38PM)

Eventually, some datasets have readonly or calculated fields.
So the AppendRecord approach will not work, right ?

But the article lights my bulb to other solutions!
Thanks for the tip,

  Josir
Respond

Using a StringList
    Chris Bray (Mar 19 2001 5:02AM)

I have implemented this capability using a string list as the temporary placeholder and the .asString method to get and set the values in a pair of  simple for..do loops.

That works perfectly and quickly.

Chris Bray.

Respond

Suggestion
    Attila Kovacs (Aug 12 2000 1:53PM)

var
  FieldNames: string
  i: integer;
  FieldValues: Variant;
begin
  for i:=0 to Table1.FieldCount-1 do
    if i<>0 then
      FieldNames:=FieldNames+`;`+Table1.Fields[i].FieldName
    else
      FieldNames:=Table1.Fields[i].FieldName;
  FieldValues:=Table1[FieldNames];
  Table1.Append;
  Table1[FieldNames]:=FieldValues;
  Table1.Post;
end;

Respond

BookMarks?
    Gert (Aug 10 2000 5:02PM)

Maybe a silly question, but why dont you just use a bookmark as a pointer to the current record?
Respond

RE: BookMarks?
Matt Harrison (Aug 11 2000 3:27AM)

The point is if you used a bookmark then as soon as you call append the record pointer is on the last record so how do you refer to the orignal record with out moving the record pointer off the new record.  The only way would be to copy the bookmarked records data somewhere temporarily then call append then refer to the copy in memory to set the appended records fields.

You can do this with vararraycreate() but it is not as fast as the method above.
Hope this helps.
Respond














 
Sign up to consume product discounts for Bronze memberships !

read more


  Visit our Sponsor

 

  Community Ad of
R. Lefter
 
   














 







     
  Copyright © 2000 - 2007 delphi3000.com - All rights reserved. Terms of use. || Privacy
delphi3000.com is a service by bluestep.com IT-Services GmbH (Vienna)