我有一个自定义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传递给类并循环遍历每个控件吗?我一直无法找到这样做的方法。谢谢你的帮助!
答案 0 :(得分:5)
您需要在运行时自定义功能区。
检查我的问题(并回答)here虽然我的问题出现在PPT VBA中,但我在Excel中进行了测试,问题的解决方案应该非常相似。
不是将boolean true
或false
分配给每个按钮的visible
属性,而是需要另一个回调,以便在加载此选项卡时,该过程检查您的类对象已经实例化,然后根据需要设置true
或false
。
例如,在我的PPT中,我的XML部分就像:
...
<tab idMso="TabView">
<group idMso="GroupMasterViews" getVisible="VisibleGroup"/>
<group idMso="GroupPresentationViews" getVisible="VisibleGroup"/>
</tab>
...
因此,我使用自定义属性Visible
来调用宏getVisible
,而不是使用该组的VisibleGroup
属性。我遇到了一些细微差别,例如,我无法在不同的类型控件上使用相同的回调/宏,因此为什么我有两个回调(EnabledControl
和{{1两者都做完全相同的事情。我不知道为什么,不幸的是,这部分开发似乎没有很好的记录。
检查我的代码,看看我在测试时放置断点的所有地方。我不得不做很多调试才能让它工作。在每个过程中放置断点并逐步执行代码。这是一个痛苦的屁股,但如果你已经走到这一步,我相信你将能够使它工作。
更新
我对PPT加载项进行了简短的测试。在功能上这是类似的,所以我测试比尝试在Excel中重新创建所有内容更容易。
我的加载项有自己的菜单组和一些自定义按钮。相关的按钮行是这样的:
VisibleGroup
完整的XML供您参考:
<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>
例程看起来像这样(我故意取消注释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
,则该过程有效,并且我的菜单栏中的按钮不再可见。
答案 1 :(得分:0)
在Excel中我注意到,只有当此工作簿可见时(窗口打开未最小化),才会显示嵌入WB的功能区。 我玩过各种可见和可见的选项,但是如果包含它的工作簿的窗口被最小化,我就无法保持功能区。 解决方法是使用包含功能区的.xlam Addin。然后,无论您在Excel中打开的工作簿的状态如何,都会显示功能区。