2010-08-09 47 views
4

我使用VS 2010开发Excel 2007 COM加载项。因为它是VS 2010 Office Project,所以它的目标是.NET 4.0 Client Framework。我添加了一个名为MyRibbon的新Ribbon(XML)项目,因此默认文件名为ThisAddIn.cs,MyRibbon.cs和MyRibbon.xml。VSTO Excel Com添加功能区无法加载

一切都很好。它以.vsto扩展名发布。当我安装加载项(通过提供的Setup.exe)时,它将以安装Excel的方式进行,并在COM加载项列表中进行检查。它也被指定在启动时加载。但是,首先打开Excel或打开Excel文件不会将该选项卡添加到功能区。

我可以告诉外接负载,因为它把“COM加载项加载”的第一片的第一个单元格。看起来好像CreateRibbonExtensibilityObject()没有被调用。

没有人有任何想法,或者能告诉我如何显示可能会得到安葬任何错误消息?

详情如下。

我添加CreateRibbonExtensibilityObject()的覆盖:

protected override Office.IRibbonExtensibility CreateRibbonExtensibilityObject() 
     { 
      return new MyRibbon(); 
     } 

MyRibbon.xml看起来是这样的,三个按钮组中的一个选项卡内:

<?xml version="1.0" encoding="UTF-8"?> 
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="Ribbon_Load"> 
    <ribbon> 
    <tabs> 
     <tab id="TabAdvComTracking" idMso="TabAdvComTrackingMso" label="Adv.com Tracking"> 
     <group id="groupPrepare" label="Prepare"> 
      <button id="GenerateNewWorkbook" idMso="GenerateNewWorkbookMso" enabled="1" size="large" onAction="GenNewWorkbook" label="Make" /> 
      <separator visible="1"/> 
      <button id="ClearData" idMso="ClearDataMso" enabled="1" size="large" onAction="ClearData" label="Clear" /> 
     </group> 
     <group id="GroupDoIt" idMso="GroupDoItMso" label="Just Do It"> 
      <button id="CaptureIds" idMso="CaptureIdsMso" enabled="1" size="large" onAction="CaptureData" label="Eat" /> 
     </group> 
     </tab> 
    </tabs> 
    </ribbon> 
</customUI> 

MyRibbon.cs外观像这样:

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Reflection; 
using System.Runtime.InteropServices; 
using System.Text; 
using Office = Microsoft.Office.Core; 
using Excel = Microsoft.Office.Interop.Excel; 

namespace AdvComTrackingAddIn 
{ 
    [ComVisible(true)] 
    public class MyRibbon : Office.IRibbonExtensibility 
    { 
     private Office.IRibbonUI ribbon; 

     public MyRibbon() 
     { 
     } 

     #region IRibbonExtensibility Members 

     public string GetCustomUI(string ribbonID) 
     { 
      //ribbonID when loaded into Excel should be Microsoft.Excel.Workbook 
      return GetResourceText("AdvComTrackingAddIn.MyRibbon.xml"); 
     } 

     #endregion 

     #region Ribbon Callbacks 
     //Create callback methods here. For more information about adding callback methods, select the Ribbon XML item in Solution Explorer and then press F1 

     public void Ribbon_Load(Office.IRibbonUI ribbonUI) 
     { 
      this.ribbon = ribbonUI; 
     } 

     public void GenNewWorkbook(Office.IRibbonControl control) 
     { 
      Excel.Workbook newWorkBook = Globals.ThisAddIn.Application.Workbooks.Add(); 

      Excel.Worksheet newWorkSheet = (Excel.Worksheet)newWorkBook.Worksheets.Add(); 
      newWorkSheet.Name = "DBTS " + GetDateRange("MMDDYYYY"); 


     } 

     public string GetDateRange(string format){ 
      string day = DateTime.Now.DayOfWeek.ToString(); 
      int offSet = 0; 
      if(day == "Sunday") offSet = 1; 
      else if(day == "Monday") offSet = 0; 
      else if(day == "Tuesday") offSet = -1; 
      else if(day == "Wednesday") offSet = -2; 
      else if(day == "Thursday") offSet = -3; 
      else if(day == "Friday") offSet = -4; 
      else if(day == "Saturday") offSet = -5; 

      DateTime MondayStartDate = DateTime.Now.AddDays(offSet);   

      return MondayStartDate.ToString(format) + "_" + MondayStartDate.AddDays(4).ToString(format);     
     } 

     public void ClearData(Office.IRibbonControl control) 
     { 
      Excel.Sheets wksheets = Globals.ThisAddIn.Application.Worksheets; 
      Excel.Worksheet sheet; 

      for(int i = 0; i < wksheets.Count; i++){ 
       sheet = wksheets[i]; 
       if(sheet.Name.StartsWith("DBTS")){ 
        sheet.get_Range("A6:H12").Clear(); 
        sheet.get_Range("A16:D22").Clear(); 
        sheet.get_Range("A26:D10000").Clear(); 
       } 
       else if(sheet.Name == "Advisory.com Activity"){ 
        sheet.get_Range("A4:B10000").Clear(); 
        sheet.get_Range("D4:F10000").Clear(); 
        sheet.get_Range("H4:J10000").Clear(); 
       } 
       else if(sheet.Name == "Unique Hits Per URL"){ 
        sheet.get_Range("A4:E10000").Clear(); 
       } 
      }    
     } 

     public void CaptureData(Office.IRibbonControl control) 
     { 
     } 

     #endregion 

     #region Helpers 

     private static string GetResourceText(string resourceName) 
     { 
      Assembly asm = Assembly.GetExecutingAssembly(); 
      string[] resourceNames = asm.GetManifestResourceNames(); 
      for (int i = 0; i < resourceNames.Length; ++i) 
      { 
       if (string.Compare(resourceName, resourceNames[i], StringComparison.OrdinalIgnoreCase) == 0) 
       { 
        using (StreamReader resourceReader = new StreamReader(asm.GetManifestResourceStream(resourceNames[i]))) 
        { 
         if (resourceReader != null) 
         { 
          return resourceReader.ReadToEnd(); 
         } 
        } 
       } 
      } 
      return null; 
     } 

     #endregion 
    } 
} 

最后,ThisAddIn.cs看起来像这样:

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; 
using System.IO; 
using System.Reflection; 

namespace AdvComTrackingAddIn 
{ 
    public partial class ThisAddIn 
    { 
     private void ThisAddIn_Startup(object sender, System.EventArgs e) 
     { 
      Globals.ThisAddIn.Application.get_Range("A1").Value = "COM add-in loaded"; 
     } 

     private void ThisAddIn_Shutdown(object sender, System.EventArgs e) 
     { 
      GC.Collect(); 
     } 

     protected override Office.IRibbonExtensibility CreateRibbonExtensibilityObject() 
     { 
      return new MyRibbon(); 
     } 

     #region VSTO generated code 

     /// <summary> 
     /// Required method for Designer support - do not modify 
     /// the contents of this method with the code editor. 
     /// </summary> 
     private void InternalStartup() 
     { 
      this.Startup += new System.EventHandler(ThisAddIn_Startup); 
      this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown); 
     } 

     #endregion 
    } 
} 

回答

3

您应该移除对CreateRibbonExtensibilityObject的覆盖。默认情况下,这由ThisAddIn的基类实现,并调用CreateRibbonObjects。您可以重写CreateRibbonObjects(这应该返回所有Ribbon对象的数组),或者让CreateRibbonObjects的默认实现完成它的工作(也就是说,每次启动插件时都会反映整个程序集)。

您可以在此blog post

2

试图更改默认TabAddIns时,我有同样的问题,了解更多关于如何这一切关系在一起。 我看到的是idMso是用于办公室栏选项卡和id是用于新选项卡。 以下适用于我。

<tab id="TabAdvComTracking" tag="TabAdvComTracking" label="Adv.com Tracking" visible="true" insertAfterMso="TabAddIns"> 
+0

优秀的信息。在我的环境中,各种插件已经实现。必须在默认加载项选项卡后插入新的VSTO插件。 – MichaelHuelsen 2017-07-27 08:48:07

4

我遇到了同样的问题。我不得不把XML文件中的不正确的路径,它是返回空:

public string GetCustomUI(string ribbonID) 
{ 
    return GetResourceText("CheckThisIsTheCorrectNameSpace.Ribbon.xml"); 
} 

硬编码命名空间作为一个字符串是不是一个好主意,主要是因为他们没有重构,能够和乐于助人的原因,我们的同胞Stackoverflow'rs在下面的评论中提到。

+1

这确实是一个陷阱,因为代码默认隐藏在折叠区域“IRibbonExtensibility Members”中。我首先驳回了这个答案,认为我的Ribbon.cs文件中没有这个函数,但确实是这样。当我重命名我的功能区时,此功能中的硬编码路径尚未自动更新。所以如果其他人想知道为什么他们的丝带没有出现,这是值得关注的。 – bovender 2014-07-18 15:27:35

+1

这帮助我找到了为什么在从传统WinForms样式功能区迁移后,xml功能区未加载,其中之前的开发人员通过链接引用添加源文件跨多个加载项共享功能区。采用这种方法,功能区xml不会作为资源返回。 – 2015-12-15 10:02:53

+1

如果将代码移动到文件夹中,请确保GetCustomUI()中的名称空间按照上面的Jerry Thompson注释进行更新。 – 2017-09-27 18:49:49