gpt4 book ai didi

vba - VBA 中的自定义回调

转载 作者:行者123 更新时间:2023-12-03 22:38:55 25 4
gpt4 key购买 nike

注意标签: 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/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com