Saturday, January 12, 2008

TDataset Enumerator

You already know that I love all things enumeratorish. Just recently I found a great example that combines three kinds of Delphi magic to allow the programmer to write very simple TDataset enumeration loops. [And for the sake of my life I can't remember where I first saw the link to this code. Apologies to the original author.] [Updated 2008-01-14: Jim McKeeth found my source. Apparently Nick Hodges was the first to blog about this enumerator. Thanks, Nick!]

This TDataset enumerator was written by Uwe Raabe and is freely available in the CodeGear's Code Central as item #25386.

The three trick he uses are:

  1. Data helper is used to push enumerator support into TDataset.
  2. Standard enumerator support to enumerate over dataset and return special descendant of the Variant type for each record.
  3. Custom variant type to automagically access record fields by by adding .RecordFieldName to the variant variable. [I must admit I didn't even know this was possible to do in Delphi.]

All together those tricks allow you to write very simple TDataset iteration loops (code taken from the example in the DN #25386):

var
Employee: Variant;
S: string;

for Employee in QuEmployee do begin
S := Trim(Format('%s %s', [Employee.First_Name, Employee.Last_Name]));
if Employee.Hire_Date < EncodeDate(1991, 1, 1) then
S := '*' + S;
end;

Excellent job!

5 comments:

  1. This was news to me, too. Great stuff! I'll have to try it out sometime. :)

    ReplyDelete
  2. Anonymous15:18

    Very usefull. I needed that. Many thanks.

    ReplyDelete
  3. Nick Hodges had a link to it. Really cool stuff.

    ReplyDelete
  4. Anonymous19:21

    Pretty nice stuff, it can be improved as:

    -Instead of TBookmark use TBookmarkStr and then change the destructor with :
    "if FBookmark <> '' then
    FDataSet.Bookmark := FBookmark;"

    So it does not crash when empty or modify

    -Also is a good idea to raise an exception when the field does not exists.

    Thanks

    ReplyDelete
  5. @jim: So that was my source. Thanks!

    @anonymous: You should post those comments to the CodeCentral. I'm no the author of this enumerator.

    ReplyDelete