Application.run 不适用于模块

Posted

技术标签:

【中文标题】Application.run 不适用于模块【英文标题】:Application.run doesn't work with module 【发布时间】:2014-02-13 14:54:03 【问题描述】:

我有两个模块。在一个模块中,我想间接地从另一个模块运行一个子模块。根据 MS 和大量在线资源的说法,这应该可以工作 - 但事实并非如此。可能是什么问题?

'Module: "Helpers"

Public Sub ubTest()
  MsgBox "ubTest is called"
End Sub


'Another Module -> I also tried this from a form and a class...

Public Sub test()
  Dim s As String
  Helpers.ubTest             'works

  s = "ubTest"
  Application.Run s        'works

  s = "Helpers.ubTest"
  Application.Run s        'doesn't work

End Sub

(显然这是一个测试 - 在实际应用程序中,我将拥有多个模块,并且不会始终控制过程名称 - 所以我必须使用模块前缀)

我尝试 /decompile 和压缩数据库 - 也没有运气。

【问题讨论】:

可能是拼写错误? s = "Helpers.ubTest" 在你的问题中你有s = "Helpes.ubTest" 抱歉拼错了。不,不是那样工作的——但我还没有找到合适的解决方案。正是我对 HansUp 的回答 【参考方案1】:

Access Application.Run Method 帮助主题对 Name 参数进行了说明:

'如果您正在调用另一个数据库中的过程,请使用项目名称和过程名称以点分隔,格式为:“projectname.procedurename”。'

所以我认为当您提供"modulename.procedurename"(即“Helpers.ubTest”)时,Access 认为您的模块名 是VBA 项目的名称。由于找不到名为 Helpers 的项目,因此会抛出错误 #2517," ... 找不到过程 'Helpers.ubTest.'"

很遗憾,我找不到使用Application.Run 做我认为你想做的事情的方法。我希望"projectname.modulename.procedurename" 可以工作,但这也触发了 2517 错误。

【讨论】:

谢谢 HansUp。我花了一个多小时寻找错误。显然,MSDN 上有不同的帮助页面,一个单独用于办公室(您可以在路径中找到“单词”)和一个单独的用于访问的帮助页面。访问页面没有说明模块参数。 (尽管您在网络上找到了一些声称存在的访问资源)。我将在每个名为 Helpers_CallbackRunner 的模块中使用一个调用方法,然后我可以使用 `Application.run modulename & "CallbackRunner", SubName 调用它【参考方案2】:

@HansUp 和@Johannes 的答案(虽然我不太了解他的解决方案)(以及大量的反复试验)使我了解了这些知识:

Access 中的Application.Run 不会尝试将过程名称的第一部分(点之前)用作模块名称,仅用作项目名称 因此,最重要的一课,如果要通过Application.Run调用模块的特定函数名,该函数必须在整个项目中唯一命名。

请参阅 Microsoft 文档:

Application.Run in Access Application.Run in Excel Application.Run in Word

例如,两个具有相同函数DoSomething 的模块在通过Application.Run 调用时总是会抛出错误2517:此时Access 找不到正确的函数。 为此,您必须重命名(其中一个)或创建一个具有全局唯一名称的包装函数。

所以:

' Module1
Public Function GetName() As String

' Module2
Public Function GetName() As String

应改为例如:

' Module1
Public Function Module1_GetName() As String

' Module2
Public Function Module2_GetName() As String

或者,为通过 Application.Run 的调用添加一个包装器:

' Module1
Public Function GetName() As String
    GetName = "Module1"
End Function

Public Function Module1_GetName() As String
    Module1_GetName = GetName()
End Function

为了测试我获得的知识,我围绕 Application.Run 调用创建了一个包装函数,当出现错误 2517 时,它将用下划线替换过程名称中的点并重新运行,因此模块中的包装函数将自动叫。 这使代码或多或少与 Excel Application.Run 兼容。 如果你然后在你的模块中创建包装函数,就像我的第二个例子你的'好去'。

Private Function RunApplicationFunction(Name As String, Value As Variant) As Variant
    On Error GoTo TryUniqueName
    
    Set RunApplicationFunction = Application.Run(Name, Value)
    Exit Function
    
    ' In MS Access we catch Error 2517 and try to call the function with the application/module name prefixed to it
    ' So WebHelpers.ParseXML becomes WebHelpers_ParseXML
TryUniqueName:
    If Err.Number = 2517 And Application.Name = "Microsoft Access" And InStr(Name, ".") > 0 Then
        Set RunApplicationFunction = Application.Run(Replace(Name, ".", "_"), Value)
    Else
        Err.Raise Err.Number
    End If
End Function

【讨论】:

以上是关于Application.run 不适用于模块的主要内容,如果未能解决你的问题,请参考以下文章

收缩资源不适用于库模块

Nodejs 加密模块不适用于打字稿

Angular <custom-component> 不适用于延迟加载的模块

Application.Run 用于宏返回数组

AspectJ AOP LTW 不适用于 javaagent 的动态加载

slowcheetah 不适用于 app.config