分享

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

 hercules028 2021-03-13

内置控件

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

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

图片

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

图片

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

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

图片

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

在标准VBA模块中的代码:












Public myRibbon As IRibbonUI 'Callback for customUI.onLoadSub Initialize(ribbon As IRibbonUI) Set myRibbon = ribbonEnd Sub 'Callback for Bold getEnabledSub getEnabledBU(control As IRibbonControl, ByRef returnedVal) returnedVal = ActiveSheet.Name ='Sheet1'End Sub

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

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










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

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

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

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

自定义控件

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

示例XML代码:

图片

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

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

在标准VBA模块中的代码:
































Public myRibbon As IRibbonUIPublic myID As String 'Callback for customUI.onLoadSub Initialize(ribbon As IRibbonUI) Set myRibbon = ribbonEnd Sub 'Callback for BtnInsert0 onActionSub Insert0(control As IRibbonControl) MsgBox 'Insert 0 被单击.'End Sub 'Callback for BtnInsert0 getEnabledSub GetEnabledAttnSh(control As IRibbonControl, ByRef returnedVal) If control.ID Like myID Then returnedVal = True Else returnedVal = False End IfEnd Sub 'Callback for BtnInsert1 onActionSub Insert1(control As IRibbonControl) MsgBox 'Insert 1 被单击.'End Sub 'Callback for BtnUpdateRed onActionSub UpdateRed(control As IRibbonControl) MsgBox 'Update Red 被单击.'End Sub

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
















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与参数值匹配,就启用该控件。否则,禁用该控件。












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模块中包括下面的事件处理代码:








Private Sub Workbook_SheetActivate(ByVal Sh As Object)    If TypeName(Sh) = 'Worksheet'Then        Call EnableAll    Else        Call DisableAll    End IfEnd Sub

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

图片

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

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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多