3

给定一个未知大小的数组和一个接受参数数组的过程,如何在不修改过程的情况下将该数组作为参数数组传递?

Sub Example(sequence() As String)
    UnModifiableSub sequence
End Sub

Sub UnModifiableSub(ParamArray bar())
    ' bar(0) = sequence not bar = sequence
End Sub

我正在寻找类似于 Python 解包的行为

def foo(*args):  # identical to ParamArray
    print(args)

x = [1,2,3,4]
foo(*x)  # what VBA can't do

我知道没有像 Python 那样的内置解决方案,但是除了长的 switch 语句之外,任何残忍的实现都是可以接受的。

4

2 回答 2

2

巨大的 switch 语句对我来说听起来有点残忍,但如果你必须调用的例程真的不可修改,那就是你要做的。在 VBA 中,这是一个Select Case声明。并且不要忘记 VBA 数组可以具有任意索引,因此您必须同时测试两者LBoundUBound除非您确定您的序列参数来自何处。

如果您可以编写自己的例程,则有一种方法可以大部分时间做您想做的事情。您可以将数组分配给 type 的变量Variant,如下所示:

Sub tryThis(v)
    Debug.Assert IsArray(v)
    Debug.Print v(LBound(v))
End Sub

Sub Example(sequence() As String)
    tryThis sequence
End Sub

Sub test()
    Dim s() As String

    ReDim s(1 To 2)
    s(1) = "a"
    s(2) = "b"

    Call Example(s)
End Sub

tryThis()代替你的UnModifiableSub. 如果您test()在立即窗口中运行,您会得到以下输出:

call test
a

我认为这就是你想要的行为。(有点,无论如何。没有人想要任意的数组索引。)当然,与 Python 相比,这是有限的。值得注意的是,如果您想调用tryThis(),您必须自己将“参数”放入一个数组中。此答案和父问题中讨论了与这样做相关的一些权衡:

使用 ParamArray(与 Variant 数组相比)有什么好处?

还有一些其他的问题。例如,您不能只将 a 的内容传递ParamArraytryThis()

'Doesn't work...
Sub gotcha(ParamArray pa())

    'Can't do it this way! "Invalid ParamArray use"
    Call tryThis(pa)
End Sub

您必须明确地转移到变量:

Sub gotchaFixed(ParamArray pa())
    Dim v
    v = pa

    Call tryThis(v)
End Sub

Sub test2()
    Call gotchaFixed("a", "b")
End Sub

...

call test2
a
于 2014-09-20T00:35:12.410 回答
1

我不相信可以将参数作为传递,就其性质而言ParamArray,您不是分配ParamArray自身,而是映射到.ParamArray

调用者传递的每个参数都映射到 ParamArray 变量中的一个元素。因此,ParamArray 变量将具有与调用语句传递的参数一样多的元素。

http://www.tushar-mehta.com/publish_train/xl_vba_cases/1005%20ParamArray.shtml

于 2014-09-19T15:14:20.263 回答