I found a way to call .NET 2 code directly from VBA code:
Dim clr As mscoree.CorRuntimeHost
Set clr = New mscoree.CorR
I'm not sure if this was just a coincidence or because I posted related question. SO showed me your question and I think I could also contribute something.
When working with VBA and DLL, most solutions that I've seen so far is telling me to register the DLL and make it com/gac visible. If you are doing this in your PC that's absolutely fine but if you are distributing your VBA application, you don't really want to install DLLs in their system. You might not have permission or you don't really want to go through install/uninstall process or messing with referencing issues.
However you can load dlls dynamically using some windows APIs.
DLL
Now the question is how to access .NET dll from vba? if your clients have mixed os architecture x86 x64 you need to handle this accordingly. Lets assume we are working on 32bit office/Excel.
If you create a .NET dll and would like to access it from VBA it will throw an error message similar to "Can't find the dll entry point". thankfully Robert Giesecke has created an abstract wrapper which will allow you to create simple DLL consumable via VBA.
A template can be found here.
All you have to do
Lets assume you have followed his template and created a test method as following.
[ComVisible(true), ClassInterface(ClassInterfaceType.AutoDual)]
public class YOUR_MAIN_CLASS
{
[return: MarshalAs(UnmanagedType.BStr)]
public string FN_RETURN_TEXT(string iMsg)
{
return "You have sent me: " + iMsg + "...";
}
}
and your unmanagedexport class:
static class UnmanagedExports
{
[DllExport]
[return: MarshalAs(UnmanagedType.IDispatch)]
static object YOUR_DLL_OBJECT()
{
return new YOUR_MAIN_CLASS();
}
}
Preparing to access the dll from vba side
Add the DLL to your root folder:
#If VBA7 Then
Public Declare PtrSafe Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As LongPtr
Public Declare PtrSafe Function YOUR_DLL_OBJECT Lib "YOUR_DLL.dll" () As Object
#Else
Public Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal strFilePath As String) As Long
Public Declare Function YOUR_DLL_OBJECT Lib "YOUR_DLL.dll" () As Object
#End If
Now It's all about loading the dll and creating & accessing objects it in vba. that would be:
LoadLibrary (FN_APP_GET_BASE_PATH & "YOUR_DLL.dll")
dim mObj as object
set mObj = YOUR_DLL_OBJECT()
debug.print mObj.FN_RETURN_TEXT("Testing ..")
the output should be
"You have sent me: Testing ....."
Advantages I personally don't like installing and referencing dlls. By following above template, you don't need to reference anything, you don't need to install anything just load and work with your the DLL with full freedom.
NOTE: I assume the dll/.net code is yours and you can compile it again with above templates to.
I had success with above template and created a .NET non-blocking notifications for vba you can have a look here: non-blocking "toast" like notifications for Microsoft Access (VBA)