Reading and Writing UDTs to file

The previous tip showed how and where to declare a user defined type, and a simple example of how to assign values to elements of the user defined type. In this tip you will learn how to determine how large all of the elements of an array of records of a user defined type are so you can write them to file. I will also show how to read the array of records back in from the disk file. .

Each native data type in Visual Basic has it's own size. A dynamic string variable has 10 bytes of overhead plus one byte for each character in the string, an integer variable is 2 bytes long. A one dimensional array in Visual Basic is as large as all of it's data elements plus 24 bytes of overhead. Boolean values are two bytes in size.

For more specifics on the sizes of the native data types, see the Data Type Summary in the Visual Basic help file

Declare a variable to hold the cumulative total of bytes in your array. For this example I will use the user defined type from the What is a UDT? example. Here is a function which will sum the size of one record in the array.

Public Function RecordLength(ThisRecord As Long)
    Length = 0   'initialize
    'add size of each data element and it's associated overhead to the length
    With People(ThisRecord)
        Length = Length + Len(.BirthName) + 10 ' string
        Length = Length + Len(.StreetAddress) + 10 'string
        Length = Length + Len(.City) + 10 'string
        Length = Length + Len(.State) + 10 'string
        Length = Length + Len(.ZipCode) + 10 'ZipCode string
        Length = Length + 2 'PhoneArea integer
        Length = Length + 2 'PhonePrefix integer
        Length = Length + 2 'PhoneSuffix integer
        Length = Length + Len(.Comments) + 10 ' string
    End With
    'return value to outside code
    RecordLength = Length
End Function

Here is the save to file sub routine with the call to the above function.

Public Sub SaveTheFile()
    Dim ThisRecord As Long
    Dim RecordNumber As Long
    Dim NumberRecords As Long
' compute the size of the array in bytes to arrive at record length
    ThisRecord = -1  'start with first record in the array which is zero [loop increments first]
    NumberRecords = UBound(People)  ' get number of records with data in them
    Length = 24 'start with the overhead for an array
    Do
        ThisRecord = ThisRecord + 1
        Length = Length + RecordLength(ThisRecord) 'call RecordLength function and sum values
    Loop Until ThisRecord = NumberRecords
'put the array in the file
    FileNumber = FreeFile()
    RecordNumber = 1
    Open RecordFile For Random As #FileNumber Len = Length
    Put #FileNumber, RecordNumber, People() 'put the whole array in the file
    Close FileNumber
End Sub

Note that the overhead for the array is summed in the SaveTheFile routine, not in the RecordLength function. This routine saves the entire array to file as one record which can be read back into an array with the following routine.

Public Sub GetArrayFromFile()
    RecordNumber = 1
    FileNumber = FreeFile() ' get a free file number
    Length = FileLen(RecordFile) 'use the length of the file to determine the size of the array
    Open RecordFile For Random As #FileNumber Len = Length
    Get #FileNumber, RecordNumber, People() 'load the array from the record in the file
    Close FileNumber
End Sub

This pair of routines has the advantage of being able to read and write the entire array of records as a single record. This makes it unnecessary to read each individual record from the file.

Reading and writing individual records from the array would require calculating and recording the lengths of each record in the array to the file as the file's first record. This first record would in turn have to be an array of record lengths which would need to be updated each time any data element of the user defined type array was changed.

Note that the above routines assume the use of a Public variable which contains the name and path to the RecordFile being used.

C Ray Parrish, Cottage Grove, Oregon