VBA专题10-21:使用VBA操控Excel界面之禁用和启用控件、组和选项卡

2021-03-26 17:05:24 浏览数 (1)

学习Excel技术,关注微信公众号:

excelperfect

内置控件

通过分别使用enabled属性和getEnabled属性,可以在设计时永久地或者在运行时动态地禁用(和启用)内置控件。被禁用的控件在功能区中显示的是灰色。

例如,下面的示例XML代码禁用“复制”、“剪切”、“加粗”和“下划线”控件:

下图显示了功能区中被禁用的“复制”、“剪切”、“加粗”和“下划线”控件已变成灰色:

虽然在功能区中被禁用的控件是灰色的,但你仍然可以通过快捷键组合执行它们中的一些命令。例如,按Ctrl C复制,按Ctrl X剪切,但是不会执行Ctrl B加粗和Ctrl U加下划线。

也可以设置自已的条件来在运行时决定是否禁用某个内置控件。例如,下面的XML代码和VBA代码能够在运行时满足某条件时使“加粗”和“下划线”控件禁用(和启用):

注意,两个command元素的getEnabled属性都引用相同的getEnabledBU过程,当打开工作簿或者其中一个或两个控件被无效时调用这个过程。

在标准VBA模块中的代码:

代码语言:javascript复制
Public myRibbon As IRibbonUI
 
'Callback for customUI.onLoad
Sub Initialize(ribbon As IRibbonUI)
    Set myRibbon = ribbon
End Sub
 
'Callback for Bold getEnabled
Sub getEnabledBU(control As IRibbonControl, ByRef returnedVal)
    returnedVal = ActiveSheet.Name ="Sheet1"
End Sub

在getEnabledBu过程中,如果活动工作表的名字是Sheet1则参数Enabled被设置为True。这使无效的控件启用。否则,这些控件被禁用。

在ThisWorkbook模块中的SheetActivate事件处理代码:

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

当激活不同的工作表时,SheetActivate事件处理使“加粗”和“下划线”控件无效。随后,调用相同的getEnabledBU过程,如果活动工作表的名字是Sheet1,那么两个控件都被启用,否则被禁用。

内置组和自定义组、内组选项卡和自定义选项卡(不允许)

不能够禁用控件和选项卡组,因为group和tab元素没有允许你这样做的enabled属性和getEnabled属性。

自定义控件

通过使用getEnabled属性禁用(和启用)自定义控件的方法与使用getVisible属性隐藏(和取消隐藏)自定义控件的方法相同。为了避免重复,这里介绍如何基于其ids禁用(和启用)某个自定义控件。

示例XML代码:

在Excel中打开该工作簿时,自动执行Initialize回调和GetEnabledAttnSh回调。

在Custom UI Editor中保存该文件,首次在Excel中打开该文件时,将会出现关于Initialize和GetEnabledAttnSh过程提示的错误消息,因为在标准的VBA模块中仍然没有这两个回调过程。单击“确定”关闭这些错误消息。

在标准VBA模块中的代码:

代码语言:javascript复制
Public myRibbon As IRibbonUI
Public myID As String
 
'Callback for customUI.onLoad
Sub Initialize(ribbon As IRibbonUI)
    Set myRibbon = ribbon
End Sub
 
'Callback for BtnInsert0 onAction
Sub Insert0(control As IRibbonControl)
    MsgBox "Insert 0 被单击."
End Sub
 
'Callback for BtnInsert0 getEnabled
Sub GetEnabledAttnSh(control As IRibbonControl, ByRef returnedVal)
    If control.ID Like myID Then
        returnedVal = True
    Else
        returnedVal = False
    End If
End Sub
 
'Callback for BtnInsert1 onAction
Sub Insert1(control As IRibbonControl)
    MsgBox "Insert 1 被单击."
End Sub
 
'Callback for BtnUpdateRed onAction
Sub UpdateRed(control As IRibbonControl)
    MsgBox "Update Red 被单击."
End Sub

要基于其在XML代码中的id禁用(和启用)某自定义控件,在现有的标准VBA模块或者新的标准VBA模块中包括下面的代码:

代码语言:javascript复制
Sub EnableAll()
    Call RefreshRibbon("*")
End Sub
 
Sub DisableAll()
    Call RefreshRibbon("")
End Sub
 
Sub EnableInsert()
    Call RefreshRibbon("*Insert*")
End Sub
 
Sub EnableInsert1()
    Call RefreshRibbon("*Insert1")
End Sub

执行上面的每个过程,看看效果。每个过程都调用RefreshRibbon过程来使所有的三个控件无效。参见下面的RefreshRibbon过程。是否启用(或禁用)某控件取决于在RefreshRibbon中参数传递的值。一旦使这些控件无效,就调用GetEnabledAttnSh过程,遍历共享这个相同回调的所有无效的控件。如果控件的id与参数值匹配,就启用该控件。否则,禁用该控件。

代码语言:javascript复制
Sub RefreshRibbon(ID As String)
    myID = ID
   
    'Invalidate all controls on the Ribbon
    'myRibbon.Invalidate
   
    'Alternatively,it is best to invalidateonly the three controls
    myRibbon.InvalidateControl "BtnInsert0"
    myRibbon.InvalidateControl "BtnInsert1"
    myRibbon.InvalidateControl "BtnUpdateRed"
End Sub

如果要在活动工作表是标准工作表时启用全部三个控件,在活动工作表不是标准工作表时禁用这三个控件,只需在ThisWorkbook模块中包括下面的事件处理代码:

代码语言:javascript复制
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
    If TypeName(Sh) = "Worksheet"Then
        Call EnableAll
    Else
        Call DisableAll
    End If
End Sub

下图展示了在执行EnableInsert过程后两个启用控件的Attn Sh组的情况:

同样,也可以基于tag属性而不是id属性来禁用(和启用)指定的自定义控件。

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

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

0 人点赞