注意标签: VBA ,不是 VB6,不是 VB.NET。
这是特定于 MS Access 中的 VBA。我在一个我称之为“可枚举”的模块中构建了一组方法。它做了很多让人想起 .NET 中的 Enumerable 类和接口(interface)的事情。我想要实现的一件事是 ForEach 方法,类似于 .NET Enumerable.Select method .
我构建了一个使用 Application.Run 的版本方法为每个元素调用一个函数,但 Application.Run 仅适用于用户定义的方法。例如,以下工作:
' User-defined wrapper function:
Public Function MyReplace( _
Expression As String, Find As String, StrReplace As String, _
Optional Start As Long = 1, _
Optional Count As Long = 1, _
Optional Compare As VbCompareMethod = vbBinaryCompare)
MyReplace = Replace(Expression, Find, StrReplace, Start, Count, Compare)
End Function
' Using Application.Run to call a method by name
Public Sub RunTest()
Debug.Print Run("MyReplace", "Input", "In", "Out")
End Sub
RunTest 按预期打印“输出”。以下不起作用:
Debug.Print Run("Replace", "Input", "In", "Out")
它抛出运行时错误 430:“类不支持自动化或不支持预期的接口(interface)”。这是意料之中的,因为文档指出 Application.Run 仅适用于用户定义的方法。
VBA 确实有一个 AddressOf 运算符,但仅在将函数指针传递给外部 API 函数时才有效;使用 AddressOf 创建的函数指针在 VBA 中不可使用。同样,这在文档中有所说明(或参见例如 VBA - CallBacks = Few Cents Less Than A Dollar? )。
那么有没有其他方法来识别和调用使用变量的方法呢?或者我的回调尝试是否会通过 Application.Run 方法仅限于用户定义的函数?
最佳答案
一周内没有其他答案......为了解决问题,这是我能想到的最好的:
CallByName
,我构建了一个辅助模块,将 ParamArray 解析为单个参数。 .如果您将 ParamArray 传递给 CallByName
它将所有参数混合成一个实际的 Array
并将其传递给您尝试调用的方法中的第一个参数。 ForEach
方法:调用 Application.Run
的方法, 另一个调用 CallByName
.如问题所述,Application.Run
仅适用于用户定义的全局(公共(public)模块)方法。反过来,CallByName
仅适用于实例方法,并且需要对象参数。 这仍然让我无法通过名称直接调用内置的全局方法(例如
Trim()
)。我的解决方法是构建只调用内置全局方法的用户定义的包装器方法,例如:Public Function FLeft( _
str As String, _
Length As Long) As String
FLeft = Left(str, Length)
End Function
Public Function FLTrim( _
str As String) As String
FLTrim = LTrim(str)
End Function
Public Function FRight( _
str As String, _
Length As Long) As String
FRight = Right(str, Length)
End Function
...etc...
我现在可以使用这些来执行以下操作:
' Trim all the strings in an array of strings
trimmedArray = ForEachRun(rawArray, "FTrim")
' Use RegExp to replace stuff in all the elements of an array
' --> Remove periods that aren't between numbers
Dim rx As New RegExp
rx.Pattern = "(^|\D)\.(\D|$)"
rx.Global = True
resultArray = ForEachCallByName(inputArray, rx, "Replace", VbMethod, "$1 $2")
关于vba - VBA 中的自定义回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9020481/