Arrays
General Array Processing – Part 2
Passing an Array to a Function or Sub
Assume the following array declaration:
Dim aintTemps(1 To 7) As Integer
Assume the following Sub to print the contents of the array is defined. This Sub accepts one parameter, an array of temperatures. The Sub header must specify the array parameter with an empty set of parentheses, but the bounds must NOT be specified. Note how the LBound and UBound functions are used to determine the array's bounds:
Private Sub PrintTemps(paintTemps() As Integer)
Dim intX As Integer
For intX = LBound(paintTemps) To UBound(paintTemps)
Print paintTemps(intX)
Next
End Sub
To call the PrintTemps sub, pass the array name, with or without a set of empty parentheses. The following statements are all valid calls to this sub:
PrintTemps aintTemps
PrintTemps aintTemps()
Call PrintTemps(aintTemps)
Call PrintTemps(aintTemps())
The sample program implements the concepts described above. In the cmdTryIt_Click event, the user is prompted to enter each of seven temperatures, which are stored in the "aintTemps" array. After the temperatures are entered, the "PrintTemps" Sub is called, passing the array. The PrintTemps Sub then prints the contents of the array on the form. The code for the cmdTryIt_Click and PrintTemps Subs is shown below:
Private Sub cmdTryIt_Click()
Dim aintTemps(1 To 7) As Integer
Dim intX As Integer
For intX = 1 To 7
aintTemps(intX) = Val(InputBox("Enter temperature #" & intX & ":"))
Next
PrintTemps aintTemps
End Sub
Private Sub PrintTemps(paintTemps() As Integer)
Dim intX As Integer
For intX = LBound(paintTemps) To UBound(paintTemps)
Print paintTemps(intX)
Next
End Sub
Download the VB project code for the example above here.
Exceptions for Variant Arrays
There are some exceptions to the rules above when the Variant datatype is involved:
For example, if the array is defined as
Dim avntTemps(1 To 7) As Variant
and you call the sub as you normally would, as in
PrintTemps avntTemps
then the Sub header can be specified as
Private Sub PrintTemps(pavntTemps() As Variant)
or
Private Sub PrintTemps(pavntTemps As Variant)
Note: Recall that since Variant is the default datatype in VB, the clause As Variant is optional in both the array definition and in the Sub header.
Assume the following definition:
Private vntTemps As Variant
Statements such as the following would "transform" this variable into an array:
vntTemps = Array(35, 41, 50, 45, 37, 39, 40)
or
ReDim vntTemps(0 To 6)
However, in passing this variable to a Sub that expects it as a parameter, you still would treat it as a non-array variable.
The call:
PrintTemps vntTemps
The Sub:
Private Sub PrintTemps(pvntTemps As Variant)
Dim intX As Integer
' The IsArray test is optional– you need not use it if you know
' you have an array ...
If IsArray(pvntTemps) Then
For intX = LBound(pvntTemps) To UBound(pvntTemps)
Print pvntTemps(intX)
Next
Else
Print pvntTemps
End If
End Sub
Passing a UDT Array to a Function or Sub
The rules for passing a UDT array to a Function or Sub follows the same principles as those for passing other types of arrays to a function or subroutine. Just make sure the proper user-defined Type is specified in the "As" clause of the parameter being passed in the Sub or Function header.
The sample program below is a modification of the sample program from the previous topic's section on "Loading a UDT Array from a File and Printing Its Contents". In this version, the printing of the UDT array's contents takes place in a separate Sub called "PrintEmps". The call to PrintEmps passes the UDT array as follows:
PrintEmps maudtEmpRecord
Note that the Sub header expects an array of type "EmployeeRecord" to be passed in:
Private Sub PrintEmps(paudtEmps() As EmployeeRecord)
The code for the modified sample program is shown below:
Option Explicit
Private Type EmployeeRecord
EmpName As String
DeptNbr As Integer
JobTitle As String
HireDate As Date
HrlyRate As Single
End Type
Private maudtEmpRecord() As EmployeeRecord
Private Sub cmdClear_Click()
Cls
End Sub
Private Sub cmdExit_Click()
End
End Sub
Private Sub cmdTryIt_Click()
Dim strEmpFileName As String
Dim strBackSlash As String
Dim intEmpFileNbr As Integer
Dim intRecCount As Integer
strBackSlash = IIf(Right$(App.Path, 1) = "\", "", "\")
strEmpFileName = App.Path & strBackSlash & "EMPLOYEE.DAT"
intEmpFileNbr = FreeFile
Open strEmpFileName For Input As #intEmpFileNbr
intRecCount = 0
Do Until EOF(intEmpFileNbr)
intRecCount = intRecCount + 1
ReDim Preserve maudtEmpRecord(1 To intRecCount)
With maudtEmpRecord(intRecCount)
Input #intEmpFileNbr, .EmpName, _
.DeptNbr, _
.JobTitle, _
.HireDate, _
.HrlyRate
End With
Loop
Close #intEmpFileNbr
PrintEmps maudtEmpRecord
End Sub
Private Sub PrintEmps(paudtEmps() As EmployeeRecord)
Dim intX As Integer
For intX = LBound(paudtEmps) To UBound(paudtEmps)
With paudtEmps(intX)
Print .EmpName; _
Tab(25); Format$(.DeptNbr, "@@@@"); _
Tab(35); .JobTitle; _
Tab(55); Format$(.HireDate, "mm/dd/yyyy"); _
Tab(70); Format$(Format$(.HrlyRate, "Standard"), "@@@@@@@")
End With
Next
End Sub
Download the VB project code for the example above here.
Using ParamArray
The ParamArray keyword is used in the Sub or Function header for procedures that will accept an arbitrary number of arguments. It is always an array of Variants.
Consider the following Sub:
Private Sub SumThem(ParamArray pvntNums() As Variant)
Dim intX As Integer
Dim lngSum As Long
For intX = LBound(pvntNums) To UBound(pvntNums)
lngSum = lngSum + pvntNums(intX)
Next
Print "The Sum is "; lngSum
End Sub
On the surface, the above Sub looks like a procedure which accepts an array of Variant values and sums them. However, the presence of the keyword ParamArray means that this Sub can be called with any number of arguments. When you call this Sub, you would pass it not an array, but any number of individual values.
Following are some sample calls and the results that they would produce:
Dim intValueA As Integer
Dim intValueB As Integer
intValueA = 3
intValueB = 7
SumThem 1, 3, 5, 8 ' SumThem will print 17
SumThem intValueA, 4, 2 ' SumThem will print 9
SumThem intValueA, intValueB ' SumThem will print 10
Following is the output of a "Try It" project using the code discussed above (with some extra Print statements between calls):
Download the VB project code for the example above here.
More on ParamArray Rules:
Example:
Private Sub SumThem(ParamArray pvntNums() As Variant)
Dim intX As Integer
Dim lngSum As Long
If IsMissing(pvntNums) Then
Exit Sub
End If
For intX = LBound(pvntNums) To UBound(pvntNums)
lngSum = lngSum + pvntNums(intX)
Next
Print "The Sum is "; lngSum
End Sub
The For Each/Next Loop
There is a variation of the For/Next loop (the For Each/Next loop) that allows you to traverse a either the elements of an array or a set of objects in a collection. Objects and Collections will come into play a little later in your travels with VB; here we will look at how the For Each/Next loop can be used to process the elements of an array. The syntax of the For Each/Next loop is as follows:
For Each ElementVariable In ArrayName
' process the current ElementVariable
Next
The ElementVariable must be defined with the Variant datatype.
Thus, the "SumThem" procedure could alternately (and less efficiently) have been written as follows:
Private Sub SumThem(ParamArray pvntNums() As Variant)
Dim vntX As Variant
Dim lngSum As Long
For Each vntX In pvntNums
lngSum = lngSum + vntX
Next
Print "The Sum is "; lngSum
End Sub