Understanding VB6 Arrays (Advanced)

Level:
Level3

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:

 

  • If the array is defined as having the Variant datatype, then the parentheses after the array name in the Sub or Function are optional.

 

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.

 

  • If you define a non-array Variant variable and later make it into an array using the Array function or ReDim statement, you would still pass it to a Sub or Function as a standard variable. In the Sub or Function, you could still process the variable as an array using LBound and UBound and referring to its elements with indexes (subscripts). Additionally, you could optionally first test the Variant variable to see if it is an array using the IsArray function.

 

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:

 

  • The ParamArray argument is always optional, and as such, if used, it must be the last argument specified in the Sub or Function's argument list. If there is the possibility that you will call the procedure without any arguments, the procedure should use the IsMissing function to detect that condition.

 

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

 

  • A Sub or Function that uses ParamArray may not have any other Optional arguments.

 

  • The keywords ByVal, ByRef, and Optional may not be used with ParamArray.

 

 

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

If you enjoyed this post, subscribe for updates (it's free)

I noticed the LBound and

I noticed the LBound and UBound functions. How would this work with a multidimensional array?

Finding bounds on a multi-dimensional array

Syntax

UBound(arrayname[, dimension])

The UBound function syntax has these parts:

Part Description

arrayname Required. Name of the arrayvariable; follows standard variable naming conventions.

dimension Optional; Variant (Long). Whole number indicating which dimension's upper bound is returned. Use 1 for the first dimension, 2 for the second, and so on. If dimension is omitted, 1 is assumed.

Sorted

Sorted

rubbish

rubbish

no

no

hi

hi