2015-09-29 87 views
1

使用Visual Studio Enterprise 2015和office 2013 pro,我创建了Excel 2013插件,当我调试它时,我无法引用Application.Workbook对象!下面是一个小例子:Office 2013 c#插件 - 空工作簿对象HRESULT:0x800A03EC错误

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,我收到错误:

“‘System.Runtime.InteropServices.COMException’类型的异常出现在ExcelAddIn1.dll但不在用户代码中处理“。

在应用程序对象许多属性的检查(快速手表)具有值:

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

看来申请对象有没有工作簿,除其他问题 我敢肯定,代码是好的,但也许有一些错误与我的.NET。框架或Office版本或建立设置? 任何人都可以摆脱任何光线就这个吗?

**编辑** 1

因此,基于理查德摩根的建议我尝试以下,已经看到,有可能是没有当原始代码运行时的活动工作簿:

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,它返回了一个引用而不会引发异常!

+0

http://stackoverflow.com/help/mcve – xxbbcc

+0

你确实有一个参考设置为“Microsoft.Office.Interop”?如果是这样,也许使用'Excel.Workbook'而不是'var' –

+0

感谢xxbbcc这现在是一个mcve – Flakker

回答

1

这是奇怪的代码:

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刚刚被激活,然后运行的代码去解决它自己呢?!

对此要非常小心。

我们有问题,在我们的VSTO Excel加载项,特别是当用户“做什么”,以揭开序幕,我们的VSTO代码ActiveWorkbookThisWorkbook,但他们有其他的Excel文件打开,或我们的VSTO任务需要花费一些时间,他们同时切换到另一个工作簿。

确保您的代码处理正确的文件的最佳(唯一?)方法是始终使用传递到OnActivate函数的Workbook

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

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

我们在试图工作时也看到了它其中Excel Workbook我们应该使用的对象。

+0

是的,这很奇怪,但对于这个例子,我只是选择了我在列表中看到的第一个保证工作簿处于活动状态的事件! – Flakker

0

由于加载项代码未包含在工作簿中,因此未设置Application.ThisWorkbook属性。 Application.ThisWorkbook属性用于返回对包含代码的工作簿的引用,并且不存在此类工作簿!

为了获得对当前打开的工作簿的引用并导致代码执行,应该使用Application.ActiveWorkbook引用。

相关问题