【问题标题】:pass undefined number of arguments to a VBA function [duplicate]将未定义数量的参数传递给VBA函数[重复]
【发布时间】:2022-05-12 17:15:42
【问题描述】:

我需要从 VBA 调用一个 excel 函数,并在函数的 and 处调用。

我不知道我有多少可变参数(var1 到...)。

有没有办法转换数组,并将其作为参数应用...? :

Application.Run("MyFunct", fixParam1, fixParam2, var1, var2 ... varx)

我虽然最终在 python 中有类似 kwargs 的东西...

Application.run("myFunct", fixParam1, fixParam2, kwargs(myArray))

也许是 paramarray 的东西?

mySub( fixParam1, fixParam2, ParamArray var() as Variant)
    Application.run([here I'm not sure...??])

【问题讨论】:

  • 由于您无法更改 myFunct(正如您在 cmets 中所说),请给我们定义的 myFunct 参数列表。如果你不能改变它,那么你必须匹配它。
  • myFunct 是用两个固定参数定义的,然后是 1 到 N 个可选参数......这就是我试图解决的困难。所以我会用 fix1 fix2 var1 调用一次,然后用 fix1,fix2,var1,var2,var3

标签: vba function excel


【解决方案1】:

定义一个以数组为参数的函数,如下所示:

Function testFunction(args())

然后你可以将一个数组传递给Function:

testFunction myArray

【讨论】:

    【解决方案2】:

    如果您可以更改myFunct 来处理它,您可以传递一个数组。 http://www.cpearson.com/excel/passingandreturningarrays.htm

    Application.run("myFunct", fixParam1, fixParam2, myArray)
    

    所以我推断myFunct 接受这样的参数:fixParam1, fixParam2, [var1], [var2], ... 括号表示可选参数。所以你可能有许多可选参数。

    选项 1 所以创建一个包含所有参数的数组并像这样调用它:

    Application.Run("MyFunct", fixParam1, fixParam2, myArray(0), myArray(1), _
        myArray(2), myArray(3), myArray(4), myArray(5))
    

    希望被调用的函数可以处理空白输入。

    选项 2 如果myFunct 无法处理额外的参数,您可能需要执行以下操作:

    Select Case argCount
        Case 1
            Call Application.Run("MyFunct", fixParam1, fixParam2, myArray(0))
        Case 2
            Call Application.Run("MyFunct", fixParam1, fixParam2, myArray(0), myArray(1))
        Case 3
            Call Application.Run("MyFunct", fixParam1, fixParam2, myArray(0), myArray(1), myArray(2))
        Case 4
            Call Application.Run("MyFunct", fixParam1, fixParam2, myArray(0), myArray(1), myArray(2), myArray(3))
    End Select
    

    不漂亮但有效。

    【讨论】:

    • 其实我没解释清楚,“myFunct”是给定的Function,我改不了……你的意思是被调用的函数,会自动把数组理解为新参数?在那种情况下,不可能将数组作为参数传递......似乎很奇怪
    • 参数只是数据。因此,如果您需要传递未知数量的值,请使用数组。
    • 由于 myFunct 不可更改,因此您需要匹配它。您不能传递比指定更多或更少的参数。一些参数可能是可选的,因此具有一定的灵活性。
    • 您尝试做的事情在 VBA 中是不可能的。您必须让代码计算参数并准确传递正确数量的参数。
    • givenFunction,被定义为有2个固定参数,然后是1到n...所以我需要一种方法来传递,也许所有参数都作为一个数组,例如:数组=(1,2,3) Application.run("givenFunct",array) array=(1,2,3,4) Application.run("givenFunct",array) 这样的事情可能吗?
    【解决方案3】:

    所以很简单。试试这个函数和子来测试:

    Function OneLine(ByVal f As Variant, ParamArray V() As Variant) As Variant
        Dim i As Long, ValToReturn As Variant
        For i = 0 To UBound(V, 1)
            V(i) = f
            If IsNumeric(V(i)) Then ValToReturn = ValToReturn + V(I)
        Next I
        OneLine = ValToReturn
    End Function
    
    Sub TestOnLineFunction()
        Dim X, a, b, c, d, e, f, g, h, i, j, k, TMP
        Dim Y(1 To 7, 8 To 12)
    
        x = 125
        Y(5, 10) = "Anything you want"
        Call OneLine(X, a, b, c, d, e)
        MsgBox d ' will show 125
        Call OneLine(Y, a, b, c, d, e, f, g, h, i, j, k)
        MsgBox h(5, 10) ' will show string:"Anything you want"
        'if You want to use Application.Run, do the same, but in this
        'case will not take V variables ByRef because Run method is always taking ByVal
        'So Sub do what is it doing but Function should return something in this case
        X = 888
        TMP = Application.Run("OneLine", X, a, b, c, d, e, f, g, h, i)
        MsgBox TMP
    End Sub
    

    函数OneLine 将设置F 变量后所有传递的值等于F 变量。 这个 F 变量可以是任何值,甚至可以是多维数组。您可以在 F 之后传递任意数量的可用变量,但始终作为 Variant 类型。 V 将始终通过ByRef。如您所见,OneLine 函数无法返回任何内容,因此您需要 Call 它,它将更改此 ParamArray V 中的所有变量。 如果你想使用 Application.Run 方法做同样的事情,但是这样函数应该返回一些东西,因为这个 Run 方法总是使用变量 ByVal。因此,如您所见,在这种情况下使用 Run 方法是没有意义的。如果您运行 Subroutine,行为将是相同的。 Sub 会做它正在做的事情,它会接受尽可能多的变量,但你应该记住 Application.Run 有 30 个变量的限制。

    【讨论】:

    • 如果调用者在编译时不知道参数的数量,这对调用ParamArray 函数有何帮助?在这里,您在调用方对 5 和 11 个参数进行了硬编码。
    • ParamArray 可以采用任意数量的参数。我没有硬编码 5 个参数,这只是我编写的如何使用 OneLine 函数的示例。如果你传递 5 个参数是可以的,但如果你传递 55 或 255 个参数也可以。
    • 您有 5 个参数硬编码在 Call OneLine(X, a, b, c, d, e)。原始问题的重点是调用OneLine,以使您在编译时不知道TestOnLineFunction 中的参数数量。将您的Sub TestOnLineFunction() 设置为Sub TestOnLineFunction(ByVal NumberOfParameters As Long),然后像Call TestOnLineFunction(5) or TestOnLineFunction(11) 一样从外部调用它,这样它又会使用在NumberOfParameters 中接收到的传递参数数量调用OneLine。
    • 就您不能将任何对象(仅变量值)传递给 Application.Run 而言,这是不可能的。在这种情况下,根据参数的数量将代码转换为调用 Run 方法的函数将是最佳选择。
    • 您可以将任何对象传递给Application.Run。 “对象”和“变量”之间没有区别。所有这些都与使用未知数量的参数调用无关 - 请参阅上面的副本了解如何做到这一点。
    猜你喜欢
    • 2016-06-14
    • 2015-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 2019-04-02
    • 2018-08-28
    相关资源
    最近更新 更多