Creating Menu Items In The VBA Editor
This page describes how to create menu items in the VBA Editor.
Adding menu items the VBA Editor (VBE) menus is somewhat different than adding menus to the main Excel menus. A workbook or
add-in that creates and responds to menu items in the VBE needs at least two modules: a code module to contain the
code to create the menu items and the procedures to be called by the menu items, and a class module to respond the the
Click events of the menu items.
In order to use the code in your projects, you must change two settings.
- First, you need to set an reference to the VBA Extensibililty library. The library contains the definitions
of the objects that make up the VBProject. In VBA, go the the Tools menu and choose References. In that dialog,
scroll down to and check the entry for Microsoft Visual Basic For Applications Extensibility 5.3
.
- Next, you need to enable access to the VBA project. In Excel 2003 and earlier, go the Tools menu
(in Excel, not in the VBA editor), choose Macros and then the Security item. In that dialog, click on the
Trusted Publishers tab and check the Trust access to the Visual Basic Project setting.
In Excel 2007, click
the Developer item on the main Ribbon and then click the Macro Security item in the Code panel.
In that dialog, choose Macro Settings and check the Trust access to the VBA project object model.
You can download an example workbook with all the on this page code.
You first need a class that will respond to the Click event of the menu or command bar
item. Since the other code in the project will use this class, we'll write the class code first.
Insert a new class module in your project. From the Insert menu, choose Class Module. Press the
F4 key to display the Properties window and change the Name property from
Class1 to CVBECommandHander. In this class module, enter the following
code:
Public WithEvents EvtHandler As VBIDE.CommandBarEvents
Private Sub EvtHandler_Click(ByVal CommandBarControl As Object, _
Handled As Boolean, CancelDefault As Boolean)
On Error Resume Next
Application.Run CommandBarControl.OnAction
Handled = True
CancelDefault = True
End Sub
The EvtHandeler variable will be set to a CommandBarEvents object provided by
the VBE for each new item that we will create. When a menu item is clicked, this procedure is called automatically. The code
looks in the OnAction property of the menu item to get the name of the procedure assigned to that
menu item and then calls that procedure using the Application.Run method. A new instance of the
CVBECommandHandler class is created for each menu item that will be added. These instances will
be stored in a Collection object as they are created.
The next step is to write the code to create the menu items. This code will do the following for each item that we create:
- Create a new instance of the CVBECommandHandler class.
- Add a menu item to the Tools menu.
- Set the properties of that menu item, such as the Caption and OnAction.
- Set the EvtHandler of the newly created CVBECommandHandler object
to a CommandBarEvents object provided by the VBE.
Create a new code module for the project. From the
Insert menu, choose
Module. In that module, use the following
code:
Private MenuEvent As CVBECommandHandler
Private CmdBarItem As CommandBarControl
Private EventHandlers As New Collection
Private Const C_TAG = "MY_VBE_TAG"
Sub AddNewVBEControls()
Dim Ctrl As Office.CommandBarControl
Set Ctrl = Application.VBE.CommandBars.FindControl(Tag:=C_TAG)
Do Until Ctrl Is Nothing
Ctrl.Delete
Set Ctrl = Application.VBE.CommandBars.FindControl(Tag:=C_TAG)
Loop
Do Until EventHandlers.Count = 0
EventHandlers.Remove 1
Loop
Set MenuEvent = New CVBECommandHandler
With Application.VBE.CommandBars("Menu Bar").Controls("Tools")
Set CmdBarItem = .Controls.Add
End With
With CmdBarItem
.Caption = "First Item"
.BeginGroup = True
.OnAction = "'" & ThisWorkbook.Name & "'!Procedure_One"
.Tag = C_TAG
End With
Set MenuEvent.EvtHandler = Application.VBE.Events.CommandBarEvents(CmdBarItem)
EventHandlers.Add MenuEvent
Set MenuEvent = New CVBECommandHandler
With Application.VBE.CommandBars("Menu Bar").Controls("Tools")
Set CmdBarItem = .Controls.Add
End With
With CmdBarItem
.Caption = "Second Item"
.BeginGroup = False
.OnAction = "'" & ThisWorkbook.Name & "'!Procedure_Two"
.Tag = C_TAG
End With
Set MenuEvent.EvtHandler = Application.VBE.Events.CommandBarEvents(CmdBarItem)
EventHandlers.Add MenuEvent
End Sub
The code above creates two menu items on the Tools menu, and assigns the procedures
Procedure_One and Procedure_Two to those
menu items. A new CVBECommandHandler is created for each menu item
and those instances are stored in the EventHandlers Collection.
When the menu items are created, the Tag property is set to the string in the constant
C_TAG. You should change the value of this constant to something unique to your
project. This value is used by the DeleteMenuItems procedure, shown below, to
remove the menu items.
Sub DeleteMenuItems()
Dim Ctrl As Office.CommandBarControl
Set Ctrl = Application.VBE.CommandBars.FindControl(Tag:=C_TAG)
Do Until Ctrl Is Nothing
Ctrl.Delete
Set Ctrl = Application.VBE.CommandBars.FindControl(Tag:=C_TAG)
Loop
End Sub
The final step is to write the procedures that are called by the menu items. When we created the menu items, we assigned the
procedure Procedure_One to the OnAction property of the first menu item
and Procedure_Two to the OnAction property of the second menu item.
The CVBECommandHandler class will call the procedure specified in the OnAction
property of the menu item. You can put these procedures in the same code module as the AddNewVBEControls
procedure or you can put them in a separate module for organizational clarity.
Public Sub Procedure_One()
MsgBox "Procedure One"
End Sub
Public Sub Procedure_Two()
MsgBox "Procedure Two"
End Sub
If you put the module above in a workbook that is automatically opened, such as your Personal.xls
workbook, or in an add-in, you should call the function AddNewVBEControls from the
Auto_Open procedure or the Workbook_Open event procedure. When the project
is closed, you should call the DeleteMenuItems procedure from either the Auto_Close
procedure or the Workbook_BeforeClose event procedure, as shown below.
Public Sub Auto_Open()
AddNewVBEControls
End Sub
Public Sub Auto_Close()
DeleteMenuItems
End Sub
Download an example workbook with all the code.
This page last updated: 3-September-2007