Greedquest / vbInvoke

vbInvoke
MIT License
9 stars 1 forks source link

vbInvoke Code Review GitHub Latest Release)

Library for calling methods in VBA modules with several key benefits:

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)

Quickstart

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:

ActiveX DLL (Tools⇒Add Reference)

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

Standard DLL Declare

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

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.