Library for calling methods in VBA modules with several key benefits:
- Host agnostic (unlike
Application.Run
) - Works with standard .bas Modules (unlike
CallByName
that calls classes) - Uses the standard
dot.Notation()
to call methods (unlikeAddressOf
which uses pointers invoked byDispCallFunc
) - Can call public or private methods
Under the hood it uses the same technique as Rubberduck's test execution engine to access the addresses of the public and private methods, ported from C# to VBA to twinBASIC (thanks RD team & Wayne for all the help). That foundation is then supplemented with a new technique to make calling them from VBA or tB much more natural (with dot notation). Click on the code review shield at top of post for more detailed code/technique walkthrough (written before tB port, but the concepts are the same)
Compile an ActiveX Dll from the vbInvoke.twinproj
, or use the precompiled vbInvoke_win[32/64].dll
(all found in the latest release Assets - whichever matches your VBA bitness). The library can be called by adding a reference or by using a declare statement. There are 2 methods GetStandardModuleAccessor
and GetExtendedModuleAccessor
:
Function GetStandardModuleAccessor(ByVal moduleName As String, ByVal proj As VBProject) As Object
Function GetExtendedModuleAccessor(ByVal moduleName As String, ByVal proj As VBProject, Optional ByRef outPrivateTI As vbInvoke.[_ITypeInfo]) As Object
or
Declare PtrSafe Function GetStandardModuleAccessor Lib "vbInvoke_win64" (ByVal moduleName As Variant, ByVal proj As VBProject) As Object
Declare PtrSafe Function GetExtendedModuleAccessor Lib "vbInvoke_win64" (ByVal moduleName As Variant, ByVal proj As VBProject, ByRef outPrivateTI As IUnknown) As Object
Note: The standard DLL version uses Variant
for the module name and has no optional arguments. The Library name in the object browser and intellisense is vbInvoke
These 2 functions create "Accessors": IDispatch
Objects that can be used with dot notation accessor.Foo
or call by name CallByName(accessor, "Foo", ...)
to invoke
- Public methods/functions/properties of modules (Standard Accessor)
- Public or Private methods/functions/properties (Extended Accessor)
You can also use the Extended Accessor in a For-Each loop to print all the public & private methods (although this API may change to be more useful):
Dim exampleModuleAccessor As Object
Set exampleModuleAccessor = GetExtendedModuleAccessor("ExampleModule", ThisWorkbook.VBProject)
For Each methodName In exampleModuleAccessor
Debug.Print methodName 'or use with CallByName
Next methodName
Finally you can reference this library as a .twinpack
. This library only works when compiled into in-process DLLs or VBE Addins - it cannot be used to create a standalone EXE as it relies on sharing memory with the active VBProject.