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 传递给类并循环遍历每个控件吗?我一直找不到这样做的方法。谢谢你的帮助!

4

2 回答 2

6

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

在这里检查我的问题(和答案)虽然我的问题是在 PPT VBA 中,但我在 Excel 中进行了测试,您的问题的解决方案应该非常相似。

您不需要为每个按钮的属性分配布尔值true或,而是需要另一个回调,以便在加载此选项卡时,该过程检查您的类对象是否已实例化,然后根据需要设置或。falsevisibletruefalse

例如,在我的 XML 的 PPT 部分中是这样的:

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

因此,我没有使用组的属性,而是使用了一个调用宏Visible的自定义属性。我遇到了一些细微差别,例如,我不能在不同类型的控件上使用相同的回调/宏,因此我有两个回调 (和),它们的作用完全相同。我不知道为什么,不幸的是,这部分开发似乎没有很好的记录。getVisibleVisibleGroupEnabledControlVisibleGroup

检查我的代码以查看我在测试时放置断点的所有位置。我必须做很多调试才能让它工作。在每个过程中放置​​断点并逐步执行您的代码。这是一个痛苦的屁股,但如果你已经走到这一步,我相信你将能够让它发挥作用。

更新

我对我的 PPT Add-In 做了一个简短的测试。这在功能上是相似的,所以我测试比尝试在 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之前FalseCall RefreshRibbon(control.Id)那么程序就可以工作,并且该按钮在我的菜单栏中不再可见。

于 2013-08-04T14:27:09.163 回答
0

在 Excel 中,我注意到您嵌入 WB 的功能区仅在此工作簿可见时才会出现(打开的窗口未最小化)。我玩过各种可见和可见选项,但如果包含它的工作簿窗口最小化,我无法让功能区持续存在。解决方法是使用包含功能区的 .xlam 插件。无论您在 Excel 中打开的工作簿的状态如何,功能区都在这里。

于 2014-07-10T07:50:31.843 回答