从工作表

时间:2017-12-08 01:34:41

标签: excel excel-vba vba

我在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阵列?

2 个答案:

答案 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数组。

相关问题