在C#中获取NamedRange控件的句柄

我正在开发使用C#(.NET 4.0)的Excel 2007的应用程序级AddIn。 以前曾问过类似这个问题>>

https://stackoverflow.com/questions/11374023/resizing-namedrange-throws-a-controlnotfoundexception

C#excel插件 – 访问控件

但对他们的回应(有的话)并不适合我。 所以我想详细描述一下我想做什么,以及当我尝试做什么时会发生什么。

简而言之,我的问题是我无法获得NamedRange控件对象来修改它们,在代码中的其他地方实例化和初始化之后。

请阅读更完整的说明。

当AddIn启动时,它创build一个NamedRange控件并将其附加到特定工作表上的某些单元格>>

Worksheet worksheet = Globals.Factory.GetVstoObject( Globals.ThisAddIn.Application.ActiveWorkbook.ActiveSheet); Excel.Range cell = worksheet.Range["A1"]; _configParams.HeaderNamedRange = worksheet.Controls.AddNamedRange(cell, "HeaderCells"); _configParams.HeaderNamedRange.RefersTo = "=" + worksheet.Name + "!$A$1:$A$5"; 

AddIn启动后,我想要允许用户重新指定NamedRange控件可以指向的单元格。 为了这样做,我让用户select一个单元格范围,然后在合适的事件处理程序方法中获取所选单元格的位置(作为string)。

然后我打算以编程方式重新指定上述NamedRange控件指向的单元格。 我已经尝试了以下方法,但都没有工作。

[方法1]

 Worksheet controlWorksheet = Globals.Factory.GetVstoObject(Globals.ThisAddIn.Application.ActiveWorkbook.ActiveSheet); ((NamedRange)(controlWorksheet.Controls["HeaderCells"])).RefersTo = newHeaderCellsLocation; 

在运行上面的代码,它会引发一个ControlNotFoundException,并得到以下消息:

 Microsoft.VisualStudio.Tools.Applications.Runtime.ControlNotFoundException was unhandled by user code Message=This document might not function as expected because the following control is missing: PortfolioHeaderCells. Data that relies on this control will not be automatically displayed or updated, and other custom functionality will not be available. Contact your administrator or the author of this document for further assistance. Source=Microsoft.Office.Tools.Excel.Implementation StackTrace: at Microsoft.Office.Tools.Excel.NamedRangeImpl.GetObjects() at Microsoft.Office.Tools.Excel.NamedRangeImpl.EnsureProxy() at Microsoft.Office.Tools.Excel.NamedRangeImpl.get_Proxy() at Microsoft.Office.Tools.Excel.NamedRangeImpl.AttachSupport() at Microsoft.Office.Tools.Excel.NamedRangeImpl.ResetControl() at Microsoft.Office.Tools.Excel.NamedRangeImpl.set_RefersTo(String value) at ExcelListenerAddIn.Configuration.ListenerConfigManager.ActivateListenerConfiguration(ListenerConfigParams newConfiguration, Boolean cameFromConfigFile) in C:\Users\jag201\Documents\Visual Studio 2010\Projects\PoC\ExcelListenerAddIn\Configuration\ListenerConfigManager.cs:line 97 at ExcelListenerAddIn.TaskPanes.ListenerConfigurator._activateNewConfigButton_Click(Object sender, EventArgs e) in C:\Users\jag201\Documents\Visual Studio 2010\Projects\PoC\ExcelListenerAddIn\TaskPanes\ListenerConfigurator.cs:line 131 at System.EventHandler.Invoke(Object sender, EventArgs e) at System.Windows.Forms.Control.OnClick(EventArgs e) at System.Windows.Forms.Button.OnClick(EventArgs e) at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ButtonBase.WndProc(Message& m) at System.Windows.Forms.Button.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) InnerException: System.Runtime.InteropServices.COMException Message=Exception from HRESULT: 0x800A03EC Source=Microsoft.VisualStudio.Tools.Office.Runtime ErrorCode=-2146827284 StackTrace: at Microsoft.VisualStudio.Tools.Office.Runtime.Interop.IHostItemProvider.GetHostObject(String primaryType, String primaryCookie, IntPtr& hostObject) at Microsoft.VisualStudio.Tools.Office.Runtime.DomainCreator.ExecuteCustomization.Microsoft.Office.Tools.IHostItemProvider.GetHostObject(Type primaryType, String primaryCookie) at Microsoft.Office.Tools.Excel.NamedRangeImpl.GetObjects() InnerException: 

[方法2]

然后我看到通过C#设置Excel命名范围? 所以试图使用在答案中描述的方法:

 Worksheet controlWorksheet = Globals.Factory.GetVstoObject(Globals.ThisAddIn.Application.ActiveWorkbook.ActiveSheet); controlWorksheet.Names.Item("HeaderCells", Type.Missing, Type.Missing).RefersTo = newHeaderCellsLocation; 

在运行上面的代码,我得到以下exception和消息:

 System.Runtime.InteropServices.COMException was unhandled by user code Message=Exception from HRESULT: 0x800A03EC Source="" ErrorCode=-2146827284 StackTrace: at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData) at Microsoft.Office.Interop.Excel.Names.Item(Object Index, Object IndexLocal, Object RefersTo) at ExcelListenerAddIn.Configuration.ListenerConfigManager.ActivateListenerConfiguration(ListenerConfigParams newConfiguration, Boolean cameFromConfigFile) in C:\Users\jag201\Documents\Visual Studio 2010\Projects\PoC\ExcelListenerAddIn\Configuration\ListenerConfigManager.cs:line 97 at ExcelListenerAddIn.TaskPanes.ListenerConfigurator._activateNewConfigButton_Click(Object sender, EventArgs e) in C:\Users\jag201\Documents\Visual Studio 2010\Projects\PoC\ExcelListenerAddIn\TaskPanes\ListenerConfigurator.cs:line 131 at System.EventHandler.Invoke(Object sender, EventArgs e) at System.Windows.Forms.Control.OnClick(EventArgs e) at System.Windows.Forms.Button.OnClick(EventArgs e) at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ButtonBase.WndProc(Message& m) at System.Windows.Forms.Button.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) InnerException: 

所以,在这两种方法中,HRESULT的exception都是一样的:0x800A03EC。 另外,这个exception是在我试图获得NamedRange控件并重新指定它指向的单元格的行中引发的。

我已经通过我的代码,并且一个NamedRange控件确实存在的地方/当我尝试修改NamedRange对象。

然后我使用下面的代码检查了controlWorksheet.Controls["HeaderCells"]对象的types>>

 Worksheet controlWorksheet = Globals.Factory.GetVstoObject(Globals.ThisAddIn.Application.ActiveWorkbook.ActiveSheet); System.Windows.Forms.MessageBox.Show((controlWorksheet.Controls["HeaderCells"]).ToString()); 

这会导致包含“Microsoft.Office.Tools.Excel.NamedRangeImpl”的MessageBox。 如果我没有弄错,这个types不是由Excel对象模型公开的,所以我不知道这个问题是否是由于我将一个NamedRangeImpl对象转换为一个NamedRange控件对象而引起的。

非常感谢您的帮助。 如果有任何我可以提供的进一步的信息,请让我知道。 提前致谢!

返回的对象types没有问题。 types“Microsoft.Office.Tools.Excel.NamedRangeImp”旨在通过“Microsoft.Office.Tools.Excel.NamedRange”接口访问。

0x800A03EC的COMexception向我build议,excel将不允许你执行请求的操作(这也是你会得到的错误代码,例如,发送一个string值给超过字符限制的单元格) 。

有几次设置RefersTo属性没有问题,因为我通过运行以下代码进行validation:

  Microsoft.Office.Tools.Excel.Worksheet worksheet = Globals.Factory.GetVstoObject( Globals.MercuryAddIn.Application.ActiveWorkbook.ActiveSheet); Excel.Range cell = worksheet.Range["A1"]; Microsoft.Office.Tools.Excel.NamedRange r = worksheet.Controls.AddNamedRange(cell, "HeaderCells"); r.RefersTo = "=" + worksheet.Name + "!$A$1:$A$5"; r.RefersTo = "=" + worksheet.Name + "!$C$1:$C$5"; 

所以这个问题必须存在于你的“newHeaderCellsLocation”variables中的string中。 RefersTo必须设置为一个范围的有效公式。 你可以仔细检查,string是在正确的格式?