Application.run不适用于模块

时间:2014-02-13 14:54:03

标签: vba ms-access access-vba ms-access-2010

我有两个模块。在一个模块中,我想间接地从另一个模块运行一个子模块。根据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

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

我尝试/反编译并压缩数据库 - 也没有运气。

2 个答案:

答案 0 :(得分:2)

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

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

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

不幸的是,我找不到用Application.Run做我认为你想要的方法。我希望"projectname.modulename.procedurename"可以工作,但这也引发了2517错误。

答案 1 :(得分:0)

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

  • Access 中的 Application.Run 不会尝试将过程名称的第一部分(点之前)用作模块名称,而仅用作项目名称
  • 因此,最重要的一课,如果您想通过 var connected = false lateinit var result: Boolean var analysis1 = true var analysis2 = true override fun analyze() { if (!connected) { result = connectToDevice() // needs to be async connected = true } // need positive result to proceed, otherwise start over if (!result) { connected = false return } if (analysis1) { // perform analysis #1... analysis1 = false // when an analysis is done, exit early and perform next analysis on next frame return } if (analysis2) { // perform analysis #2... analysis2 = false // same as above return } // when all analyses are done, reset all flags to start over connected = false analysis1 = true analysis2 = true } 调用模块的特定函数名称,则该函数必须在整个项目中唯一命名。

请参阅 Microsoft 文档:

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

所以:

Application.Run

应该改为例如:

' 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 调用创建了一个包装函数,当出现错误 2517 时,它将用下划线替换过程名称中的点并重新运行,因此模块中的包装函数将被自动调用。 这使得代码或多或少与 Excel Application.Run 兼容。 如果您随后在您的模块中创建包装函数,就像我的第二个示例一样,您的“好去处”。

Application.Run