在 Microsoft Access 中,我有一个加载项 (*.accda) 函数,我想从 VBA 调用它,就像我从“数据库工具”->“加载项”菜单中单击该项目一样。
在注册表中,有一个键列出了库路径和表达式,但我还没有找到将调用它的能力暴露给 VBA 的地方。
我最接近的是添加对库的引用,然后立即删除引用。这将加载 VBE 项目并允许我调用该函数而无需添加对项目的持久引用。
With References
.AddFromFile Environ$("AppData") & "\Microsoft\AddIns\Version Control.accda"
.Remove references("MSAccessVCS")
End With
Run "MSAccessVCS.AddInMenuItemLaunch"
Run Code Online (Sandbox Code Playgroud)
问题是,如果我关闭CurrentDB,则不再加载库。另一方面,如果我通过加载项菜单调用加载项,即使当前数据库关闭,它也会保留。
由于加载项需要执行包括关闭当前数据库在内的功能,因此它仅在我通过菜单启动加载项时才有效。
有没有人找到可以像单击加载项菜单中的链接一样启动加载项的系统命令、WizHook参考、API 调用或其他函数?此处的最终目标是创建一个自动化的 DevOps 流程,在该流程中,数据库无需任何用户干预(即单击菜单)即可打开并调用插件功能。
非常感谢 Victor K 为我指明了正确的方向!事实证明,您实际上可以在函数中包含文件路径Application.Run以在应用程序级别加载加载项,这就是从菜单命令启动加载项时发生的情况。
语法类似于在 Microsoft Excel 中加载加载项的方式,但到目前为止我还没有弄清楚如何成功地将过程名称添加到文件路径以在一次调用中调用加载项函数。相反,我采用两步方法,第一个调用加载库,第二个调用运行我的加载项函数。我已经在我的 VBA 代码中实现了这个功能。
希望没有人在他们的加载项函数中实际使用 30 个命名参数,:-) 但我继续在第二个示例中添加了所有这些参数以完全反映Application.Run.
' Example of calling an add-in function.
Public Sub ShowVersionControl()
RunAddin Environ$("AppData") & "\Microsoft\AddIns\Version Control.accda", "MSAccessVCS.AddInMenuItemLaunch"
End Sub
' Simple function to demonstrate concept:
Public Sub RunAddin(strPath As String, strFunction As String)
' The following lines will load the add-in at the application level,
' but will not actually call the function. Ignore the error of function not found.
On Error Resume Next
Application.Run strPath & "!DummyFunction"
Application.Run strFunction
End Sub
' More robust function with full parameter support for .Run()
Public Sub RunAddin2(strPath As String, strFunction As String, _
Optional Arg1, Optional Arg2, Optional Arg3, Optional Arg4, Optional Arg5, _
Optional Arg6, Optional Arg7, Optional Arg8, Optional Arg9, Optional Arg10, _
Optional Arg11, Optional Arg12, Optional Arg13, Optional Arg14, Optional Arg15, _
Optional Arg16, Optional Arg17, Optional Arg18, Optional Arg19, Optional Arg20, _
Optional Arg21, Optional Arg22, Optional Arg23, Optional Arg24, Optional Arg25, _
Optional Arg26, Optional Arg27, Optional Arg28, Optional Arg29, Optional Arg30)
Dim lngError As Long
' Trap and ignore expected error.
On Error Resume Next
' The following lines will load the add-in at the application level,
' but will not actually call the function. Ignore the error of function not found.
Application.Run strPath & "!DummyFunction"
' Check returned error just in case it was something else.
lngError = Err.Number
If Err Then Err.Clear
On Error GoTo 0
If lngError <> 2517 Then Err.Raise lngError
' Now that the library is loaded, we can call the function.
Application.Run strFunction, _
Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10, _
Arg11, Arg12, Arg13, Arg14, Arg15, Arg16, Arg17, Arg18, Arg19, Arg20, _
Arg21, Arg22, Arg23, Arg24, Arg25, Arg26, Arg27, Arg28, Arg29, Arg30
End Sub
Run Code Online (Sandbox Code Playgroud)
现在,我可以成功调用加载项中的函数,使其在应用程序级别加载。这允许加载项关闭当前数据库并在完全自动化的过程中从源代码重建它。
注意:使用此方法时,您可能需要添加受信任的位置,以允许加载项在没有安全警告的情况下运行。
为了加载加载项或包含宏的文件,您可以使用 Application.Run文件的完整路径,如下所示:
在加载项中创建一个空子程序,例如:
Public Sub Ping()
End Sub
Run Code Online (Sandbox Code Playgroud)
从需要加载加载项的项目中调用此子例程:
Application.Run "'X:\ExamplePath\Addins\MyAddIn.accda'!Ping"
Run Code Online (Sandbox Code Playgroud)
事实上,您通常可以使用它立即调用您想要的任何子程序:
Application.Run "'X:\ExamplePath\AddIns\MyAddIn.accda'!SubIWnatToRunInTheAddIn"
Run Code Online (Sandbox Code Playgroud)
您还可以以类似于后期绑定的方式使用此方法(此外,您还可以传递参数):
在加载项中:
Public Function NewAddInClass() as AddInClass
Set NewAddInClass = New AddInClass
End Function
Run Code Online (Sandbox Code Playgroud)
在调用代码中:
Public Sub CallAddInClass()
Dim TestClass as Object
Set TestClass = Applcation.Run ("'X:\AddinPath\MyAddIn.accda'!NewAddInClass")
TestClass.ExampleMethod
End Sub
Run Code Online (Sandbox Code Playgroud)
我没有工作,尽可能多使用Access,但现在看来,Access有CurrentProject对象,您可以或许,可以让您使用类似的方式参考返回从加载项AllMacros,AllModules等等。