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.
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.
type TMember = record Name : string; eMail : string; Posts : Cardinal; end;
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:
Now, when we have a record, we use a dot to isolate the fields of DelphiGuide:
var DelphiGuide, AMember : TMember;
Note: the above piece of code could be rewritten with the use of with keyword:
DelphiGuide.Name := 'Zarko Gajic'; DelphiGuide.eMail := 'firstname.lastname@example.org'; DelphiGuide.Posts := 15;
We can now copy the values of DelphiGuides fields to AMember:
with DelphiGuide do begin Name := 'Zarko Gajic'; eMail := 'email@example.com'; Posts := 15; end;
AMember := DelphiGuide;
Record Scope and visibilityRecord 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.
To learn more about Delphi's variable scope go the Variable Scope article.
An Array of RecordsSince TMember acts like any other Object Pascal type, we can declare an array of record variables:
To access the fifth member we use:
var DPMembers : array[1..50] of TMember;
Or, to display information (e-mail, for example) about every member we could use:
with DPMembers do begin Name := 'First name Last'; eMail := 'FirstLast@domain.com' Posts := 0; end;
Note: Here's how to declare and initialize a constant array of records in Delphi
var k: cardinal; for k:= 1 to 50 do ShowMessage(DPMembers[k].eMail) ;
Records as Record fieldsSince 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:
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:
type TExpandedMember = record SubmitType : string; Member : TMember; end;
var SubTypeMember :TExpandedMember; SubTypeMember.SubmitType := 'VCL'; SubTypeMember.Member.Name := 'vcl Programmer'; SubTypeMember.Member.eMail := 'firstname.lastname@example.org'; SubTypeMember.Member.Name := 555;
Record with "unknown" fieldsA 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"