学习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社群下载这本书的完整中文版电子书。
欢迎在下面留言,完善本文内容,让更多的人学到更完美的知识。