I am on Excel 2010.
When a VBA user-defined function, say make2DArray, outputs a variant representing a 2D-array, this 2D-array can be then used as an input to another VBA function, say someFunction. While calling the functions from within VBA code. It works fine.
However when doing the same, passing make2DArray output as argument to someFunction, from within the sheet (via a formula in a cell), then it seems to work only for 2D-array with **2 or more rows**. Generating 2D-array with 1 row would fail. It seems that the 1-row 2D-array is then transformed automatically into an equivalent 1D-array.
A small example :
Option Explicit
'returns last (top-most, right-most) element
Function someFunction(v As Variant) As Integer
On Error Resume Next
Debug.Print "Dim-1 size", UBound(v, 1) - LBound(v, 1) + 1
Debug.Print "Dim-2 size", UBound(v, 2) - LBound(v, 2) + 1
On Error GoTo 0
someFunction = v(UBound(v, 1), UBound(v, 2))
End Function
Function make2DArray(h As Integer, w As Integer) As Variant
Dim i As Integer, j As Integer
Dim v2d As Variant
ReDim v2d(1 To h, 1 To w)
For i = 1 To h
For j = 1 To w
v2d(i, j) = i * j
Next j
Next i
make2DArray = v2d
End Function
Sub test()
'also works when called from sheet
Debug.Print someFunction(make2DArray(2, 3)) 'returns 6
'doesn't work when called from sheet
Debug.Print someFunction(make2DArray(1, 3)) 'returns 3
End Sub
The test function will work fine from within VBA. Similarly =someFunction(make2DArray(2, 3)) or any =someFunction(make2DArray(i, j)) cell formula would work well for i>1, however =someFunction(make2DArray(1, 3)) or any =someFunction(make2DArray(1, j)) will only produce a #VALUE! result in the sheet.
My question : Is this behavior documented somewhere? Is there a way to avoid the "casting" from 2D-array to 1D-array for 1-row 2D-arrays?
=someFunction(make2DArray(2, 4))and it returns 8 which is the value at the ubound of both ranks.make2DArray(1,4)is passed back to Excel, Excel converts it to a 1D array, and then passes that 1D array to thesomeFunctionfunction. It is always a bad idea to use the Excel-modified result of a UDF as a parameter to a UDF. Instead passhandwtosomeFunctionitself, and havesomeFunctioninvokemake2DArray. (I.e. call it as=someFunction(1, 4).)