Office 2013 c#加载项 – 空工作簿对象HRESULT:0x800A03EC错误
使用Visual Studio Enterprise 2015和office 2013 pro,我创build了一个Excel 2013插件,当我debugging它时,我无法引用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“types的exception,但未在用户代码中处理”。
在应用程序对象的检查(快速监视)中,许多属性具有以下价值:
{System.Reflection.TargetInvocationException:exception已被调用的目标引发。 —> System.Runtime.InteropServices.COMException:旧格式或无效的types库。 (来自HRESULT的exception:0x80028018(TYPE_E_INVDATAREAD))“
看来应用程序对象没有工作簿,除其他问题之外。 我敢肯定,代码是好的,但也许有我的.NET框架或办公室版本或build立设置有问题吗? 任何人都可以摆脱这个光?
**编辑1 **
所以基于理查德·摩根的build议,我尝试了以下,看到有可能没有活动工作簿原始代码运行时:
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的exception:0x800A03EC”。
对应用程序对象的进一步检查显示,工作簿集合已部分填充,但许多属性仍指向:
System.Runtime.InteropServices.COMException – 旧的格式或无效的types库
进一步的search已经显示,这可能是由于Excel和VS代码之间的区域设置不匹配造成的,但是我已经检查过在这种情况下匹配的区域。
编辑2
所以也许我在这里很愚蠢! 进一步阅读显示应用程序的.ThisWorkbook属性返回包含代码的工作簿的引用。 由于这是一个加载项,代码包含在.dll中。 所以相反,我使用.ActiveWorkbook,它返回一个引用,而不会引发exception!
这是奇怪的代码:
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 Addin中,我们遇到了ActiveWorkbook
和ThisWorkbook
问题,特别是当用户“做某些事情”来启动我们的VSTO代码,但他们还有其他Excel文件打开,或者我们的VSTO任务需要一些时间,他们切换到另一个工作簿同时。
确保代码处理正确的文件的最佳(唯一的方法)是始终使用传递给OnActivate
函数的Workbook
。
private void WorkWithWorkbook(Microsoft.Office.Interop.Excel.Workbook workbook) { // Do some stuff directly with "workbook" // }
至于0x800A03EC错误,它似乎是Excel的通用“这可能意味着什么”COM错误之一。
当我们试图找出我们应该使用哪个Excel Workbook
对象时,我们也看到了它。
因为加载项代码不包含在工作簿中,所以未设置Application.ThisWorkbook
属性。 Application.ThisWorkbook
属性用于返回对包含代码的工作簿的引用,并且不存在此类工作簿!
为了获得对当前打开的工作簿的引用并导致代码执行,应该使用Application.ActiveWorkbook
引用。