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 不适用于模块的主要内容,如果未能解决你的问题,请参考以下文章
Angular <custom-component> 不适用于延迟加载的模块