隐藏单个自定义功能区按钮

baa*_*ger 4 excel vba ribbon excel-vba

我有一个自定义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>
Run Code Online (Sandbox Code Playgroud)

然后,我在模块中有以下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
Run Code Online (Sandbox Code Playgroud)

在我的特定工作簿中,功能区应该加载,我有一个隐藏的工作表,我的类模块类从中读取每个按钮的值,以确定它是否应该显示.一旦我读到这个值,我怎么能隐藏一个单独的按钮?我发现的所有示例似乎只适用于标签.我可以将ribbonUI传递给类并循环遍历每个控件吗?我一直无法找到这样做的方法.谢谢你的帮助!

Dav*_*ens 5

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

检查我的问题(和答案),在这里,虽然我的问题是在PPT VBA,我做我的测试在Excel和解决你的问题应该是非常相似的.

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

例如,在我的PPT中,我的XML部分就像:

...
<tab idMso="TabView">
               <group idMso="GroupMasterViews" getVisible="VisibleGroup"/>
               <group idMso="GroupPresentationViews" getVisible="VisibleGroup"/>
           </tab>
           ...
Run Code Online (Sandbox Code Playgroud)

因此Visible,我使用getVisible调用宏的自定义属性,而不是使用组的属性VisibleGroup.我遇到了一些细微差别,比如,我不能在不同类型的控件上使用相同的回调/宏,因此为什么我有两个回调(EnabledControlVisibleGroup)两者都完全相同.我不知道为什么,遗憾的是,这部分开发似乎没有得到很好的记录.

检查我的代码,看看我在测试时放置断点的所有地方.我不得不做很多调试才能让它工作.在每个过程中放置断点并逐步执行代码.这是一个痛苦的屁股,但如果你已经走到这一步,我相信你将能够使它工作.

UPDATE

我对我的PPT加载项做了一个简短的测试.在功能上这是类似的,所以我测试比尝试在Excel中重新创建所有内容更容易.

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

<button id="HelpButton" label="Help" getVisible="EnableControl" onAction="HelpFile" />
Run Code Online (Sandbox Code Playgroud)

完整的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>
Run Code Online (Sandbox Code Playgroud)

EnableControl程序看起来像这样(我故意取消注释MsgBox,这样我可以打破与输入代码,您可能希望这样做只是为了调试,并确保适当的布尔VAL被传递到控制):

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
Run Code Online (Sandbox Code Playgroud)

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

只要值returnedValFalse在之前Call RefreshRibbon(control.Id)那么程序的工作原理和按钮不再可见在我的菜单栏.