将动态参数传递给VBA中的Application.Run - 错误449参数不可选错误

时间:2017-11-24 09:25:23

标签: vba excel-vba excel

上下文:我试图通过VBA的Application.Run函数动态调用方法,并动态地将参数传递给方法。更多的概念证明而非实际用例。

代码:

Public Sub Test()
    Call MethodDynamically("MethodToBeCalled", "This doesnt, work")
End Sub

Public Sub MethodDynamically(MethodName As String, Params As String)
    Application.Run MethodName, Params
End Sub

Public Sub MethodToBeCalled(Param1 As String, Param2 As String)
    Debug.Print Param1 & " " & Param2
End Sub

错误:在Test方法的Run-time error '449': Argument not optional行上运行Application.Run方法,我会收到MethodDynamically

期望:我希望运行Test方法会触发MethodToBeCalledThis doesntwork作为参数传递。结果将是立即窗口中的This doesnt work

3 个答案:

答案 0 :(得分:1)

你有两个选择。

1分割字符串“这不,工作2个参数

Public Sub TestThis()
    Call MethodDynamically("MethodToBeCalled", "This doesnt", "work")
End Sub

Public Sub MethodDynamically(MethodName As String, Param1 As String, Param2     As String)
    Application.Run MethodName, Params
End Sub

Public Sub MethodToBeCalled(Param1 As String, Optional Param2 As String)
    Debug.Print Param1 & ", " & Param2
End Sub

或使用可选参数:

Public Sub TestThis()
    Call MethodDynamically("MethodToBeCalled", "This doesnt, work")
End Sub

Public Sub MethodDynamically(MethodName As String, Params As String)
    Application.Run MethodName, Params
End Sub

Public Sub MethodToBeCalled(Param1 As String, Optional Param2 As String)
    Debug.Print Param1 & ", " & Param2
End Sub

编辑: 试试这个。

Public Sub TestThis()
    Call MethodDynamically("MethodToBeCalled", "This doesnt, work")
End Sub

Public Sub MethodDynamically(MethodName As String, Optional params As String = "")
    If params = "" Then Application.Run MethodName
    Select Case selectParamNumbers(params)
        Case 0
        paramArr = paramSplit(params)
        Application.Run MethodName, paramArr(0)
        Case 1
        paramArr = paramSplit(params)
        Application.Run MethodName, paramArr(0), paramArr(1)
        Case 2
        paramArr = paramSplit(params)
        Application.Run MethodName, paramArr(0), paramArr(1), paramArr(2)
        'And so on...
   End Select
End Sub

Public Function paramSplit(param As String) As Variant
    paramSplit = Split(param, delimiter:=", ")
End Function

Public Function selectParamNumbers(param As String) As Long
    Dim paramAmount() As String
    paramAmount = Split(param, delimiter:=",")
    selectParamNumbers = UBound(paramAmount)
End Function

Public Sub MethodToBeCalled(Param1 As String, Optional Param2 As String)
    Debug.Print Param1 & " " & Param2
End Sub

答案 1 :(得分:1)

这个问题已经有了答案here,但值得考虑一个允许NPE调用具有任意数量参数的其他子例程的示例。

解决方案是使用MethodDynamically来处理未知数量的参数。例如:

ParamArray

输出:

Option Explicit

Public Sub Test()
    Call MethodDynamically("MethodToBeCalled1", "This", "works") '<-- 2 args
    Call MethodDynamically("MethodToBeCalled2", "This", "works", "too") '<-- 3 args
    Call MethodDynamically("MethodToBeCalled3", "This", "works", "too", "as well") '<-- 4 args
    Call MethodDynamically("MethodToBeCalled4", "Working", 10, 2, 35) '<-- 4 args; different types
End Sub

Public Sub MethodDynamically(MethodName As String, ParamArray Params() As Variant)
    Application.Run MethodName, Params
End Sub

Public Sub MethodToBeCalled1(Params As Variant)
    Debug.Print Params(0) & " " & Params(1)
End Sub

Public Sub MethodToBeCalled2(Params As Variant)
    Debug.Print Params(0) & " " & Params(1) & " " & Params(2)
End Sub

Public Sub MethodToBeCalled3(Params As Variant)
    Debug.Print Params(0) & " " & Params(1) & " " & Params(2) & " " & Params(3)
End Sub

Public Sub MethodToBeCalled4(Params As Variant)
    Debug.Print Params(0) & " " & CStr((Params(1) ^ Params(2)) + Params(3))
End Sub

答案 2 :(得分:0)

Public Sub Test()
    Call MethodDynamically("MethodToBeCalled", "This doesnt, work")
End Sub

Public Sub MethodDynamically(MethodName As String, Params As String, Optional Params2 As String)
    Application.Run MethodName, Params, Params2
End Sub

Public Sub MethodToBeCalled(Param1 As String, Param2 As String)
    Debug.Print Param1 & "  " & Param2
End Sub