我在Excel 2010上。
当VBA用户定义函数(例如make2DArray)输出表示2D数组的变量时,此2D数组可用作另一个VBA函数的输入,比如someFunction。从VBA代码中调用函数时。它工作正常。
然而,当执行相同操作时,将make2DArray输出作为参数传递给someFunction,从工作表内(通过单元格中的公式),然后它似乎仅适用于具有** 2或更多行**的2D数组。生成具有1行的2D阵列将失败。看来,1行2D阵列会自动转换为等效的1D阵列。
一个小例子:
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
测试功能可以在VBA内正常工作。类似地= someFunction(make2DArray(2,3))或any = someFunction(make2DArray(i,j))单元格公式适用于i> 1,但是= someFunction(make2DArray(1,3))或any = someFunction(make2DArray) (1,j))只会产生一个#VALUE!导致表格。
我的问题:这种行为是否记录在某处?有没有办法避免"铸造"从2D阵列到1D 2D阵列的1D阵列?
答案 0 :(得分:1)
来自我的评论:
我以前从未见过。它就像使用转置将2-D(一行)数组转换为1-D数组。我认为这是一个错误,因为VBA开销正在考虑一个带有一行'行的二维变体数组。 (例如,1作为无限制的第一等级)并将其转换为具有原始未结合第二等级的1-D数组作为唯一1-D等级的无效。对于普遍性,我能提出的唯一建议是错误控制;我将在下面发布一条建议。 子>
这是一些错误控制,可以克服流氓2-D到1-D阵列的转换。
'returns bottom-right element of 2D-array
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
'Debug.Print IsArray(v)
'Debug.Print UBound(v, 1) & ":" & UBound(v, 2)
On Error GoTo err_1D_array
someFunction = v(UBound(v, 1), UBound(v, 2))
Exit Function
err_1D_array:
someFunction = v(UBound(v))
End Function
答案 1 :(得分:1)
UDF应该真正复制参数是一个范围,一个矢量,一个数组,一个标量常量,或一些其他函数的数组/矢量输出。
SomeFunction({1,2,3})获得一维向量数组
SomeFunction({1; 2; 3})得到一个二维数组
SomeFunction(Range as variant)得到一个变量包含一个范围对象,其Value2属性始终返回标量或2D数组。