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

时间:2012-09-04 20:15:22

标签: c# .net excel user-controls vsto

我正在使用C#(.NET 4.0)开发Excel 2007的应用程序级AddIn。之前已经问过与此类似的问题>>

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

C# excel addin - Accessing Controls

但是对他们的反应(哪里有)对我不起作用。所以我想详细描述我正在尝试做什么,以及当我尝试这样做时会发生什么。

非常简单,我的问题是,在实例化并在代码中的其他位置初始化之后,我无法获取NamedRange控件对象以进行修改。

请继续阅读以获得更完整的说明。

当AddIn启动时,它会创建一个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控件可指向的单元格。为了做到这一点,我让用户选择一系列单元格,然后在合适的事件处理程序方法中获取所选单元格的位置(作为字符串)。

然后我打算以编程方式重新指定上面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]

然后我看到Set Excel Named Ranges via C#?,因此尝试使用答案中描述的方法:

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

在运行上面的代码时,我收到以下异常和消息:

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的异常都是相同的:0x800A03EC。此外,在我尝试获取NamedRange控件并重新指定它指向的单元格的行中抛出异常。

我已经完成了我的代码,当我尝试修改NamedRange对象时,确实存在NamedRange控件。

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

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

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

非常感谢您的帮助。如果我能提供任何进一步的信息,请告诉我。提前谢谢!

1 个答案:

答案 0 :(得分:0)

返回的对象类型没有问题。 “Microsoft.Office.Tools.Excel.NamedRangeImp”类型旨在通过“Microsoft.Office.Tools.Excel.NamedRange”界面访问。

0x800A03EC的COM异常向我建议excel不允许您执行请求的操作(这也是您尝试的错误代码,例如,将字符串值发送到超过字符限制)。

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

        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”变量中包含的字符串中。 RefersTo必须设置为范围的有效公式。你能仔细检查字符串是否格式正确吗?