c# - Office 2013 c# 加载项 - 空工作簿对象 HRESULT : 0x800A03EC error

标签 c# .net excel ms-office office-interop

使用 Visual Studio Enterprise 2015 和 office 2013 pro,我创建了一个 Excel 2013 插件,当我调试它时,我无法引用 Application.Workbook 对象!这是一个最小的例子:

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
    }
}

在尝试分配 wb 时,我收到错误:

“ExcelAddIn1.dll 中发生了‘System.Runtime.InteropServices.COMException’类型的异常,但未在用户代码中处理”。

在检查(快速查看)应用程序对象时,许多属性具有以下值:

{System.Reflection.TargetInvocationException:调用的目标已引发异常。 ---> System.Runtime.InteropServices.COMException:旧格式或无效类型库。 (来自 HRESULT 的异常:0x80028018 (TYPE_E_INVDATAREAD))"

除其他问题外,似乎应用程序对象没有工作簿。
我确定代码没问题,但也许我的 .Net 框架或办公版本或build设置有问题?
任何人都可以对此有所了解吗?

** 编辑 1 **

因此,根据 Richard Morgan 的建议,我尝试了以下操作,发现原始代码运行时可能没有事件的工作簿:
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
    }
}

因此,当 WorkWithWorkbook() 执行时,我希望有一个 ActiveWorkbook 可以引用。不幸的是,我仍然得到 COMException:

“HRESULT 异常:0x800A03EC”。

对应用程序对象的进一步检查显示工作簿集合已部分填充,但许多属性仍引用:

System.Runtime.InteropServices.COMException - 旧格式或无效类型库

进一步搜索表明,这可能是由于 Excel 和 VS 代码之间的区域设置不匹配造成的,但我已经检查了在这种情况下区域是否匹配。

编辑 2

所以也许我在这里很愚蠢!进一步阅读表明应用程序的 .ThisWorkbook 属性返回对包含代码的工作簿的引用。由于这是一个加载项,因此代码包含在 .dll 中。因此,我使用了 .ActiveWorkbook,它返回了一个引用而不抛出异常!

最佳答案

那是奇怪的代码:

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;
}

因此,Excel 为您提供了准确的 Workbook刚刚被激活,然后你自己运行代码来解决它?!

对此要非常小心。

我们遇到了 ActiveWorkbook 的问题和 ThisWorkbook在我们的 VSTO Excel 插件中,特别是当用户“做某事”来启动我们的 VSTO 代码时,但他们打开了其他 Excel 文件,或者我们的 VSTO 任务需要一些时间,同时他们切换到另一个工作簿。

确保您的代码处理正确文件的最佳(唯一?)方法是始终使用 Workbook传递给您的 OnActivate功能。
private void WorkWithWorkbook(Microsoft.Office.Interop.Excel.Workbook workbook)
{
    //  Do some stuff directly with "workbook" 
    //  
}

至于 0x800A03EC 错误,它似乎是 Excel 的通用“这可能意味着任何”COM 错误之一。

我们在尝试找出哪个 Excel Workbook 时也看到了它。我们应该使用的对象。

关于c# - Office 2013 c# 加载项 - 空工作簿对象 HRESULT : 0x800A03EC error,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32847674/

相关文章:

c# - 从两个列表中生成一个列表

c# - 无法将 utc 时间转换为特定时区

c# - IPAddress 上的奇怪 .Net 行为等于

c# - C#中事件的主要目的

java - java语言标签为zh-CN时如何获取中文(简体)?

c# - ImageResizer - 转换 PSD 文件时出错 - System.ArgumentException : Parameter is not valid

c# - 使用反射(PrivateObject)进行测试

c# - 子目录中私有(private)程序集的运行时加载

VBA 锁定了我的工作表

excel - 在 Excel 的 Power Query 中将日期转换为序列号