[更新:问题已经形成,以便可以将功能直接复制到VBA模块并通过运行test_callback_loop_function_works_with_multiple_parameters
方法进行测试]
我正在使用Application.Run
函数动态调用我的VBA中的方法。我的想法是,这个助手将节省我在VBA中的各种函数/子函数中循环遍历字典。相反,我可以调用以下帮助器来为我做循环:
Public Function user_func_dictionary_loop(Dictionary As Dictionary, _
MethodCallback As String, _
Optional Params As Variant) As Boolean
Dim Key As Variant
For Each Key In Dictionary
If IsMissing(Params) Then
Application.Run MethodCallback, Dictionary(Key)
Else
Application.Run MethodCallback, user_param_replace(Dictionary(Key), Params)
End If
Next Key
End Function
如果没有为函数提供参数,那么它只使用Dictionary的键值运行MethodCallback
。如果有参数,则在下面触发另一个步骤:
Private Function user_param_replace(Item As Variant, Optional Params As Variant) As Variant
Dim i As Long
Dim strTest As String
Dim Output As Variant
Output = replace_dictionary_values(Item, Params)
If IsArray(Output) Then
ReDim Preserve Output(0 To UBound(Output))
user_param_replace = Join(Output, ",")
Exit Function
End If
user_param_replace = Output
End Function
Private Function replace_dictionary_values(Item As Variant, Optional Params As Variant) As Variant
Dim l As Long
Dim varTemp() As Variant
Dim Param_Item As Variant
l = 0
If IsMissing(Params) Or Not IsArray(Params) Then
replace_dictionary_values = Replace$(Params, "{D:Value}", Item)
Exit Function
Else
ReDim varTemp(0 To UBound(Params))
For Each Param_Item In Params
varTemp(l) = Replace$(Param_Item, "{D:Value}", Item)
l = l + 1
Next Param_Item
End If
replace_dictionary_values = varTemp
End Function
上述步骤允许用户传入包含{D:Value}
的参数,然后将其替换为Dictionary的键值。
我在下面做了一个小单元测试,认为它应该测试我的方法的功能。目前我得到的是“Argument not optional”错误:
Function test_callback_loop_function_works_with_multiple_parameters() As Boolean
Dim dictTest As New Dictionary
dictTest.Add 1, "1 - Foo"
dictTest.Add 2, "2 - Foo"
dictTest.Add 3, "3 - Foo"
Dim MyArray(0 To 1) As Variant
MyArray(0) = "{D:Value}"
MyArray(1) = "Bar"
user_func_dictionary_loop dictTest, "custom_debug_print_multiple_params", MyArray
test_callback_loop_function_works_with_multiple_parameters = True
End Function
Function custom_debug_print_multiple_params(strPrint As String, strPrint2 As String) As String
Debug.Print strPrint & strPrint2
End Function
输出应为:
1 - FooBar
2 - FooBar
3 - FooBar
但我得到了
运行时错误'449' - 参数不是可选的
Application.Run MethodCallback, user_param_replace(Dictionary(Key), Params)
行上的错误。
我的预感是,因为我正在尝试将数组元素与“,”一起连接,然后作为参数(在Join(Output, ",")
行中)传递给方法,这会导致测试失败。 / p>
所以我的问题是,在VBA中,是否可以将数组的元素连接在一起,以便它们可以动态地传递给另一个方法/函数?
答案 0 :(得分:1)
这行代码存在问题。
replace_dictionary_values = Replace$(Params, "{D:Value}", Item)
当IsMissing(Params)= True时,调用此行,并且可预测地返回错误。
我还发现你的测试程序无法正常工作。
Function custom_debug_print_multiple_params(strPrint As String, strPrint2 As String) As String
Debug.Print strPrint & strPrint2
End Function
所有变量都是变体,但上述函数的两个参数是字符串类型。如果要传递字符串类型的变体,则应将参数声明为ByVal。我建议单独测试每个函数,并确保它在使用其返回值作为其他函数的参数之前有效。
我怀疑您的部分问题可能是由于您不加区别地使用变体造成的。例如,您在上面引用的错误行中调用的Replace
函数需要3个字符串作为参数。在您的代码中,Item
和Params
(如果存在)都是变体。您的计划很有可能实际工作,但是当某些事情不能正常工作时,就像这里的情况一样,所有那些被削减的角落都必须进行检查,从而增加了调试工作的时间。在编码期间保存。
在下面的第一个示例中,调用过程提供了被调用过程所需的两个字符串。传递字符串类型的变体,它们通过ByVal参数转换为字符串。
Function Test_TestPrint() As Boolean
Dim dictTest As New Scripting.Dictionary
Dim MyArray(0 To 1) As Variant
dictTest.Add 1, "1 - Foo"
dictTest.Add 2, "2 - Foo"
dictTest.Add 3, "3 - Foo"
MyArray(0) = "{D:Value}"
MyArray(1) = "Bar"
TestPrint MyArray(0), MyArray(1)
' user_func_dictionary_loop dictTest, "TestPrint", MyArray
Test_TestPrint = True
End Function
Sub TestPrint(ByVal strPrint As String, ByVal strPrint2 As String)
Debug.Print strPrint & strPrint2
End Sub
在下面的代码中,数组被传递给执行过程,该过程需要这样一个数组并打印出它的元素。
Function Test_TestPrint2() As Boolean
Dim dictTest As New Scripting.Dictionary
Dim MyArray(0 To 1) As Variant
dictTest.Add 1, "1 - Foo"
dictTest.Add 2, "2 - Foo"
dictTest.Add 3, "3 - Foo"
MyArray(0) = "{D:Value}"
MyArray(1) = "Bar"
Sub TestPrint2 MyArray
' user_func_dictionary_loop dictTest, "TestPrint", MyArray
Test_TestPrint2 = True
End Function