Office 2013 c# add-in - Null workbook object HRESULT: 0x800A03EC error

2

Using Visual Studio Enterprise 2015 and office 2013 pro, I have created an Excel 2013 addin and when I debug it, I am unable to reference the Application.Workbook object! Here is a minimal example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Excel = Microsoft.Office.Interop.Excel;
using Office = Microsoft.Office.Core;
using Microsoft.Office.Tools.Excel;

namespace ExcelAddIn1
{
    public partial class ThisAddIn
    {
         private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            var app = Globals.ThisAddIn.Application;
            var wb = app.ThisWorkbook;
        }

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }

        #region VSTO generated code

        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }

        #endregion
    }
}

On attempting to assign wb, I receive the error:

"An exception of type 'System.Runtime.InteropServices.COMException' occurred in ExcelAddIn1.dll but was not handled in user code".

On inspection (quick watch) of the application object many of the properties have the value:

{System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Runtime.InteropServices.COMException: Old format or invalid type library. (Exception from HRESULT: 0x80028018 (TYPE_E_INVDATAREAD))"

It seems the application object has no workbook, amongst other problems. I'm sure that the code is ok, but perhaps there is something wrong with my .Net framework or office versions or build settings? Can anyone shed any light on this please?

** Edit 1 **

So based on Richard Morgan's suggestion I tried the following, having seen that there may be no active workbook when the original code runs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Excel = Microsoft.Office.Interop.Excel;
using Office = Microsoft.Office.Core;
using Microsoft.Office.Tools.Excel;

namespace ExcelAddIn1
{
    public partial class ThisAddIn
    {
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {

            this.Application.WorkbookActivate += new Excel.AppEvents_WorkbookActivateEventHandler(WorkWithWorkbook);
        }

        private void WorkWithWorkbook(Microsoft.Office.Interop.Excel.Workbook workbook)
        {
            // Workbook has been opened. Do stuff here.
            var app = Globals.ThisAddIn.Application;
            Excel.Workbook wb = app.ThisWorkbook;
        }

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }

        #region VSTO generated code

        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }

        #endregion
    }
}

So when WorkWithWorkbook() is executed, I expect that there is an ActiveWorkbook to get a reference to. Unfortunately, I still get the COMException with:

"Exception from HRESULT: 0x800A03EC".

Further checking of the application object shows that the workbooks collection is partially populated but many properties still refer to:

System.Runtime.InteropServices.COMException - Old Format or Invalid Type Library

Further searching has revealed that this can be caused by mismatching region settings between Excel and VS code, but I've checked that the regions match in this case.

Edit 2

So perhaps I'm being very foolish here! Further reading shows that the application's .ThisWorkbook property returns a reference to the workbook in which the code is contained. As this is an add-in, the code is contained in .dll. So instead, I used .ActiveWorkbook, which returned a reference without throwing an exception!

c#
.net
excel
ms-office
office-interop
asked on Stack Overflow Sep 29, 2015 by Flakker • edited Sep 30, 2015 by Flakker

2 Answers

1

That is strange code:

private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
    this.Application.WorkbookActivate += new Excel.AppEvents_WorkbookActivateEventHandler(WorkWithWorkbook);
}

private void WorkWithWorkbook(Microsoft.Office.Interop.Excel.Workbook workbook)
{
    // Workbook has been opened. Do stuff here.
    var app = Globals.ThisAddIn.Application;
    Excel.Workbook wb = app.ThisWorkbook;
}

So, Excel provides you with the exact Workbook which has just been Activated, then you run code to work it out yourself ?!

Be very careful with this.

We have had issues with ActiveWorkbook and ThisWorkbook in our VSTO Excel Addin, particularly when users "do something" to kick off our VSTO code, but they have other Excel files open, or our VSTO task takes some time, and they switch to another workbook in the meantime.

The best (only?) way to make sure that your code is dealing with the right file is to always use the Workbook which is passed to your OnActivate function.

private void WorkWithWorkbook(Microsoft.Office.Interop.Excel.Workbook workbook)
{
    //  Do some stuff directly with "workbook" 
    //  
}

As for the 0x800A03EC error, it seems to be one of Excel's generic "this could mean anything" COM errors.

We've also seen it when attempting to work out which Excel Workbook object we should be using.

answered on Stack Overflow Sep 30, 2015 by Mike Gledhill
0

Because the add-in code was not contained in a workbook, the Application.ThisWorkbook property is not set. The Application.ThisWorkbook property is used to return a reference to the workbook containing the code, and no such workbook exists!

In order to get a reference to the workbook currently open and causing the code to be executed, the Application.ActiveWorkbook reference should be used instead.

answered on Stack Overflow Sep 30, 2015 by Flakker

User contributions licensed under CC BY-SA 3.0