[AccessD] Passing ParamArrays down the line

Kenneth Ismert kismert at gmail.com
Tue Sep 6 16:52:13 CDT 2011


John:

It's true: you can't pass a ParamArray to a routine expecting a Variant() or
Variant parameter. You have to convert to a Variant array first.

You can pass ParamArrays to other routines accepting a ParamArray. But, the
initial ParamArray gets nested in element(0) in the ParamArray of the called
routine, making the values hard to extract.

This routine takes any ParamArray with any level of nesting, and returns the
actual values as a plain variant array:

' UnpackParamArray
'
' Unpacks the given ParamArray, and returns it as a Variant array
' * Handles nested ParamArray calls
' * Handles an array passed to a ParamArray
'
' Allows several parameter passing styles:
' 1. ParamArray from another routine    -- lowest-level nested array
' 2. Variant Array as only parameter    -- "  "
' 3. List of values                        -- returns array containing
values given
'                                          (works, but use Array() instead)
' ParamArray Nesting
' * Every time you pass a ParamArray to another routine, it gets nested as
'   element 0 in the new ParamArray:
'
'   Nest Level  Array Structure
'
---------------------------------------------------------------------------
'   1           Array(N)
'   2           Array(0) -> Array(N)
'   3           Array(0) -> Array(0) -> Array(N)
'   4           Array(0) -> Array(0) -> Array(0) -> Array(N)
'
' * This function unwraps the nested Array(0) pointers until the base array
is found.
' * When you pass a standard array to a ParamArray, you start at nest level
2.
'
' Notes:
' * ParamArrays can only be passed to other Routines as ParamArrays
' * Passing ParamArray() to Variant() or Variant will result in an
'   'Invalid Use Of ParamArray' compile error.
' * If an object with a default property is passed, the property is used
instead of the object
'
Public Function UnpackParamArray(ParamArray vParameters() As Variant) As
Variant()

    Dim vOut() As Variant
    Dim vTemp() As Variant
    Dim lUBound As Long

    On Error GoTo HandleErr

    ' empty array: LBound=0; UBound=-1
    UnpackParamArray = VBA.Array()

    vOut() = vParameters()
    lUBound = UBound(vOut)

    ' If UBound > 0, some regular array has been found, so skip this loop
    Do While (lUBound = 0)

        If IsArray(vOut(0)) Then
            ' Swap carefully to avoid fatal error
            vTemp() = vOut(0)
            Erase vOut()
            vOut() = vTemp()
            Erase vTemp()
            ' test the bounds of the new array
            lUBound = UBound(vOut)

        Else
            ' scalar or object value: return array holding it
            lUBound = 1

        End If

    Loop

    If lUBound >= 0 Then
        ' Return
        UnpackParamArray = vOut()
    End If

    Exit Function

HandleErr:
    Err.Raise Err.Number, "UnpackParamArray" & VbCrLf & Err.Source,
Err.Description
End Function


jwcolby:
> I use param arrays to allow me to pass in things like group ids that a user
> might belong to.  The following fails:
>
> Function mPLSUserInGroup(ParamArray Grps() As Variant) As Boolean
>    mPLSUserInGroup = cPLS.cCurrUser.pUserInGrp(**Grps)
> End Function
>
> However the following works:
>
> Function mPLSUserInGroup(ParamArray Grps() As Variant) As Boolean
> Dim lGrps() As Variant
>    lGrps = Grps
>    mPLSUserInGroup = cPLS.cCurrUser.pUserInGrp(**lGrps)
> End Function
>
> Thus in order to push a paramarray into another function we just need to
> dim an array, set it equal to the paramarray and then push that array on
> down.
>
> Pretty strange that a ParamArray cannot be directly passed along.
>



More information about the AccessD mailing list