本类文章的标签为 ‘CommandBars集合’


创建自定义工具栏示例

1 颗星2 颗星3 颗星4 颗星5 颗星 (目前还没有人投票)
Loading ... Loading ...

在《RibbonX: Customizing the Office 2007 Ribbon》的第1章,介绍了一个在Excel 2003及以前版本中定制工具栏的很好的示例,现辑录于此,与大家分享。
首先,在VBE中,插入一个类模块,并命名为clsEvents,输入下面的代码:

'声明应用程序事件
Public WithEvents appXL As Application
Public WithEvents drop As Office.CommandBarComboBox
 
Private Sub appXL_SheetActivate(ByVal Sh As Object)
    Dim ws As Worksheet
    Dim Wb As Workbook
    Dim i  As Long
 
    On Error GoTo Err_Handler
    Set Wb = ActiveWorkbook
    If Not Wb.Name = ThisWorkbook.Name Then Exit Sub
    '初始化复选框
    Set g_cmdbarcboBox = g_cmdBar.FindControl(Type:=msoControlDropdown, Tag:="MyList")
        g_cmdbarcboBox.Clear
    '添加复选框项目,即工作表名称
    For Each ws In Sh.Parent.Sheets
        g_cmdbarcboBox.AddItem ws.Name
    Next
    For i = 1 To g_cmdbarcboBox.ListCount
        If g_cmdbarcboBox.List(i) = Sh.Name Then g_cmdbarcboBox.ListIndex = i: Exit For
    Next
    Call drop_Change(g_cmdbarcboBox)
    Exit Sub
Err_Handler:
    ErrHandle Err
End Sub
 
Private Sub appXL_WorkbookActivate(ByVal Wb As Workbook)
    Set g_cmdbarcboBox = g_cmdBar.FindControl(Type:=msoControlDropdown, Tag:="MyList")
    If Wb.Name = ThisWorkbook.Name Then
        g_cmdbarcboBox.Enabled = True
        appXL_SheetActivate Wb.ActiveSheet
    Else:
        Call deleleteControls
        g_cmdbarcboBox.Enabled = False
    End If
    Exit Sub
Err_Handler:
    ErrHandle Err
End Sub
 
Public Sub setDrop(box As Office.CommandBarComboBox)
    '设置复选框对象
    Set drop = box
End Sub
 
 
Private Sub drop_Change(ByVal Ctrl As Office.CommandBarComboBox)
    '如果选择的复选框文本为工作表名称,则创建相应的菜单
    Select Case UCase(Ctrl.Text)
        Case "SUPPLIERS"
            Call setMNUSUPPLIERS
        Case "CUSTOMERS"
            Call setMNUCUSTOMERS
        Case "ACCOUNTS"
            Call setMNUACCOUNTS
        Case Else
            Call deleleteControls
    End Select
End Sub

然后,添加标准模块,输入下面的代码:

'声明全局变量
Public Const gcstrCMDBARNAME    As String = "DYNAMIC MENU"
Public Const gcstrMNUSUPPLIERS  As String = "Suppliers"
Public Const gcstrMNUCUSTOMERS  As String = "Customers"
Public Const gcstrMNUACCOUNTS   As String = "Accounts"
 
Public g_cmdBar                 As CommandBar
Public g_cmdbarMenu             As CommandBarPopup
Public g_cmdbarBtn              As CommandBarButton
Public g_cmdbarcboBox           As CommandBarComboBox
Public gcls_appExcel            As New clsEvents
Public gcls_cboBox              As New clsEvents
 
Sub wsBuildMenus()
    Call wsDeleteMenus
    On Error GoTo Err_Handler
    '添加工具栏,并设置尺寸
    Set g_cmdBar = CommandBars.Add(gcstrCMDBARNAME, msoBarFloating)
        g_cmdBar.Width = 150
    '添加复选框
    Set g_cmdbarcboBox = g_cmdBar.Controls.Add(Type:=msoControlDropdown)
    '设置复选框标签以便程序中识别
    '设置复选框操作过程
    With g_cmdbarcboBox
        .Tag = "MyList"
        .OnAction = "selectedSheet"
        .Width = 150
    End With
    '添加帮助按钮
    Set g_cmdbarBtn = g_cmdBar.Controls.Add(Type:=msoControlButton)
    With g_cmdbarBtn
        .Caption = "帮助"
        .OnAction = "runHelp"
        .Style = msoButtonIconAndCaption
        .FaceId = 984
    End With
    '设置应用程序级事件并传递复选框对象
    Set gcls_appExcel.appXL = Application
    gcls_cboBox.setDrop g_cmdbarcboBox
    With g_cmdBar
        .Visible = True
        .Protection = msoBarNoChangeDock + msoBarNoResize
    End With
    Exit Sub
Err_Handler:
    ErrHandle Err
End Sub
 
'删除菜单工具栏
Sub wsDeleteMenus()
    On Error Resume Next
    Application.CommandBars(gcstrCMDBARNAME).Delete
    Set g_cmdBar = Nothing
    Set g_cmdbarMenu = Nothing
    Set g_cmdbarBtn = Nothing
    Set g_cmdbarcboBox = Nothing
    Set gcls_appExcel = Nothing
    Set gcls_cboBox = Nothing
End Sub
 
'删除工具栏中的菜单项
Sub deleleteControls()
    On Error Resume Next
    g_cmdBar.Controls(gcstrMNUACCOUNTS).Delete
    g_cmdBar.Controls(gcstrMNUCUSTOMERS).Delete
    g_cmdBar.Controls(gcstrMNUSUPPLIERS).Delete
End Sub
 
'设置复选框中选中项目后的操作,即激活与项目名称相同的工作表
Sub selectedSheet()
    Dim g_cmdbarcboBox As CommandBarComboBox
    On Error Resume Next
    Set g_cmdbarcboBox = CommandBars.FindControl(Type:=msoControlDropdown, Tag:="MyList")
    ActiveWorkbook.Sheets(g_cmdbarcboBox.Text).Activate
End Sub
 
'设置选择相应工作表后,出现在工具栏中的菜单
Sub setMNUACCOUNTS()
    Call deleleteControls
    On Error GoTo Err_Handler
    Set g_cmdbarMenu = g_cmdBar.Controls.Add(Type:=msoControlPopup, BEFORE:=2)
    g_cmdbarMenu.Caption = gcstrMNUACCOUNTS
    Set g_cmdbarBtn = g_cmdbarMenu.Controls.Add(Type:=msoControlButton)
    g_cmdbarBtn.Caption = "New Account"
    Set g_cmdbarBtn = g_cmdbarMenu.Controls.Add(Type:=msoControlButton)
    g_cmdbarBtn.Caption = "Delete account"
    Exit Sub
Err_Handler:
    ErrHandle Err
End Sub
 
Sub setMNUSUPPLIERS()
    Call deleleteControls
    On Error GoTo Err_Handler
    Set g_cmdbarMenu = g_cmdBar.Controls.Add(Type:=msoControlPopup, BEFORE:=2)
    g_cmdbarMenu.Caption = gcstrMNUSUPPLIERS
    Set g_cmdbarBtn = g_cmdbarMenu.Controls.Add(Type:=msoControlButton)
    g_cmdbarBtn.Caption = "New Supplier"
    Set g_cmdbarBtn = g_cmdbarMenu.Controls.Add(Type:=msoControlButton)
    g_cmdbarBtn.Caption = "Current data"
    Exit Sub
Err_Handler:
    ErrHandle Err
End Sub
 
Sub setMNUCUSTOMERS()
    Call deleleteControls
    On Error GoTo Err_Handler
    Set g_cmdbarMenu = g_cmdBar.Controls.Add(Type:=msoControlPopup, BEFORE:=2)
    g_cmdbarMenu.Caption = gcstrMNUCUSTOMERS
    Set g_cmdbarBtn = g_cmdbarMenu.Controls.Add(Type:=msoControlButton)
    g_cmdbarBtn.Caption = "New Customer"
    Set g_cmdbarBtn = g_cmdbarMenu.Controls.Add(Type:=msoControlButton)
    g_cmdbarBtn.Caption = "Outstanding parts"
    Exit Sub
Err_Handler:
    ErrHandle Err
End Sub
 
Sub ErrHandle(ByVal objError As ErrObject)
    MsgBox objError.Description, vbCritical, objError.Number
    Call wsDeleteMenus
End Sub
 
Sub runHelp()
    ActiveWorkbook.FollowHyperlink "http://www.excelperfect.com", NewWindow:=True, AddHistory:=True
End Sub

最后,编写ThisWorkbook模块代码,以便在工作簿打开时执行创建工具栏的操作,在工作簿关闭时删除自定义工具栏。

Private Sub Workbook_Open()
    Call wsBuildMenus
End Sub
 
Private Sub Workbook_BeforeClose(Cancel As Boolean)
    Call wsDeleteMenus
End Sub

至此,代码全部编写完成。保存后,关闭该工作簿。再重新打开工作簿,如果没有选择与创建工具栏菜单名称相同的工作表,则会出现下面的工具栏:
custommenustyle1
如果选择的复选框项目与创建工具栏菜单的工作表名相同,则会出现下面的工具栏:
custommenustyle2

相关文章

表驱动的方式构建自定义命令栏(示例2)

1 颗星2 颗星3 颗星4 颗星5 颗星 (目前还没有人投票)
Loading ... Loading ...

下面是John Walkenbach介绍的创建自定义菜单的技巧,辑录于此。
Excel 97-2003使用CommandBars对象来构建菜单,必须使用VBA创建特定工作簿的菜单,下面的技巧介绍了一种创建自定义菜单的相对简单的方法。当特定的工作簿打开时,出现自定义菜单;当关闭该工作簿时,删除自定义菜单。
示例中,包含了用于创建自定义菜单的所有VBA代码,在大多数情况下,不需要修改这些代码,而只需要简单地修改MenuSheet工作表。
注意,这里介绍的技术只是新建菜单,而不会在已有的菜单中添加菜单项。
MenuSheet工作表
这项技术使用了一个Excel工作表,这里将其命名为MenuSheet。要创建自定义菜单,只需简单地修改表中的数据。MenuSheet工作表如下图所示。
makemenu1
工作表MenuSheet包含5列:

  • 菜单层级:特定项目的层级。有效值为1、2、3。层级1代表菜单;2代表菜单项;3代表子菜单项。通常,有一个层级1的项目,在它下面是层级2的项目。层级2的项目可以有也可以没有层级3的项目(子菜单)。
  • 标题:菜单、菜单项或子菜单显示的文本。使用符号(&)指定带下划线的字符,即快捷键。
  • 位置/宏:对于层级1的项目,应该是一个表示在菜单栏中位置的整数。对于层级2或层级3的项目,应该是选择该项目时执行的宏的名称。如果层级2的项目有一个或多个层级3的项目,那么层级2的项目可能没有与之相关的宏。
  • 分隔线:如果为True,则在该菜单项或子菜单项之前应该放置一条分隔线。
  • FaceID:可选的。代表显示在菜单项旁边的内置图像的编号。

菜单示例
使用上图所示表所创建的菜单如下图:
makemenu2
代码清单

Sub CreateMenu()
'   打开工作簿时执行本过程
'   注: 在本过程中没有编写错误处理的代码

    Dim MenuSheet As Worksheet
    Dim MenuObject As CommandBarPopup
 
    Dim MenuItem As Object
    Dim SubMenuItem As CommandBarButton
    Dim Row As Integer
    Dim MenuLevel, NextLevel, PositionOrMacro, Caption, Divider, FaceId
 
''''''''''''''''''''''''''''''''''''''''''''''''''''
'   菜单数据所在的工作表
    Set MenuSheet = ThisWorkbook.Sheets("MenuSheet")
''''''''''''''''''''''''''''''''''''''''''''''''''''

'   确保不会出现重复菜单
    Call DeleteMenu
 
'   初始化行计数器
    Row = 2
 
'   使用存储在MenuSheet工作表中的数据添加菜单,菜单项和子菜单项
    Do Until IsEmpty(MenuSheet.Cells(Row, 1))
        With MenuSheet
            MenuLevel = .Cells(Row, 1)
            Caption = .Cells(Row, 2)
            PositionOrMacro = .Cells(Row, 3)
            Divider = .Cells(Row, 4)
            FaceId = .Cells(Row, 5)
            NextLevel = .Cells(Row + 1, 1)
        End With
 
        Select Case MenuLevel
            Case 1 ' 代表菜单
'              在工作表命令栏中添加顶级菜单
                Set MenuObject = Application.CommandBars(1). _
                    Controls.Add(Type:=msoControlPopup, _
                    Before:=PositionOrMacro, _
                    Temporary:=True)
                MenuObject.Caption = Caption
 
            Case 2 ' 代表菜单项
                If NextLevel = 3 Then
                    Set MenuItem = MenuObject.Controls.Add(Type:=msoControlPopup)
                Else
                    Set MenuItem = MenuObject.Controls.Add(Type:=msoControlButton)
                    MenuItem.OnAction = PositionOrMacro
                End If
                MenuItem.Caption = Caption
                If FaceId <> "" Then MenuItem.FaceId = FaceId
                If Divider Then MenuItem.BeginGroup = True
 
            Case 3 ' 代表子菜单项
                Set SubMenuItem = MenuItem.Controls.Add(Type:=msoControlButton)
                SubMenuItem.Caption = Caption
                SubMenuItem.OnAction = PositionOrMacro
                If FaceId <> "" Then SubMenuItem.FaceId = FaceId
                If Divider Then SubMenuItem.BeginGroup = True
        End Select
        Row = Row + 1
    Loop
End Sub
 
Sub DeleteMenu()
'   关闭工作簿时执行本过程
'   删除创建的菜单
    Dim MenuSheet As Worksheet
    Dim Row As Integer
    Dim Caption As String
 
    On Error Resume Next
    Set MenuSheet = ThisWorkbook.Sheets("MenuSheet")
    Row = 2
    Do Until IsEmpty(MenuSheet.Cells(Row, 1))
        If MenuSheet.Cells(Row, 1) = 1 Then
            Caption = MenuSheet.Cells(Row, 2)
            Application.CommandBars(1).Controls(Caption).Delete
        End If
        Row = Row + 1
    Loop
    On Error GoTo 0
End Sub
 
Sub DummyMacro()
    MsgBox "这里一个用于演示的宏."
End Sub

代码简要解释

  • CommandBars(1)引用“工作表菜单栏”,也可以通过名称“Worksheet Menu Bar”来引用,其中1代表“工作表菜单栏”在CommandBars集合中的索引。
  • CommandBars集合是所有CommandBar对象的集合,而每个CommandBar对象都有一个 Controls集合。
  • Add方法向Controls集合中添加新控件。参数Type为msoControlPopup时,指定控件类型为弹出式控件;参数Before指定所添加的控件的位置;参数Temporary设置为True,表示为临时命令栏。
  • FaceID属性确写出现在菜单文本旁的图像,其中的数字代表内置图像编号。
  • BeginGroup属性设置为True时,将在该菜单项前放置分隔条。

技术运用
按下列步骤在工作簿或加载项中使用这项技术:
1、在VBE中插入一个标准模块,将上述代码复制到该模块中。
2、在ThisWorkbook模块中,编写下列代码:

Private Sub Workbook_Open()
    Call CreateMenu
End Sub
 
Private Sub Workbook_BeforeClose(Cancel As Boolean)
    Call DeleteMenu
End Sub

在工作簿打开时执行Workbook_Open事件,在工作簿关闭时执行Workbook_BeforeClose事件。
3、在工作簿中插入一个新工作表并命名为MenuSheet。按上图所示的格式输入菜单数据,或者直接复制上述数据后,再进行修改。

相关文章

表驱动的方式构建自定义命令栏

1 颗星2 颗星3 颗星4 颗星5 颗星 (目前还没有人投票)
Loading ... Loading ...

在Excel中采用表驱动(table-driven)的方式创建自定义命令栏是一种常用的技术。即在工作表中设置适当的数据,然后利用这些数据来创建菜单,这样既简单又方便。而且,不懂VBA编程的用户也能通过修改工作表中的数据来创建自已的命令栏。
这里介绍一个相对简单的例子,来自于《Mastering Excel 2003 Programming with VBA》。在下图所示的工作表中放置用来创建菜单的数据:
menubuilder1
现在,需要使用程序来运用Menu Builder工作表来构建适当的菜单,除了ParentTag列(即A列)外,其他列为CommandBarControl对象的不同属性。ParentTag列用来指定是否创建一个新的菜单、菜单项或子菜单。
创建的菜单如下图。
menubuilder2
代码如下:

Const NA = "N/A"
'列偏移量
Const TAG_OFFSET = 1
Const CAPTION_OFFSET = 2
Const TYPE_OFFSET = 3
Const ONACTION_OFFSET = 4
Const BEGINGROUP_OFFSET = 5
Const DESCRIPTION_OFFSET = 6
 
Sub BuildMenu()
  Dim ws As Worksheet
  Dim rg As Range
  On Error GoTo ErrHandler
  Set ws = ThisWorkbook.Worksheets("Menu Builder")
  '从第二行开始,因为第一行已经包含了列标题
  Set rg = ws.Cells(2, 1)
  Do Until IsEmpty(rg)
      If rg.Value = NA Then
      '新建顶级菜单项
          AddTopLevelItem rg
      Else
          '现有控件的子菜单
          AddSubItem rg
      End If
      '向下移一行
      Set rg = rg.Offset(1, 0)
  Loop
ExitPoint:
  Set rg = Nothing
  Set ws = Nothing
  Exit Sub
ErrHandler:
  Debug.Print Err.Description
  Resume ExitPoint
End Sub
 
'向工作表菜单栏中添加新菜单项
Private Function AddTopLevelItem(rg As Range) As CommandBarControl
  Dim cbWSMenuBar As CommandBar
  Dim cbc As CommandBarControl
  On Error GoTo ErrHandler
  Set cbWSMenuBar = Application.CommandBars("Worksheet Menu Bar")
  '添加菜单项
  Set cbc = cbWSMenuBar.Controls.Add(msoControlPopup, , , , True)
  cbc.Tag = rg.Offset(0, TAG_OFFSET).Value
  cbc.DescriptionText = rg.Offset(0, DESCRIPTION_OFFSET).Value
  cbc.Caption = rg.Offset(0, CAPTION_OFFSET).Value
  '返回新添加的菜单项
  Set AddTopLevelItem = cbc
ExitPoint:
  Set cbc = Nothing
  Set cbWSMenuBar = Nothing
  Exit Function
ErrHandler:
  Set AddTopLevelItem = Nothing
  Resume ExitPoint
End Function
 
Private Function AddSubItem(rg As Range) As CommandBarControl
  Dim cbcParent As CommandBarControl
  Dim cbc As CommandBarControl
  On Error GoTo ErrHandler
  '基于父标记定位父菜单
  Set cbcParent = Application.CommandBars.FindControl(, , rg.Value)
  If Not cbcParent Is Nothing Then
      '添加菜单项
      Set cbc = cbcParent.Controls.Add(GetType(rg))
      '确保该菜单项具有一个OnAction值而不是N/A
      If rg.Offset(0, ONACTION_OFFSET).Value <> NA Then
          cbc.OnAction = rg.Offset(0, ONACTION_OFFSET).Value
      End If
      cbc.Tag = rg.Offset(0, TAG_OFFSET).Value
      cbc.DescriptionText = rg.Offset(0, DESCRIPTION_OFFSET).Value
      cbc.Caption = rg.Offset(0, CAPTION_OFFSET).Value
      cbc.BeginGroup = rg.Offset(0, BEGINGROUP_OFFSET).Value
      '返回新添加的控件
      Set AddSubItem = cbc
  Else
      '不能找到父控件-返回无
      Set AddSubItem = Nothing
  End If
ExitPoint:
  Set cbc = Nothing
  Set cbcParent = Nothing
  Exit Function
ErrHandler:
  Debug.Print Err.Description
  Set AddSubItem = Nothing
  Resume ExitPoint
End Function
 
'将所选的msoControlType枚举转换为值
Private Function GetType(rg As Range) As Long
  Dim sType As String
  sType = rg.Offset(0, TYPE_OFFSET).Value
  Select Case sType
      Case Is = "msoControlPopup"
          GetType = msoControlPopup
      Case Is = "msoControlButton"
          GetType = msoControlButton
      Case Is = "msoControlDropDown"
          GetType = msoControlDropdown
      Case Else '包括N/A
      '默认为msoControlPopup
          GetType = msoControlPopup
  End Select
End Function
 
'删除标记为"我的菜单1"的控件
Sub DeleteMyMenu1()
  DeleteMenu "我的菜单1"
End Sub
 
'删除标记为"我的菜单2"的控件
Sub DeleteMyMenu2()
  DeleteMenu "我的菜单2"
End Sub
 
Private Sub DeleteMenu(sTag As String)
  Dim cbc As CommandBarControl
  Set cbc = Application.CommandBars.FindControl(Tag:=sTag)
  If Not cbc Is Nothing Then
  cbc.Delete
  End If
  Set cbc = Nothing
End Sub

上述代码的主程序是BuildMenu过程,该过程遍历工作表MenuBuilder中A列的单元格,检查其值是否等于N/A,如果等于则调用AddTopLevelItem过程在工作表菜单栏中创建一个新菜单项,如果不等于则调用AddSubItem过程,根据标记查找已存在的菜单项并在其中添加子菜单项。为了找到控件,代码使用FindControl方法。
此外,AddTopLevelItem过程忽略了Type列和OnAction列,并自动添加msoControlPopup类型的控件。AddSubItem过程将检查OnAction列的值,确保其中不会包含值N/A,若包含则不会设置OnAction属性。
最后的三个过程用来删除已创建好的菜单项。
前面说过,这是一个简单的菜单构建器示例,其中只包括了构建菜单所需的常见的一些属性。您可以添加列并修改相应的代码,使其功能更加强大,例如添加控件的Visible和Enabled属性列。

相关文章

根据单元格内容创建自定义弹出菜单

1 颗星2 颗星3 颗星4 颗星5 颗星 (1 人投票, 平均: 5.00 out of 5)
Loading ... Loading ...

下面介绍如何在Excel中创建自定义弹出菜单。
Excel有许多可用的右键弹出菜单,其内容取决正在做什么,术语称为上下文菜单。例如,在单元格中单击右键,将出现“单元格”弹出菜单及其可用的选择。这个菜单可以定制,即允许在其中添加项目或者禁用项目。
取决于需要,下拉菜单可能会变得非常巨大。进一步说,如果取决于单元格内容而为每个单元格获得相同的菜单,可能会有太多的选择。一个完整的基于单元格内容或区域的自定义菜单,将会更好地满足特定的需要。
下面的代码使得您在当前工作簿的任何工作表中,右键单击分别填充有红色、黄色和绿色阴影的单元格时,创建并弹出三个自定义菜单(红色、黄色和绿色)。
本示例需要在Workbook.Open事件中编写代码,同时需要一个代码模块和一个类模块。
关键是类模块。类模块包含工作表事件的处理,无论何时在工作簿的任何工作表中发生操作时触发该事件。特别需要说明的是Worksheet.BeforeRightClick事件,正如其名字所表示的意思,即当用户右击工作表时发生默认的操作之前希望做的事情。
本例中,Range.Interior属性用于访问单元格的Interior.ColorIndex属性。取决于颜色返回的值,取消了默认的弹出菜单,并且根据返回的属性值显示相应的弹出菜单。
createpopupmenusample1
这项技术可用于自定义Excel解决方案,限制最终用户只做特定的任务。
Workbook_Open
Workbook_Open事件处理建立三个弹出菜单,并在类中创建工作表对象。打开VBE,将下面的代码粘贴到ThisWorkbook模块中:

Private Sub Workbook_Open()
    Set cb_Red = CreateSubMenu("红色")
    Set cb_Yellow = CreateSubMenu("黄色")
    Set cb_Green = CreateSubMenu("绿色")
    Call SetupAllWSEvents
End Sub

代码模块
代码模块包含类设置和实际的菜单创建过程。在VBE中,插入一个标准模块,将下面的代码粘贴到该模块中:

Global cb_Red As CommandBar
Global cb_Yellow As CommandBar
Global cb_Green As CommandBar
Global WSObj As Collection
Global ws As Worksheet
 
Sub SetupAllWSEvents()
 
    Dim WSo As clsWs
    Set WSObj = Nothing
    Set WSObj = New Collection
    For Each ws In ActiveWorkbook.Worksheets
        Set WSo = New clsWs
        Set WSo.WSToMonitor = ws
        WSObj.Add WSo, ws.Name
    Next ws
 
End Sub
 
Function CreateSubMenu(strCB) As CommandBar
 
    Const CBPREFIX = "CustomPopUp"
    Dim cb As CommandBar
    Dim cbc As CommandBarControl
    Dim strCBName As String
    '自定义菜单名称
    strCBName = CBPREFIX & strCB
    '移除以前的实例
    Call DeleteCommandBar(strCBName)
   '添加弹出菜单到CommandBars集合
    Set cb = CommandBars.Add(Name:=strCBName, _
        Position:=msoBarPopup, _
        MenuBar:=False, _
        Temporary:=False)
    '添加控件
    Set cbc = cb.Controls.Add
    With cbc
        .Caption = strCB & " 控件 1"
        .OnAction = "DummyMessage"
    End With
 
    Set cbc = cb.Controls.Add
    With cbc
        .Caption = strCB & " 控件 2"
        .OnAction = "DummyMessage"
    End With
 
    Set CreateSubMenu = cb
    Set cbc = Nothing
    Set cb = Nothing
 
End Function
Sub DeleteCommandBar(cbName)
 
    On Error Resume Next
    CommandBars(cbName).Delete
 
End Sub
Sub DummyMessage()
    MsgBox CommandBars.ActionControl.Caption, vbInformation + vbOKOnly, "Dummy Message"
End Sub

类模块
类模块根据目标单元格的特征决定弹出哪个菜单。在VBE中,插入类模块,将其名字改为clsWS,并在其中粘贴下列代码:

Dim WithEvents aWS As Worksheet
 
Property Set WSToMonitor(uWS As Worksheet)
    Set aWS = uWS
End Property
 
Private Sub aWS_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
    Select Case Target.Interior.ColorIndex
        Case 3, 9
        cb_Red.ShowPopup
        Cancel = True '使标准的单元格弹出菜单失效
    Case 4, 10, 14, 35, 43, 50, 51, 52
        cb_Green.ShowPopup
        Cancel = True
    Case 6, 12, 36, 44
        cb_Yellow.ShowPopup
        Cancel = True
    Case Else
        Cancel = False
    End Select
End Sub

代码测试
如上图所示,在某工作表中分别使用红色、黄色、绿色填充单元格,保存并关闭工作簿。然后重新打开该工作簿,此时在有颜色的单元格中单击右键,会出现不同的自定义弹出菜单。

示例下载

注:来源于Excel Team Blog,本文稍有调整。

相关文章