SteGriff

Blog

Next & Previous

Globals.ThisAddIn is null or Nothing in VSTO Automation Add-In

Scenario

You’ve created a VSTO Add-In and you want to call some of the code from VBA, so you’ve followed the procedure to expose RequestComAddInAutomationService. But when you create an instance of that exposed object and try to call one of its properties or methods, you get an error because Globals.ThisAddIn == null or Nothing.

You may be making the same mistake I made, which is to ask for a New AddInUtilities instead of using the existing instance.

Example VSTO code in ThisAddIn.vb

Your exposed class could be called anything, but for these examples, I’m going to use AddInUtilities.

Private utilities As AddInUtilities

Protected Overrides Function RequestComAddInAutomationService() As Object
	If utilities Is Nothing Then
		utilities = New AddInUtilities()
	End If
	Return utilities
End Function

Your bad VBA code

If you’ve set up your projects like I do, so that you get Intellisense in VBA, then you may have been tempted to write your code like the sample below:

Dim utils = New AddInUtilities
utils.DoSomething

The problem with this is that you’ve created a new instance of your Automation object (AddInUtilities), therefore it doesn’t have access to Globals.ThisAddIn. Check out the VBA-VSTO Walkthrough on MSDN, and you’ll see that they get the automation object like this:

Sub CallVSTOMethod()
	Dim addIn As COMAddIn
	Dim automationObject As Object
	Set addIn = Application.COMAddIns("ExcelImportData")
	Set automationObject = addIn.Object
	automationObject.ImportData
End Sub

I’ve previously looked at this snippet and gone “Bah! That’s stupid, because they treat their automationObject as an Object and don’t get any early binding or Intellisense.” and thereby I led myself into failure.

Fixing your VBA

Your easy fix for one-offs is to use the CallVSTOMethod snippet from above, but change Object to AddInUtilities so that you get Intellisense and early binding.

The (slightly) more sophisticated approach, to get properly nice global access to your class(with Intellisense) is to add something like this in a VBA Module (all modules are global):

Private pAi As Core

'Get the AddIn Automation Object
Public Property Get Ai()
	If pAi Is Nothing Then
		Dim MyAddIn As COMAddIn
		'Set the right name here instead of "MyAddIn"
		Set MyAddIn = Application.COMAddIns("MyAddIn") 
		Set pAi = WtsrAddIn.Object
	End If
	Set Ai = pAi
End Property

And then anywhere you want to make use of a VSTO method, call it like so:

Ai.DoSomething

Conclusion

Hopefully this will help you with your Globals.ThisAddIn object being null! If you are really stuck with VBA-VSTO interoperability, follow the MSDN tutorial and then customise it as necessary.

I have found that with Office solutions, writing basic test projects and spreadsheets is really helpful for proving something works before moving the principles into my main project.