Understanding and Using Record Data Types in Delphi

Young man surfing the net
BJI/Blue Jean Images/Getty Images

Sets are ok, arrays are great.

Suppose we want to create three one-dimensional arrays for 50 members in our programming community. The first array is for names, the second for e-mails, and the third for number of uploads (components or applications) to our community.

Each array (list) would have matching indexes and plenty of code to maintain all three lists in parallel. Of course, we could try with one three-dimensional array, but what about it's type?

We need string for names and e-mails, but an integer for the number of uploads.

The way to work with such a data structure is to use Delphi's record structure.

TMember = record ...

For example, the following declaration creates a record type called TMember, the one we could use in our case.

   TMember = record
     Name : string;
     eMail : string;
     Posts : Cardinal;

Essentially, a record data structure can mix any of Delphi's built in types including any types you have created. Record types define fixed collections of items of different types. Each item, or field, is like a variable, consisting of a name and a type.

TMember type contains three fields: a string value called Name (to hold the name of a member), a value of a string type called eMail (for one e-mail), and an integer (Cardinal) called Posts (to hold the number of submissions to our community).

Once we have set up the record type, we can declare a variable to be of type TMember.

TMember is now just as good variable type for variables as any of Delphi's built in types like String or Integer. Note: the TMember type declaration, does not allocate any memory for the Name, eMail, and Posts fields;

To actually create an instance of TMember record we have to declare a variable of TMember type, as in the following code:

 var DelphiGuide, AMember : TMember; 

Now, when we have a record, we use a dot to isolate the fields of DelphiGuide:

 DelphiGuide.Name := 'Zarko Gajic';
 DelphiGuide.eMail := 'delphi@aboutguide.com';
 DelphiGuide.Posts := 15; 

Note: the above piece of code could be rewritten with the use of with keyword:

 with DelphiGuide do
   Name := 'Zarko Gajic';
   eMail := 'delphi@aboutguide.com';
   Posts := 15; end;

We can now copy the values of DelphiGuide’s fields to AMember:

 AMember := DelphiGuide; 

Record Scope and visibility

Record type declared within the declaration of a form (implementation section), function, or procedure has a scope limited to the block in which it is declared. If the record is declared in the interface section of a unit it has a scope that includes any other units or programs that use the unit where the declaration occurs.

An Array of Records

Since TMember acts like any other Object Pascal type, we can declare an array of record variables:

 var DPMembers : array[1..50] of TMember; 

To access the fifth member we use:

 with DPMembers[5] do begin
   Name := 'First name Last';
   eMail := 'FirstLast@domain.com'
   Posts := 0;

Or, to display information (e-mail, for example) about every member we could use:

 var k: cardinal;
 for k:= 1 to 50 do
    ShowMessage(DPMembers[k].eMail) ; 

Note: Here's how to declare and initialize a constant array of records in Delphi

Records as Record fields

Since a record type is legitimate as any other Delphi type, we can have a field of a record be a record itself. For example, we could create ExpandedMember to keep track of what the member is submitting along with the member information:

    TExpandedMember = record
      SubmitType : string;
      Member : TMember;

Filling out all the information needed for a single record is now somehow harder. More periods (dots) are required to access the fields of TExpandedMember:

 var SubTypeMember :TExpandedMember;
 SubTypeMember.SubmitType := 'VCL';
 SubTypeMember.Member.Name := 'vcl Programmer';
 SubTypeMember.Member.eMail := 'vcl@aboutguide.com';
 SubTypeMember.Member.Name := 555; 

Record with "unknown" fields

A record type can have a variant part (I don't mean Variant type variable). Variant records are used, for example, when we want to create a record type that has fields for different kinds of data, but we know that we will never need to use all of the fields in a single record instance. To learn more about Variant parts in Records take a look at Delphi's help files. The use of a variant record type is not type-safe and is not a recommended programming practice, particularly for beginners.

However, variant records can be quite usefull, if you ever find yourself in a situation to use them, here's the secont part of this article: "However, variant records can be quite usefull, if you ever find yourself in a situation to use them, here's the secont part of this article: Records in Delphi - Part 2"