【问题标题】:VBA - UDF handles Arrays differentlyVBA - UDF 以不同方式处理数组
【发布时间】:2012-04-23 18:30:31
【问题描述】:

此代码是我正在处理的代码的一小部分。我已将问题缩小到以下部分。我有这个 UDF SampleFunction,我需要将一个数组 {3;4} 作为唯一参数传递给它。

Function SampleFunction(InputVar As Variant) As Integer
    SampleFunction = InputVar(LBound(InputVar))
End Function

我以两种不同的方式调用此 UDF。一、通过VBA

案例一:

Sub testSF()
    MsgBox SampleFunction(Array(3, 4))
End Sub

其次,通过我的excel工作表作为

案例2:

={SampleFunction(ROW(3:4))} -> 即作为数组函数。

问题:

UDF 适用于案例 1,即通过 VBA 调用,当我通过 excel 工作表调用它时,它会为案例 2 提供 #VALUE 错误。

我在案例 2 中使用 F8 逐步完成该函数。Lbound(InputVar) 的计算结果为 1(这与案例 1 中从 sub 调用不同,它的计算结果为 0),但 InputVar(Lbound(InputVar)) 显示“下标超出案例 2 中的“范围”错误。

我只想知道如何从工作表中调用 SampleFunction 函数,即案例 2,使其具有与上面显示的案例 1 相同的行为。作为奖励,如果有人能解释为什么 Lbound(InputVar) 在上述情况下的评估不同,那就太好了。

其他一些细节:

我正在构建一个 UDF 来执行一些正则表达式操作。上面的参数 InputVar 将是一个数组 {x;y;z;...} 指定第 x、y、z ... 次出现。 InputVar 的数据类型保留为 Variant,因为我希望能够将数字(作为单长度数组)、数组或范围(获取并转换为数组)传递给函数。

提前致谢!!

【问题讨论】:

    标签: arrays excel excel-formula excel-2003 vba


    【解决方案1】:

    我相信你有两个问题。首先,如果您在非数组公式中使用SampleFunction,我认为您的代码不会评估,即,如果 InputVar 是一个范围。您需要结合一些方法来处理可以传递到变体中的不同类型的输入。其次,您的代码假定 InputVar 是一维数组。这将导致任何多维数组出错。这是'Subscript out of range.' 错误的根源,因为数组函数将所有数组参数作为二维数组传递,即使它们可以表示为一维。

    我建议在您的函数中声明一个新的动态数组,然后将其设置为等于 InputVar。在过去,我已经为数组和非数组公式做了这项工作,如下所示。另外,请注意从数组中检索第一项的方式发生了变化。

    Option Explicit
    Function SampleFunc(InputVar As Variant) As Integer
    
    Dim tmpArray() As Variant
    
    On Error GoTo ErrHandler
    tmpArray = InputVar
    
    'Added extra argument to LBound since dynamic arrays have two dimensions by default.
    SampleFunc = tmpArray(LBound(tmpArray, 1), LBound(tmpArray, 2))
    Exit Function
    
    ErrHandler:
    'Handles the case where InputVar is a Range.
    tmpArray = InputVar.Value
    Resume Next
    
    End Function
    

    这又快又脏,尤其是。错误处理,但希望基本思想是有帮助的。

    【讨论】:

    • 回想起来,我认为您可以将 LBound() 呼叫全部放在一起并改用它:SampleFunc = tmpArray(1, 1)
    • 谢谢。这非常有帮助。永远不会想到差异在于尺寸:)。此外,我已经使用IsObject 和 `TypeOf InputVar is Excel.Range' 明确处理了 InputVar 的 Range 可能性,因此该位似乎正在工作(现在:))。再次感谢!
    • 完美。这比我上面的错误处理程序要好得多。我很高兴这有帮助!
    • @Excelll:LBound 更好,因为它也适用于基于 0 的数组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    • 2018-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-08
    • 2020-07-28
    相关资源
    最近更新 更多