Situation ..
For my project I need to perform some complex operations to the content of some Excel documents. So I thought this would be much more convenient to program the logic in c# rather than in a VBA macro. Since I need this logic in more than just one document, and I need different pieces of this logic in different document, I want to call the c# methods from within a VBA macro.
So ..
I came by this answer and it does perfectly solve the issue. However, it seems that since I need to pass the ThisWorkbook object from VBA into the .net methods, Excel.exe remains active in the background after closing the application (task manager > details). Next time I open Excel, it crashes immediately after which Excel.exe is then closed properly.
This is the only issue I have and I'm very frustrated I can't get it solved. Any ideas?
What I've considered ..
A working (non-perfect) solution is to make a document level VSTO add-in. But I don't get very excited about the need to make small changes and recompile the entire project for each different document. It would be way better if I could centralize the c# logic and require it from within the different documents.
Making an application level VSTO add-in is also undesired, since all users of the company I work for then need to install the VSTO add-in before they can open any document that requires it. This is too much risk and effort. I would rather centralize it, to prevent duplication and also to ensure that always the latest version is called.
My code ..
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
namespace ExcelVSTOUtils
{
[ComVisible(true), ClassInterface(ClassInterfaceType.AutoDispatch)]
public class Utilities
{
public Excel.Workbook _ThisWorkbook { get; private set; }
// parameterless constructor since vba does not support it
public Utilities(/*Excel.Workbook ThisWorkbook*/)
{
}
// helper function to set the workbook property after all
public void Initialize(Excel.Workbook ThisWorkbook)
{
_ThisWorkbook = ThisWorkbook;
}
// method 1
public void Method1()
{
// doing something complex with _ThisWorkbook ..
}
// method 2
public void Method2()
{
// doing something complex with _ThisWorkbook ..
}
}
}
'ThisWorkbook object
Private Utilities As New ExcelVSTOUtils.Utilities
Private Sub Workbook_Open()
Utilities.Initialize ThisWorkbook
End Sub
Sub Method1()
Utilities.Method1
End Sub
Sub Method2()
Utilities.Method2
End Sub