RAD Studio
ContentsIndex
PreviousUpNext
Marking and Returning to Records

In addition to moving from record to record in a dataset (or moving from one record to another by a specific number of records), it is often also useful to mark a particular location in a dataset so that you can return to it quickly when desired. TDataSet introduces a bookmarking feature that consists of a Bookmark property and five bookmark methods. 

TDataSet implements virtual bookmark methods. While these methods ensure that any dataset object derived from TDataSet returns a value if a bookmark method is called, the return values are merely defaults that do not keep track of the current location. TDataSet descendants vary in the level of support they provide for bookmarks. None of the dbExpress datasets add any support for bookmarks. ADO datasets can support bookmarks, depending on the underlying database tables. BDE datasets, InterBase express datasets, and client datasets always support bookmarks. 

The Bookmark property indicates which bookmark among any number of bookmarks in your application is current. Bookmark is a string that identifies the current bookmark. Each time you add another bookmark, it becomes the current bookmark.

To create a bookmark, you must declare a variable of type TBookmark in your application, then call GetBookmark to allocate storage for the variable and set its value to a particular location in a dataset. The TBookmark type is a Pointer.

When passed a bookmark, GotoBookmark moves the cursor for the dataset to the location specified in the bookmark. Before calling GotoBookmark, you can call BookmarkValid to determine if the bookmark points to a record. BookmarkValid returns True if a specified bookmark points to a record.

You can also call CompareBookmarks to see if a bookmark you want to move to is different from another (or the current) bookmark. If the two bookmarks refer to the same record (or if both are nil), CompareBookmarks returns 0.

FreeBookmark frees the memory allocated for a specified bookmark when you no longer need it. You should also call FreeBookmark before reusing an existing bookmark.

The following code illustrates one use of bookmarking:

procedure DoSomething (const Tbl: TTable)
var
  Bookmark: TBookmark;
begin
  Bookmark := Tbl.GetBookmark; { Allocate memory and assign a value }
  Tbl.DisableControls; { Turn off display of records in data controls }
  try
    Tbl.First; { Go to first record in table }
    while not Tbl.Eof do {Iterate through each record in table }
    begin
      { Do your processing here }
      .
      .
      .
      Tbl.Next;
    end;
  finally
    Tbl.GotoBookmark(Bookmark);
    Tbl.EnableControls; { Turn on display of records in data controls, if necessary }
    Tbl.FreeBookmark(Bookmark); {Deallocate memory for the bookmark }
  end;
end;

 

void DoSomething (const TTable *Tbl)
{
  TBookmark Bookmark = Tbl->GetBookmark(); // Allocate memory and assign a value
  Tbl->DisableControls(); // Turn off display of records in data controls
  try
  {
    for (Tbl->First(); !Tbl->Eof; Tbl->Next()) // Iterate through each record in table
    {
      // Do your processing here
      .
      .
      .
    }
  }
  __finally
  {
    Tbl->GotoBookmark(Bookmark);
    Tbl->EnableControls(); // Turn on display of records in data controls
    Tbl->FreeBookmark(Bookmark); // Deallocate memory for the bookmark
  }
}

Before iterating through records, controls are disabled. Should an error occur during iteration through records, the finally clause ensures that controls are always enabled and that the bookmark is always freed even if the loop terminates prematurely.

Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.
What do you think about this topic? Send feedback!