VBA专题10-20:使用VBA操控Excel界面之隐藏和取消隐藏控件、组和选项卡

2021-03-12 17:02:59 浏览数 (1)

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模块中的代码如下:

代码语言:javascript复制
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事件处理中的代码:

代码语言:javascript复制
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
    '在Excel 2010及以后版本,使用下面的代码语句:
    myRibbon.InvalidateControlMso "GroupAlignmentExcel"
 
    '由于Excel 2007没有InvalidateControlMso方法
    '使用下面的语句使功能区无效
    'myRibbon.Invalidate
End Sub

当激活不同的工作表时,执行SheetActivate事件处理。在Excel 2010及之后的版本中,InvalidateControlMso方法仅使“对齐方式”组无效。在Excel 2007中,Invalidate方法使功能区无效。随后,调用HideAlignmentGroup过程。如果活动工作表不是标准工作表,就隐藏该组,否则该组可见。

注意,当打开工作簿时,创建ribbon对象。编辑VBA代码可能销毁这个新创建的对象。试图使与销毁对象相关的控件无效是不可能的,唯一的办法是重新创建ribbon对象重新打开该工作簿。

当激活图表工作表时,“开始”选项卡中的“对齐方式”组被隐藏,如下图所示:

事实上,可以只是使用一个回调过程来隐藏多个组。这种只使用一个回调的思想可以被扩展到选项卡和控件,稍后我们会谈到这方面的内容。

内置选项卡

例如,下面的示例XML代码隐藏“开始”和“数据”选项卡:

隐藏“开始”和“数据”选项卡的功能区如下图所示:

虽然选项卡中的控件被隐藏,但仍然可以通过快捷键组合和上下文菜单执行它们底层的命令。例如,选择非空工作表单元格,按Alt D S将显示“排序”对话框,按Ctrl H显示“查找和替换”对话框,右击单元格将显示单元格上下文菜单和Mini工具栏。

与隐藏(和取消隐藏)内置组相似,可以在运行时当满足某条件时动态地隐藏(和取消隐藏)内置选项卡。例如,运行时当满足某条件时,下面的示例XML代码和VBA代码可以隐藏(和取消隐藏)“开始”选项卡:

在标准VBA模块中的代码:

代码语言:javascript复制
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事件处理代码:

代码语言:javascript复制
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
    '在Excel 2010 及其后的版本中,使用下面的代码语句:
    myRibbon.InvalidateControlMso "TabHome"
   
    '由于Excel 2007没有InvalidateControlMso方法,
    '使用下面的语句使Ribbon无效:
    'myRibbon.Invalidate
End Sub

当激活不同的工作表时,执行SheetActivate事件处理。在Excel 2010及之后的版本中,InvalidateControlMso方法仅使“开始”选项卡无效——仅仅是该选项卡被无效,在“开始”选项卡中的控件实际上没有被无效。在Excel 2007中,Invalidate方法使功能区中所有的控件无效。随后,调用HideHomeTab过程。如果活动工作表不是标准工作表,就隐藏“开始”选项卡,否则该选项卡可见。

所有内置选项卡

示例XML代码:

功能区的所有选项卡都被隐藏,如下图所示:

虽然所有的内置选项卡都被隐藏,但仍然可以通过快捷键组合、上下文菜单和上下文选项卡访问内置控件。例如,按Alt I S将显示“符号”对话框,按Alt F1将插入一个空的嵌入式图表并显示“图表工具”上下文选项卡,右击工作表单元格将显示单元格上下文菜单和Mini工具栏。

自定义控件

不能够单独隐藏内置控件,但可以单独隐藏自定义控件。可以在设计时永久地或者在运行时动态地隐藏(和取消隐藏)自定义控件。然而,动态地隐藏(和取消隐藏)控件更可取,可以设置自已的条件来是否使控件隐藏。

例如,下面的示例XML代码在“开始”选项卡中的“字体”组前添加3个按钮:

注意,两个按钮的getVisible属性都使用了相同的getVisibleBtnBC回调过程。当打开工作簿或者当其中一个或两个控件被无效时执行该回调。

在标准VBA模块中的VBA代码:

代码语言:javascript复制
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事件处理代码:

代码语言:javascript复制
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代码:

代码语言:javascript复制
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事件处理代码:

代码语言:javascript复制
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
    myRibbon.InvalidateControl "CustomTab"
End Sub

说明:本专题系列大部分内容学习整理自《Dissectand Learn Excel VBA in 24 Hours:Changingworkbook appearance》,仅供学习研究。注:如果你有兴趣,你可以到知识星球App的完美Excel社群下载这本书的完整中文版电子书。

欢迎在下面留言,完善本文内容,让更多的人学到更完美的知识。

0 人点赞