Skip to content

Greedquest/vbInvoke

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

92 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

vbInvoke Code Review GitHub Latest Release)

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 (unlike AddressOf which uses pointers invoked by DispCallFunc)
  • 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)

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

  • 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.