VBA专题10-20:使用VBA操控Excel界面之隐藏和取消隐藏控件、组和选项卡
excelperfect
内置控件(不被允许)
不能够单独隐藏内置组中的内置控件。然而,可以隐藏内置组,因此会隐藏该组中的所有控件。可以单独禁用(和启用)组中的控件。
下表中的command元素的可用属性说明了为什么不能够隐藏但可以单独禁用(和启用)内置控件。另一方面,group和tab元素的可用属性说明了为什么可以隐藏(和取消隐藏)但不能够禁用组和选项卡。
上面的表也展示了通用理念,一些属性(enabled,label,visible …)可以在设计时设置它们的值,一些属性(getEnabled,getLabel, getVisible …,称作回调属性)可以在启动(当Excel开启时)动态设置值,可以在运行时改变它们的值(在使元素无效后通过使用VBA回调过程)。
内置控件组
通过使用visible属性,可以在设计时永久隐藏控件组。或者,可以通过使用getVisible回调属性动态地隐藏(和取消隐藏)它们。visible是设计时属性,而getVisible是运行时属性。
例如,下面的示例XML代码永久隐藏“开始”选项卡中的“字体”组和“对齐方式”组:
隐藏“字体”组和“对齐方式”组后的“开始”选项卡如下图所示:
虽然隐藏了组中的控件,但是仍然可以通过快捷键组合和上下文菜单执行它们底层的命令,例如,选择工作表单元格,按下Ctrl+B将使单元格内容加粗,右击单元格将显示“单元格”上下文菜单和Mini工具栏。
正如本文开头提到的,也可以在满足某条件时在运行时动态地隐藏(和取消隐藏)内置组。这样的例子包括:选择了图表工作表、选择了特定的工作表、从组合框中选择了特定项、以及勾选了网格线复选框。
例如,下面的示例XML代码和在标准VBA模块中的代码在运行时满足某条件时隐藏(和取消隐藏)“对齐方式”组:
customUI元素包括带有Initialize回调过程的onLoad属性。当打开工作簿时执行该回调。
GroupAlignmentExcel组元素包括getVisible属性。通过该属性指向HideAlignmentGroup过程,在打开工作簿或使该控件无效时执行。在该过程中评估是否隐藏或取消隐藏组的条件。
在Custom UI Editor中保存该文件,首次在Excel中打开时,会出现关于Initialize和HideAlignmentGroup过程的错误消息提示,因为这两个过程仍然没有在标准的VBA模块中找到,单击“确定”关闭错误消息。
打开VBE,在标准VBA模块中的代码如下:
Public myRibbon As IRibbonUI
'Callback for customUI.onLoad
Sub Initialize(ribbon As IRibbonUI)
Set myRibbon = ribbon
End Sub
'Callback for GroupAlignmentExcel getVisible
Sub HideAlignmentGroup(control As IRibbonControl, ByRef returnedVal)
returnedVal = TypeName(ActiveSheet) ='Worksheet'
End Sub
在HideAlignmentGroup过程中,如果活动工作表是标准工作表,那么returnedVal参数设置为True,结果是“文本对齐”组可见。如果returnedVal参数设置为False,那么该组被隐藏。
在ThisWorkbook模块的SheetActivate事件处理中的代码:
Private Sub Workbook_SheetActivate(ByVal Sh As Object) '在Excel 2010及以后版本,使用下面的代码语句: myRibbon.InvalidateControlMso 'GroupAlignmentExcel' '由于Excel 2007没有InvalidateControlMso方法 '使用下面的语句使功能区无效 'myRibbon.InvalidateEnd Sub
当激活不同的工作表时,执行SheetActivate事件处理。在Excel 2010及之后的版本中,InvalidateControlMso方法仅使“对齐方式”组无效。在Excel 2007中,Invalidate方法使功能区无效。随后,调用HideAlignmentGroup过程。如果活动工作表不是标准工作表,就隐藏该组,否则该组可见。
注意,当打开工作簿时,创建ribbon对象。编辑VBA代码可能销毁这个新创建的对象。试图使与销毁对象相关的控件无效是不可能的,唯一的办法是重新创建ribbon对象重新打开该工作簿。
当激活图表工作表时,“开始”选项卡中的“对齐方式”组被隐藏,如下图所示:
事实上,可以只是使用一个回调过程来隐藏多个组。这种只使用一个回调的思想可以被扩展到选项卡和控件,稍后我们会谈到这方面的内容。
内置选项卡
例如,下面的示例XML代码隐藏“开始”和“数据”选项卡:
隐藏“开始”和“数据”选项卡的功能区如下图所示:
虽然选项卡中的控件被隐藏,但仍然可以通过快捷键组合和上下文菜单执行它们底层的命令。例如,选择非空工作表单元格,按Alt+D+S将显示“排序”对话框,按Ctrl+H显示“查找和替换”对话框,右击单元格将显示单元格上下文菜单和Mini工具栏。
与隐藏(和取消隐藏)内置组相似,可以在运行时当满足某条件时动态地隐藏(和取消隐藏)内置选项卡。例如,运行时当满足某条件时,下面的示例XML代码和VBA代码可以隐藏(和取消隐藏)“开始”选项卡:
在标准VBA模块中的代码:
Public myRibbon As IRibbonUI
'Callback for customUI.onLoad
Sub onLoad(ribbon As IRibbonUI)
Set myRibbon = ribbon
End Sub
'Callback for TabHomegetVisible
Sub HideHomeTab(control As IRibbonControl, ByRef returnedVal)
returnedVal = TypeName(ActiveSheet) ='Worksheet'
End Sub
当调用HideHomeTab过程时,如果活动工作表不是标准工作表,那么隐藏“开始”选项卡,否则使“开始”选项卡可见。
在ThisWorkbook模块中的SheetActivate事件处理代码:
Private Sub Workbook_SheetActivate(ByVal Sh As Object) '在Excel 2010 及其后的版本中,使用下面的代码语句: myRibbon.InvalidateControlMso 'TabHome' '由于Excel 2007没有InvalidateControlMso方法, '使用下面的语句使Ribbon无效: 'myRibbon.InvalidateEnd Sub
当激活不同的工作表时,执行SheetActivate事件处理。在Excel 2010及之后的版本中,InvalidateControlMso方法仅使“开始”选项卡无效——仅仅是该选项卡被无效,在“开始”选项卡中的控件实际上没有被无效。在Excel 2007中,Invalidate方法使功能区中所有的控件无效。随后,调用HideHomeTab过程。如果活动工作表不是标准工作表,就隐藏“开始”选项卡,否则该选项卡可见。
所有内置选项卡
示例XML代码:
功能区的所有选项卡都被隐藏,如下图所示:
虽然所有的内置选项卡都被隐藏,但仍然可以通过快捷键组合、上下文菜单和上下文选项卡访问内置控件。例如,按Alt+I+S将显示“符号”对话框,按Alt+F1将插入一个空的嵌入式图表并显示“图表工具”上下文选项卡,右击工作表单元格将显示单元格上下文菜单和Mini工具栏。
自定义控件
不能够单独隐藏内置控件,但可以单独隐藏自定义控件。可以在设计时永久地或者在运行时动态地隐藏(和取消隐藏)自定义控件。然而,动态地隐藏(和取消隐藏)控件更可取,可以设置自已的条件来是否使控件隐藏。
例如,下面的示例XML代码在“开始”选项卡中的“字体”组前添加3个按钮:
注意,两个按钮的getVisible属性都使用了相同的getVisibleBtnBC回调过程。当打开工作簿或者当其中一个或两个控件被无效时执行该回调。
在标准VBA模块中的VBA代码:
Public myRibbon As IRibbonUI
'Callback for customUI.onLoad
Sub Initialize(ribbon As IRibbonUI)
Set myRibbon = ribbon
End Sub
'Callback for BtnB getVisible
Sub getVisibleBtnBC(control As IRibbonControl,ByRef returnedVal)
returnedVal = ActiveSheet.Name ='Sheet1'
End Sub
当调用getVisibleBtnBC过程时,如果活动工作表的名称是Sheet1,那么使BtnB和BtnC按钮可见,否则这两个按钮隐藏。
在ThisWorkbook模块中的SheetActivate事件处理代码:
Private Sub Workbook_SheetActivate(ByVal Sh As Object) myRibbon.InvalidateControl 'BtnB' myRibbon.InvalidateControl 'BtnC'End Sub
当激活不同的工作表时,执行SheetActivate事件处理,使BtnB和BtnC按钮无效。随后,调用相同的getVisibleBtnBC过程,遍历所有无效的控件(本例中,是两个按钮),它们的getVisible属性使用相同的getVisibleBtnBC过程。如果活动单元格的名称是Sheet1,那么这两个按钮可见,否则被隐藏。
自定义组和选项卡
隐藏(和取消隐藏)自定义组和选项卡的方法与隐藏(和取消隐藏)内置组和选项卡的方法相同。下面展示了一个示例,当活动工作表不是标准工作表时隐藏自定义选项卡。
示例XML代码:
在标准VBA模块中的VBA代码:
Public myRibbon As IRibbonUI
'Callback for customUI.onLoad
Sub Initialize(ribbon AsIRibbonUI)
Set myRibbon = ribbon
End Sub
'Callback for customTabgetVisible
Sub HideCustomTab(control As IRibbonControl, ByRef returnedVal)
returnedVal = TypeName(ActiveSheet) ='Worksheet'
End Sub
在ThisWorkbook模块中的SheetActivate事件处理代码:
Private Sub Workbook_SheetActivate(ByVal Sh As Object) myRibbon.InvalidateControl 'CustomTab'End Sub
说明:本专题系列大部分内容学习整理自《Dissectand Learn Excel VBA in 24 Hours:Changingworkbook appearance》,仅供学习研究。注:如果你有兴趣,你可以到知识星球App的完美Excel社群下载这本书的完整中文版电子书。