2013-08-04 110 views
4

我有一个自定义的Excel功能区和一个包含一个在打开工作簿时实例化的类的Excel附加组件。根据班级的某些属性,我需要隐藏自定义功能区中的某些按钮(全部在同一个标​​签中)。隐藏个别自定义功能区按钮

我的自定义功能区是:

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="loadCustom"> 
<ribbon> 
<tabs> 
<tab id="tab1" label="customTab" getVisible="GetVisible" tag="myTab"> 
<group id="grp1" label="Group1" imageMso="ViewFullScreenView" getVisible="GetVisible"> 
    <button id="Bt1" size="large" label="Button1" imageMso="AccessListIssues" onAction="runBt1" visible="true"/> 
    <button id="Bt2" size="large" label="Button2" imageMso="AccessListTasks" onAction="runBt2" visible="true"/> 
    <button id="Bt3" size="large" label="Button3" imageMso="ControlLayoutStacked" onAction="runBt3" visible="true"/> 
    <button id="Bt4" size="large" label="Button4" imageMso="ControlLayoutTabular" onAction="runBt4" visible="true"/> 

</group> 
</tab> 
</tabs> 
</ribbon> 
</customUI> 

然后我有一个模块在下面的VBA宏加载自定义功能区和/或禁用:

Public Sub loadCustom(ribbon As IRibbonUI) 

    Set RibUI = ribbon 

    If workbookTitle = "myWorkbook" Then 
     MyTag = "show" 
    Else 
     MyTag = False 
     RefreshRibbon MyTag 
    End If 

End Sub 

Sub GetVisible(control As IRibbonControl, ByRef visible) 

    If MyTag = "show" Then 
     visible = True 
    Else 
     If control.Tag Like MyTag Then 
      visible = True 
     Else 
      visible = False 
     End If 
    End If 
End Sub 

Sub RefreshRibbon(Tag As String) 
    MyTag = Tag 
    If RibUI Is Nothing Then 
     MsgBox "Error, Save/Restart your workbook" 
    Else 
     RibUI.Invalidate 
    End If 
End Sub 

在我具体的工作簿中功能区应加载为我有一个隐藏的表,从我的类模块类读取每个按钮的值,以确定它是否应该显示或不。一旦我阅读了这个值,我该如何隐藏一个单独的按钮?我发现的所有例子似乎只能用于制表符。我可以将ribbonUI传递给类并通过每个控件循环吗?我一直无法找到这样做的方法。谢谢你的帮助!

回答

5

您需要在运行时自定义功能区。

检查我的问题(和答案)here尽管我的问题是在PPT VBA中,我在Excel中做了我的测试,解决方案与您的问题应该非常相似。

而不是指定一个布尔truefalse每个按钮的visible财产,你需要另一个回调,这样,当装入此选项卡中,过程检查您的类对象是否已经被实例化,然后设置truefalse作为必要。

举例来说,在我的XML我的PPT部分是这样的:

... 
<tab idMso="TabView"> 
       <group idMso="GroupMasterViews" getVisible="VisibleGroup"/> 
       <group idMso="GroupPresentationViews" getVisible="VisibleGroup"/> 
      </tab> 
      ... 

因此,而不是使用组的Visible财产,我使用自定义属性getVisible它调用宏VisibleGroup。有一些细微差别,我跑中一样,我不能使用相同的回调/微距不同类型的控件,因此为什么我有两个回调(EnabledControlVisibleGroup)两者做同样的事情 。我不知道为什么,不幸的是,这部分开发似乎没有很好的记录。

查看我的代码,查看我在测试时放置断点的所有位置。我必须做相当多的调试才能使其工作。每隔程序在中放置断点并逐步执行代码。这是一个痛苦的屁股,但如果你已经得到这么多,我相信你将能够使它的工作。

UPDATE

我做我的PPT外接一个简短的测试。在功能上,这是相似的,所以比我尝试重新创建Excel中的所有内容更容易测试。

我的加载项有它自己的菜单组和一些自定义按钮。相关的按钮行是这样的:

<button id="HelpButton" label="Help" getVisible="EnableControl" onAction="HelpFile" /> 

完整的XML,供大家参考:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
    <customUI onLoad="RibbonOnLoad" xmlns="http://schemas.microsoft.com/office/2009/07/customui"> 
     <commands> 
      <command idMso="ViewSlideSorterView" getEnabled="EnableControl"/> 
      <command idMso="ViewNotesPageView" getEnabled="EnableControl"/> 
      <command idMso="ViewSlideShowReadingView" getEnabled="EnableControl"/> 
      <command idMso="ViewSlideMasterView" getEnabled="EnableControl"/> 
      <command idMso="ViewHandoutMasterView" getEnabled="EnableControl"/> 
      <command idMso="ViewNotesMasterView" getEnabled="EnableControl"/> 
      <command idMso="WindowNew" getEnabled="EnableControl"/> 
     </commands> 
     <ribbon startFromScratch="false"> 
      <tabs> 
       <tab idMso="TabView"> 
        <group idMso="GroupMasterViews" getVisible="VisibleGroup"/> 
        <group idMso="GroupPresentationViews" getVisible="VisibleGroup"/> 
       </tab> 
       <tab id="TabTiger" label="Chart Builder" insertAfterMso="TabDeveloper"> 
        <group id="GroupTigerMain" label="XXXX Chart Builder"> 
         <menu id="TigerMenu" image="XXXXLogo" size="large"> 
          <button id="LaunchButton" label="Launch Chart Builder" onAction="ShowChart_Form" /> 
          <button id="InfoButton" label="Info" onAction="Credit_Inf" /> 
          <button id="VersionButton" label="Version" onAction="VersionNum" /> 
          <button id="HelpButton" label="Help" getVisible="EnableControl" onAction="HelpFile" /> 
         </menu> 
        </group> 
       </tab> 
      </tabs> 
     </ribbon> 
    </customUI> 

EnableControl程序看起来像这样(我故意取消对MsgBox,这样我可以打破&输入代码,你可能想这样做只是为了调试并确保正确的布尔值被传递给控件):

Sub EnableControl(control As IRibbonControl, ByRef returnedVal) 
    returnedVal = Not TrapFlag 'TrapFlag = True indicates the Application is running. 
    MsgBox ("GetEnabled for " & control.Id) 
    'Debug.Print control.Id & " enabled = " & CStr(returnedVal) 
    Call RefreshRibbon(control.Id) 
End Sub 

您需要修改分配returnedVal以符合您的目的的逻辑。但基本上这个宏应该在每次时触发这个按钮即将被显示,所以在我的情况下,每当我打开包含它的菜单时它就会触发。

只要returnedVal的值为False之前的Call RefreshRibbon(control.Id)那么该过程就起作用,并且该按钮在我的菜单栏中不再可见。

+1

,我打算给getVisible回调添加到我的XML,像这样: <按钮ID =“BT1” getVisible =“ButtonVisible” 但我的色带停止显示,如果是畸形XML的。你不能在button标签中使用这个属性吗? – db579

+0

@ db579是否还在工作簿的VBProject中添加了“getVisible”子例程? (有点愚蠢的问题,但只是想确保你没有忽视明显的)另外,我注意到你在Group控件上使用了相同的'getVisible'自定义属性。在我的应用程序中,**我不能在不同类型的控件上使用相同的回调/宏** - 如果您在组控件(“group1”)上使用'getVisible',请尝试使用不同的回调(即使它是重复的代码)在按钮上。让我知道,我可以尝试在今晚晚些时候用一个按钮进行测试。 –

+1

是的,我没有添加相应的宏到项目中,我从组中删除了回调,所以不应该有任何冲突。我确实使用了获取可见回调的选项卡,但是我给这个宏指定了一些不同的东西(我认为getVisible =''位必须被调用才能工作? – db579

0

在Excel中我注意到,当如果(不开最小化窗口)工作簿可见您在WB嵌入丝带才会出现。 我玩过各种可见和不可见的选项,但是如果包含它的工作簿的窗口最小化,我无法让功能区保持不变。 解决方法是使用包含功能区的.xlam Addin。然后功能区在这里,无论您在Excel中打开的工作簿的状态如何。

+0

这是设计完成的:CustomUI功能区对于包含Ribbon XML标记的文件是本地的;这样,您的自定义功能区仅适用于特定文件。如您所见,如果将RibbonUI保存在XLAM文件中,它将对所有打开的工作簿都可见(或者,您可以添加条件逻辑以仅在符合用户定义的标准的工作簿中显示它)等。 –

相关问题