Excel快捷菜单和Excel事件

本文中的示例演示了与事件协同使用的不同的快捷菜单编程技术。
自动添加和删除菜单
如果需要在打开工作簿时修改快捷菜单,则使用Workbook_Open事件。下面的代码存储在ThisWorkbook对象的代码模块中,在打开工作簿时将执行ModifyShortcut过程。
Private Sub Workbook_Open()
    Call ModifyShortcut
End Sub

要使快捷菜单恢复到其修改前的状态,则使用下面的过程。该过程在关闭工作簿之前执行,并且会调用RestoreShortcut过程。
Private Sub Workbook_BeforeClose(Cancel As Boolean)
    Call RestoreShortcut
End Sub

但是,这里存在着一个问题,即在用户关闭工作簿时,如果不保存该工作簿,会发生意外情况。在Workbook_BeforeClose事件处理运行之后,Excel会提示“是否保存对工作簿所作的修改?”,此时,如果用户单击“取消”按钮,则工作簿仍然保持打开,但自定义菜单已经被删除了。
对该问题的一种解决方法是绕开Excel的提示,在Workbook_BeforeClose过程中编写代码来询问用户保存该工作簿。下面的代码演示了如何进行操作:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
    If Not Me.Saved Then
        Msg = “您想保存对”
        Msg = Msg & Me.Name & “的改变吗?”
        Ans = MsgBox(Msg, vbQuestion + vbYesNoCancel)
        Select Case Ans
            Case vbYes
                Me.Save
            Case vbNo
                Me.Saved = True
            Case vbCancel
                Cancel = True
                Exit Sub
        End Select
    End If
    Call RestoreShortcut
End Sub

上述过程确定是否已保存了工作簿,如果该工作簿已保存,则没有问题,执行RestoreShortcut过程,然后关闭该工作簿。但是如果还没有保存该工作簿,则该过程显示一条复制Excel正常显示时的消息框。如果用户单击“是”,则保存工作簿,并删除菜单,然后关闭工作簿。如果用户单击“否”,则代码将Workbook对象的Saved属性设置为True(实际上没有保存该文件)并删除菜单。如果用户单击“取消”,则BeforeClose事件被取消,过程结束而不会恢复快捷菜单。

禁用或者隐藏快捷菜单项
当禁用某菜单项时,其文本显示为暗灰色的阴影,单击该菜单项时没有任何反应。当隐藏某菜单项时,在快捷菜单中不会出现该菜单项。当然,您可以编写VBA代码来启用或禁用快捷菜单项。同样,您可以编写代码来隐藏快捷菜单项。关键是要使用正确的事件。
例如,下面的代码在激活工作表Sheet2时禁用Change Case快捷菜单项(该菜单项已添加到单元格快捷菜单中,参见“使用VBA自定义Excel 2007快捷菜单”),该过程位于Sheet2代码模块中:
Private Sub Worksheet_Activate()
    CommandBars(”Cell”).Controls(”Change Case”).Enabled = False
End Sub

要在工作表Sheet2失活时(即不为当前活动工作表时)启用该菜单项,添加下面的过程。其效果是,除了激活工作表Sheet2外,Change Case菜单项在所有其它情形下均可用。
Private Sub Worksheet_Deactivate()
    CommandBars(”Cell”).Controls(”Change Case”).Enabled = True
End Sub
要隐藏该菜单项而不是禁用它,只需使用Visible属性代替Enabled属性。

创建一个上下文相关的快捷菜单
可以创建一个全新的快捷菜单,并且在响应特定的事件时显示该菜单。下面的代码创建一个名为MyShortcut的快捷菜单,包含有6个菜单项,分别设置其OnAction属性来执行简单的过程,即分别显示“单元格格式”对话框中的某一选项卡(参见下图1)。
ExcelMenuAndEvent
图1:一个新的快捷菜单,仅当用户右击工作表阴影区域中的某单元格时出现
Sub CreateShortcut()
    Dim myBar As CommandBar
    Dim myItem As CommandBarControl
    
    ‘   若已存在该菜单,则删除
    DeleteShortcut
    
    ‘   添加一个新菜单
    Set myBar = CommandBars.Add _
      (Name:=”MyShortcut”, Position:=msoBarPopup, Temporary:=True)
    
    ‘   添加一个新菜单
    Set myItem = myBar.Controls.Add(Type:=msoControlButton)
    With myItem
        .Caption = “&Number Format…”
        .OnAction = “ShowFormatNumber”
        .FaceId = 1554
    End With
        
    ‘   添加一个新菜单
    Set myItem = myBar.Controls.Add(Type:=msoControlButton)
    With myItem
        .Caption = “&Alignment…”
        .OnAction = “ShowFormatAlignment”
        .FaceId = 194
    End With
        
    ‘   添加一个新菜单
    Set myItem = myBar.Controls.Add(Type:=msoControlButton)
    With myItem
        .Caption = “&Font…”
        .OnAction = “ShowFormatFont”
        .FaceId = 309
    End With
    ‘   添加一个新菜单
    Set myItem = myBar.Controls.Add(Type:=msoControlButton)
    With myItem
        .Caption = “&Borders…”
        .OnAction = “ShowFormatBorder”
        .FaceId = 149
        .BeginGroup = True
    End With
    
    ‘   添加一个新菜单
    Set myItem = myBar.Controls.Add(Type:=msoControlButton)
    With myItem
        .Caption = “&Fill…”
        .OnAction = “ShowFormatPatterns”
        .FaceId = 687
    End With
    
    ‘   添加一个新菜单
    Set myItem = myBar.Controls.Add(Type:=msoControlButton)
    With myItem
        .Caption = “&Protection…”
        .OnAction = “ShowFormatProtection”
        .FaceId = 225
    End With
End Sub

创建了快捷菜单后,可以通过使用ShowPopup方法来显示该菜单。下面的过程,位于Worksheet对象的代码模块中,当用户右击某单元格时执行:
Private Sub Worksheet_BeforeRightClick _
  (ByVal Target As Excel.Range, Cancel As Boolean)
    If Union(Target.Range(”A1″), Range(”data”)).Address = _
      Range(”data”).Address Then
        CommandBars(”MyShortcut”).ShowPopup
        Cancel = True
    End If
End Sub

当用户右击时,如果活动单元格在名为data的单元格区域内,则显示MyShortcut菜单。设置Cancel参数为True,确保不显示正常的快捷菜单。注意,微型(mini)工具栏也没有显示。
下面是创建快捷菜单的过程代码中对应的所要执行的宏:
Sub ShowFormatNumber()
    ‘Application.Dialogs(xlDialogFormatNumber).Show
    CommandBars.ExecuteMso (”FormatCellsNumberDialog”)
End Sub
Sub ShowFormatAlignment()
    ‘Application.Dialogs(xlDialogAlignment).Show
    CommandBars.ExecuteMso (”CellAlignmentOptions”)
End Sub

Sub ShowFormatFont()
    ‘Application.Dialogs(xlDialogFormatFont).Show
    CommandBars.ExecuteMso (”FormatCellsFontDialog”)
End Sub

Sub ShowFormatBorder()
    ‘Application.Dialogs(xlDialogBorder).Show
    CommandBars.ExecuteMso (”BordersMOreDialog”)
End Sub

Sub ShowFormatPatterns()
    ‘(没有ExecuteMso方法,因此使用旧样式)
    Application.Dialogs(xlDialogPatterns).Show
End Sub

Sub ShowFormatProtection()
    ‘(没有ExecuteMso方法,因此使用旧样式)
    Application.Dialogs(xlDialogCellProtection).Show
End Sub

Sub DeleteShortcut()
    On Error Resume Next
    CommandBars(”MyShortcut”).Delete
End Sub
也可以使用鼠标来显示该快捷菜单,创建一个简单的过程,并通过“宏”对话框中的“选项”按钮分配一个快捷键。
Sub ShowMyShortcutMenu()
‘   Ctrl+Shift+M快捷键
    CommandBars(”MyShortcut”).ShowPopup
End Sub


提示:您可以在评论中使用HTML标签,且任何与HTML标签相同的符号都会被理解为HTML标签并以相应的格式显示.如果您的评论中有代码,可以使用相应的标签,例如,如果有VB或VBA代码,则可以使用[vb]标签,即[vb]放置的代码[/vb],这样会很清晰地显示代码.

1条评论

  1. sblisb 说到:

    有没示例寄给我一个,谢谢!

留下回复