Random Files
Random Files
Random files are record-based files with an internal structure that supports "direct access" by
record number. This means that your program can read from or write to a specific record in a
random access file, say the 50th record, without reading through the previous 49 records.
Compare that to reading or writing a sequential file, where to get to a specific record, you must
read through all preceding records.
The difference between random access and sequential access can be likened to accessing
music on a CD versus a cassette tape. To get to song number 6, you can tell your CD player to
go directly to track 6, whereas on a cassette tape, you must fast-forward through the first 5
songs to get to song number 6.
In the earlier days of BASIC, before the "client-server era" where RAD systems such as VB,
Delphi, and PowerBuilder interacted with desktop and ODBC databases such as MS-Access,
SQL Server, and Oracle, random access files were used as building blocks to put together data
access systems that could be considered early forms of desktop databases.
The "full blown" syntax for the Open statement was given in the previous topic on binary files.
The syntax for the Open statement, as it pertains to random files, is as follows:
If you only want to read from the random access file, use:
and if you only want to write to the random access file, use:
Open filename For Random Access Write As #filenumber Len = reclength
and if you want to both read from and write to the random access file (for example, you want to
access a particular record and then update one or more of its fields), use:
Open filename For Random Access Read Write As #filenumber Len = reclength
In the syntax formats above, reclength refers to the total length in bytes of all of the fields
(variables) you define as part of a user-defined Type (UDT) structure. The variable that you
base on the UDT serves as the storage facility, or record variable, into which a record from the
random file is read, or from which a record to the random file is written.
For example, the sample program for this topic will use a random access version of the
employee file we used in the topics on sequential files. The Type structure for the employee
record will be defined as follows:
EmpName As String * 20
DeptNbr As Integer
JobTitle As String * 25
HireDate As Date
HrlyRate As Single
End Type
The record variable based on this EmployeeRecord Type will be defined as:
Note that the String variables that make up this structure are defined as fixed-length strings.
This is important for efficient access of the random file. Given that (in VB6 and lower), the size
of an Integer is 2, the size of a Date is 8, and the size of a Single is 4, the total length of the
structure above is 59 (20 + 2 + 25 + 8 + 4)
Thus, an Open statement for the random employee file could be written as:
As #intRndEmpFileNbr Len = 59
In the syntax above, the Len function is used on the record variable, thus "letting the computer
do the work" of figuring out the total length of the structure. And, using this method, if we add
fields to or remove fields from the structure, we don't have to worry about recalculating the total
length.
The Get Statement
The Get statement is used read data from a file opened in random mode. The syntax, as it
applies to random files is:
Recnumber is the record position within the file that is read. The record position is "one-based",
meaning the first record position in the file is 1, the second record position is 2, and so on. You
can omit this entry, in which case the next record following the last Get or Put statement is read.
If you omit the record number entry, you must still include the delimiting commas in the Get
statement, for example:
Varname is the record variable into which the data will be read. The record variable is a variable
defined on the UDT record structure as described above. Once the Get statement is executed,
the data from the file record can be referenced using the following syntax:
recordname.fieldname
mudtEmpRecord.EmpName
The Put Statement
The Put statement is used write data to a file opened in random mode. The syntax, as it applies
to binary files is:
Recnumber is the record position within the file which is written. The record position is "one-
based", meaning the first record position in the file is 1, the second record position is 2, and so
on. You can omit this entry, in which case the next record following the last Get or Put statement
is written. If you omit the record number entry, you must still include the delimiting commas in
the Put statement, for example:
Varname is the record variable from which the data will be written. The record variable is a
variable defined on the UDT record structure as described above.
Sample Program
The "Try It" sample program performs three main functions that demonstrate the features of
random files: (1) creates a random file based on input from a sequential file; (2) reads back the
random file just created and displays its contents; and (3) retrieves a record from the random file
given the record number, and updates a field in the retrieved record based on user input.
The code listed below is heavily commented to aid in the understanding of how the program
works.
The Type declaration for EmployeeRecord must be defined in the General Declarations section
of the from (the portion of the code prior to where any Subs or Functions are defined). The
record variable "mudtEmpRecord" is also declared in this area (although strictly speaking, that
is not an absolute requirement, as it could have been declared at the local level with the Dim
statement in the cmdTryIt_Click event procedure).
Option Explicit
EmpName As String * 20
DeptNbr As Integer
JobTitle As String * 25
HireDate As Date
HrlyRate As Single
End Type
'-----------------------------------------------------------------------
' In the first part of this sample program, we will create, or load,
' file that was used in one of the sample programs for sequential access
' files.
'-----------------------------------------------------------------------
intSeqEmpFileNbr = FreeFile
Kill strRndEmpFileName
End If
intRndEmpFileNbr = FreeFile
' Initialize record count variable to keep track of how many records will
intRecordCount = 0
' This loop will read a record from the comma-delimited sequential employee file
' and write a corresponding record to its random access counterpart ...
Do Until EOF(intSeqEmpFileNbr)
' Read a record's worth of fields from the comma-delimited employee file,
' Assign each variable read in from the comma-delimited file to its corresponding
' field in the mudtEmpRecord record variable (based on the EmployeeRecord UDT).
' Note that a With/End With block is used. If With/End With was not used, this set
With mudtEmpRecord
.EmpName = strEmpName
.DeptNbr = intDeptNbr
.JobTitle = strJobTitle
.HireDate = dtmHireDate
.HrlyRate = sngHrlyRate
End With
' Now that the record variable has been populated with the proper data,
' write the record out to the random file using the Put statement ...
intRecordCount = intRecordCount + 1
Loop
' Close the sequential file and the random file ...
Close #intSeqEmpFileNbr
Close #intRndEmpFileNbr
'-----------------------------------------------------------------------
' In the next part of this sample program, we will display the records
' written to the random file by reading them back and printing their
'-----------------------------------------------------------------------
Cls
Print intRecordCount & " employee records were written to the random file."
Tab(25); "DEPT"; _
Print "--------"; _
Tab(25); "----"; _
Tab(35); "---------"; _
Tab(60); "---------"; _
Tab(70); "---------"
' Open the random file for reading ...
intRndEmpFileNbr = FreeFile
' Since we know how many records are in the file, we can use a For/Next loop
' With the Get statement, read the next (or first) record from the
' random file, storing its contents in the mudtEmpRecord structure ...
' Print the data from the record onto the form. Once again, a With/End With
' block is used to "factor out" the record variable. If With/End With was
' not used, the Print statement would have to be written as follows:
With mudtEmpRecord
Print .EmpName; _
Tab(25); Format$(.DeptNbr, "@@@@"); _
Tab(35); .JobTitle; _
End With
Next
Close #intRndEmpFileNbr
'-----------------------------------------------------------------------
' In the last part of this sample program, we will request an employee
' record and then update the job title for that employee.
'-----------------------------------------------------------------------
' Prompt the user to enter a valid record number (the record number must be
' between 1 and the number of records in the file). The loop below validates
' the entry, and re-prompts the user if necessary, before moving on ...
Do
strRecordNumber _
= InputBox("Enter a record number between 1 and " & intRecordCount & ":", _
intRecordNumber = Val(strRecordNumber)
End If
' Open the random employee file for read/write access ...
intRndEmpFileNbr = FreeFile
' Get the employee record corresponding to the record number entered above ...
' Prompt the user to enter a new job title for the employee ...
strPrompt = "The employee in record # " & intRecordNumber & " is " _
& Trim$(mudtEmpRecord.EmpName) _
& ". Enter the new job title for this employee:"
Else
mudtEmpRecord.JobTitle = strNewJob
End If
Close #intRndEmpFileNbr
End Sub
Upon clicking Try It button, the random file will be written out and then read back and its
contents will be displayed. The user will then be prompted to enter a record number, as shown
below:
The program will then prompt you to enter a new job title for the retrieved employee, showing
the exsiting job title as a default:
You can then enter the new job title:
A message confirming the update is then displayed below the previously displayed data: