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

Vba 隐藏单个自定义功能区按钮,vba,excel,ribbon,Vba,Excel,Ribbon,我有一个自定义excel功能区和一个excel加载项,其中包含一个在打开工作簿时实例化的类。基于类的某些属性,我需要隐藏自定义功能区中的某些按钮(都在同一选项卡中) 我的自定义功能区是: <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="loadCustom"> <ribbon> <tabs> <tab id="tab1" label="custo

我有一个自定义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>

在功能区应该为其加载的特定工作簿中,我有一个隐藏的工作表,我的类模块类从中读取每个按钮的值,以确定它是否应该显示。读取此值后,如何隐藏单个按钮?我发现的所有示例似乎只适用于选项卡。我可以将ribbonUI传递给类并循环每个控件吗?我还没有找到一种方法来做这件事。谢谢你的帮助

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

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

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

例如,在我的PPT中,XML的一部分如下所示:

...
<tab idMso="TabView">
               <group idMso="GroupMasterViews" getVisible="VisibleGroup"/>
               <group idMso="GroupPresentationViews" getVisible="VisibleGroup"/>
           </tab>
           ...
完整的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>
您需要修改分配
returnedVal
的逻辑,以满足您的需要。但基本上,这个宏应该在每次显示按钮时触发,所以在我的例子中,每次打开包含它的菜单时它都会触发


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

在Excel中,我注意到嵌入WB的功能区只有在该工作簿可见时才会出现(打开的窗口未最小化)。 我使用了各种visible和getvisible选项,但如果包含功能区的工作簿窗口最小化,我无法使功能区保持不变。
解决方法是使用一个包含ribbon的.xlam加载项。然后,无论您在Excel中打开的工作簿的状态如何,ribbon都在这里。

我尝试向xml添加一个getVisible回调,如下所示:@db579您是否也在工作簿的VBProject中添加了一个
getVisible
子例程?(这是一个很愚蠢的问题,但只是想确保你没有忽略显而易见的问题)另外,我注意到你在组控件上使用了相同的
getVisible
自定义属性。在我的应用程序中,我不能在不同类型的控件上使用相同的回调/宏——如果你在组控件(“group1”)上使用
getVisible
,尝试使用其他回调(即使是重复代码)在按钮上。让我知道,今晚晚些时候我可以尝试用一个按钮来测试它。是的,我确实向项目中添加了相应的宏,并从组中删除了回调,因此那里不应该有任何冲突。我确实对选项卡使用了get visible回调,但我将宏命名为其他名称(我假设必须调用getVisible=''位才能工作?请参阅我上面的修订,我可以使用XML中的
getVisible
属性禁用/启用按钮。我将尝试使用其他宏,例如,您可以使用
getVisible=“EnabledControl”
然后尝试添加
EnabledControl
子例程。啊,我现在明白了-我没有从xml中删除可见属性。非常感谢您的帮助,非常感谢!这是出于设计:CustomUI功能区位于包含功能区xml标记的文件的本地;这样,您的自定义功能区仅在具体文件。如您所述,如果将RibbonUI保存在XLAM文件中,则所有打开的工作簿都可以看到它(或者,您可以添加条件逻辑以仅在满足某些用户定义条件的工作簿中显示它,等等)。
<button id="HelpButton" label="Help" getVisible="EnableControl" onAction="HelpFile" />
<?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>
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