Creating a C # COM visible class is quite simple, and (as you said in your comments) is fun. Here is a small sample.
In a new C # library project, add:
using System; using System.Runtime.InteropServices; using System.Windows.Forms; namespace CSharpCom { [ComVisible(true)] [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] //The 3 GUIDs in this file need to be unique for your COM object. //Generate new ones using Tools->Create GUID in VS2010 [Guid("18C66A75-5CA4-4555-991D-7115DB857F7A")] public interface ICSharpCom { string Format(string FormatString, [Optional]object arg0, [Optional]object arg1, [Optional]object arg2, [Optional]object arg3); void ShowMessageBox(string SomeText); } //TODO: Change me! [Guid("5D338F6F-A028-41CA-9054-18752D14B1BB")] //Change this [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] interface ICSharpComEvents { //Add event definitions here. Add [DispId(1..n)] attributes //before each event declaration. } [ComVisible(true)] [ClassInterface(ClassInterfaceType.None)] [ComSourceInterfaces(typeof(ICSharpComEvents))] //TODO: Change me! [Guid("C17C5EAD-AA14-464E-AD32-E9521AC17134")] public sealed class CSharpCom : ICSharpCom { public string Format(string FormatString, [Optional]object arg0, [Optional]object arg1, [Optional]object arg2, [Optional]object arg3) { return string.Format(FormatString, arg0, arg1, arg2, arg3); } public void ShowMessageBox(string SomeText) { MessageBox.Show(SomeText); } } }
You will want to enter your project properties, on the "Signing" tab, check the box to sign your assembly, and create a new "strong name key file". This will help prevent version problems in your registered DLL.
Compile it and register the DLL with regasm at the Visual Studio command prompt. You will use 32 or 64-bit regasm depending on which version of Office you are using ... you will find RegAsm in C:\windows\Microsoft.NET\Framework or C:\windows\Microsoft.NET\Framework64 (respectively 32 and 64 bit):
C:\windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe /codebase /tlb CSharpCom.dll
This will register your Windows DLL, so now in the VBA editor you can go to Tools-> References and find your COM namespace "CSharpCom". Check this box and now you can create your COM objects in VBA:
Sub TestCom() Dim c As CSharpCom.CSharpCom Set c = New CSharpCom.CSharpCom c.ShowMessageBox c.Format("{0} {1}!", "Hello", "World") End Sub
You can add forms to your COM object and open them when VBA calls a specific method; you must use this to create a progress bar form. However, it is worth considering that VBA is single-threaded. This means that everything else freezes while your code is running, so everything can get a little confused.
At the top of my head, you can create 3 methods in the COM visibility class: one to open the form, one to update the progress (calling the VBA DoEvents () method right after your VBA calls the update () method of your COM object to let Office handle screen updates), and one to close it. You must call Dispose () on the form; what can be done in the close method, but I think it could potentially cause a memory leak / problem if your VBA crashes and your close method is never called - just something else to consider.