The fields within a User-Defined Type can be made up of other User-Defined Types. Just like a set of Chinese boxes, with each box containing a smaller box, you can nest one User-Defined Type within another. The result is that you create data structures that have a hierarchy similar to the directory tree structure of your hard drive.
Instead of storing the student names as two separate fields, we could instead define a Type called NameRec as follows:
TYPE NameRec
Last AS STRING * 20
First AS STRING * 15
Initial AS STRING * 1
END TYPE
Then, when we define our Student Record Type, we can define the field containing the individual student's name as NameRec:
TYPE StudentRecord
FullName AS NameRec
IdNum AS LONG
Contact AS NameRec
ContactPhone AS STRING * 14
ContactRel AS STRING * 8
AverageGrade AS SINGLE
END TYPE
You could, of course carry this idea a step further, and define other components of the student record as nested records. For instance, a ContactRecord or even a PhoneRec but we'll leave that refinement up to you. To access the fields of a nested record, simply extend the dot notation. Just as the backslash (\) is used to separate the individual subdirectory names in a path (i.e., C:\PROJECTS\PROGRAM), the period is used within record variable names to separate the member elements from the base Type. For instance:
StudentRecord.FullName
refers to the FullName field (which happens to be of Type NameRec) within Student Record, and:
StudentRecord.FullName.First
refers to the sub-field First within the FullName field.
You can nest User-Defined Types as deeply as you want to, as long as the entire name used to refer to a field is within the maximum identifier length of 255 characters. In practical terms however, you probably would not want to carry nesting beyond two or, at most, three levels. Beyond that, it becomes clumsy, difficult to remember, and you are more likely to make typing errors. Note that User-Defined Types cannot contain circular references - for example, a UDT called StudentRecord cannot contain a field of Type StudentRecord.
See Also
Accessing the fields of a User-Defined Type
Arrays within User-Defined Types
Using arrays of User-Defined Types
Using User-Defined Types with procedures and functions
Storage requirements and restrictions