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