I want to call System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) on some 3rd party COM objects that I’ve instantiated in my VBA code, from my workbook close event, something like the following:
Public Sub disconnect(obj As Variant)
Dim refs As Long
refs = 0
If Not obj Is Nothing Then
Do
refs = System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
Loop While (refs > 0)
End If
End Sub
However, I get a compile error: invalid qualifier with the System highlighted with the above code. Search doesn’t seem to return any VBA code that calls System.Runtime methods from a VBA macro – I can only find VB.Net automating Excel. I’m not sure it’s even possible.
I’m trying to resolve this issue: Excel 2007 Zombie Process not COM automation but w/ references to 3rd party com objects by ensuring these 3rd party COM objects are properly disposed of before Excel exits.
I was unable to resolve the zombie problem using the recommended VBA only method, even after careful checking for and removal of circular references.
Additional searching turned up a way to call the
ReleaseCommethod using code that wrapsSystem.Runtime.InteropServices.Marshal.FinalReleaseComObjectto create a COM visible dll that can be called from VBAUsing the tutorial “how to create a com object using vs 2008 and consume it from vb6.0 client” and a newly installed copy of VS2010 Express, I was able to create a COM visible dll callable from VBA.
Here’s the slightly modified wrapper and how to build the dll:
and the interface:
To build, create a new class library project, add references to
System.Runtime.InteropServicesandSystem.EnterpriseServices, enable ‘Sign the assembly’ (in the menu under project / properties / signing ) and select or create a key file. Add the class and interface code files. In the AssemblyInfo.cs file (located under properties) addand
and build. If all goes well, you can register you dll as follows:
In VBA, after adding a reference to your new COM library, use it as follows:
Early testing indicates that it’s working, i.e. Excel closes cleanly and no longer creates zombie processes.
Interestingly, I just ran across this method for using your dll from VBA without having to register it first which could be useful if you didn’t have access to the registry on your client machine.