Customizing Context Menus in Microsoft Excel
Contents
Introduction Context Menus
Add button and menu to the Cell menu with VBA code(Every Excel version)
Add button and menu to the Cell menu with RibbonX (Only Excel 2010)
Add a dynamic menu to the Cell menu with VBA code or RibbonX
Disable or Enable a control on the Cell menu with VBA and RibbonX
Tips for the VBA and RibbonX examples
Other Articles
Conclusion
Introduction Context Menus
The most common Context Menu that most people know and use is the Cell menu.
This is the menu that you see when you right click on a worksheet cell or selection.
The screenshot below is from the Excel 2010 Cell menu.
Note: On the bottom of the menu you also see the name of the idMso of this
menu added by the Microsoft add-in discussed later in this article.

The only way to change this menu up to Excel 2007 is to use VBA code, but in Excel 2010
you can also change a context menu with RibbonX.
The advantage of RibbonX in Excel 2010 is that you can add controls that are not possible
to add with VBA, the following lists the controls allowed in context menus.
control
button
checkBox
dynamicMenu
gallery
menu
menuSeparator
splitButton
toggleButton
But this will only work in Excel 2010, so if not all your users use Excel 2010 it is better to use
VBA code and add controls that work in every Excel version.
Add button and menu to the Cell menu with VBA code(Every Excel version)
This example will add a custom button, built-in button (Save) and a Custom menu on top of the Cell menu. Other context menus that you can change are the Row and Column context menus for example.
These are the menus that you see when you right click on the row or column headers.
See theTips section for a tip how to find the names of the other context menus.
Note: There are two Cell menu's in Excel, the second one you see when you are in page break preview mode.
If you want to change this menu use this then in the code.
Set ContextMenu = Application.CommandBars(Application.CommandBars("Cell").Index + 3)
The same applies to the Row and Column context menus.
Copy the six macro's below into a General module of your workbook.
If you do not know where to copy the code check out this page.
http://www.rondebruin.nl/code.htm
The first macro adds the controls to the Cell menu (see how I add a Tag to the controls I add).
The second macro deletes the controls from the Cell menu (See how I use the Tag to delete the controls).
The other four macros will run when you click on the Button or on one of the three options in the menu.
As a example I use macros that change the Case of the text cells in the selection.
Copy the two event procedures below in the Thisworkbook module of your workbook
This will automatically add the controls to the Cell menu when you open or activate the workbook
and delete the controls when you close or deactivate the workbook
Add button and menu to the Cell menu with RibbonX (Only Excel 2010)
We will create the same menu as the VBA example above with the RibbonX below.
If you do not know how to add RibbonX to your workbook see this page
http://www.rondebruin.nl/ribbon.htm
The Cell menu in page break preview mode in Excel 2010 hase a different name.
I am glad that Microsoft use a different idMso now in the RibbonX, see the Add-in in the
Tips part of this article for a easy way to find the idMso's for every context menu.
Open a new workbook and save it at as a Macro Enabled Workbook (xlsm)
Close the workbook in Excel
Open the file in the Custom UI Editor and Insert an Office 2010 Custom UI Part
Add the RibbonX below in the Office 2010 Custom UI Part of the workbook and save it.
Close the Custom UI Editor
Open the workbook in Excel
Copy the four macros below into a General module of your workbook and save the file.
Now right click on a cell and if you followed the steps correctly you will see that the Cell menu is changed.
Bug: When you close the workbook every control you add is removed from the Cell menu, but if you
select another workbook the built-in Save button that we added to the Cell menu is not removed.
This seems to be a problem when you add built-in controls to a context menu.
If this is a problem for you you can insert a custom button instead that calls a macro
that executes the built-in Save control in this example as a workaround.
Replace this line in the RibbonX that added the Built-in control
<button idMso="FileSave" insertBeforeMso="Cut" />
with this
<button id="DuplicateBuiltInButton1" label="Save"
insertBeforeMso="Cut"
onAction="BuiltInSaveCommand"
imageMso="FileSave"/>
The macro for the onAction looks like this
But with ExecuteMso you can execute every built-in control on the Ribbon or context Menu.
Add a dynamic menu to the Cell menu with VBA code or RibbonX
Excel 2010

Dynamic menus point to callback procedures that create the menus at runtime.
The dynamicMenu control includes the getContent attribute that points to a GetContent callback procedure.
This is the RibbonX that create a dynamic menu in the Cell context menu.
For example, the following VBA code builds a dynamic menu at runtime with two buttons,
which means that it is not created until the menu control on the context menu is clicked.
You can download three example workbooks here that add a dynamic menu to the cell menu based
on the username, language of Excel or the value of the active cell (Formula, Empty, Numeric or Text)
You can find all the information about the example in the relevant workbook.
Note: Remember that the RibbonX examples only work in Excel 2010
Download workbooks for Excel 2010
Excel 97-2010
In the VBA example on top of this page I showed you how to change the Cell menu and I used the
Activate and Deactivate event of the workbook to call a macro to create and delete the menu controls.
You can change the Activate event like this to create different menus for different users, this way
you can create a menu with different sets of custom controls for different users.
If you use the same Tags in the code there is no need to call a different macro to delete the menu.
See the two commented lines that show you how to call a different macro if another user opens the workbook.
Another example is to check for the Excel language in the activate event so you can create menu captions in the language of the user in the context menu. In this case if a Dutch or German user opens the workbook
no menu will be created because I commented out the two lines that call the macros you could make for these two languages. For all other languages in this example the macro AddToCellMenu is called and it creates a menu with English captions
http://www.rondebruin.nl/international.htm
Disable or Enable a control on the Cell menu with VBA and RibbonX
VBA example for Excel 97-2010
To disable a control use always the ID and not the caption in your code.
If you use the caption, your code will not work when your workbook is used
in a different language version of Excel.
This will disable the Insert comment control for example on the Cell menu in Excel 97-2010.
Application.CommandBars("Cell").FindControl(ID:=2031).Enabled = False
But how do you find the ID's of each control on a contextmenu ?
You can use the add-in from Ole P. Erlandsen that you can find in the Tips section below.
Another way is to use a macro like this that adds the ID to the caption.
Remember that the Cell menu is not exactly the same in every Excel version.
You can use the Activate and Deactivate events, like I showed you in the example that added the buttons
and menu to the Cell menu, also to disable and to enable controls.
For more information about Command bars and controls in Excel 97-2003 visit also this page
Disable Command bars and controls in Excel 97-2003
http://www.rondebruin.nl/menuid.htm
RibbonX example for Excel 2010
For example if we want to disable Delete in the Cell menu we can add this to the RibbonX example above.
<button idMso="CellsDelete" enabled="false" />
You see that if we want to disable a control on a contextmenu we must know it's idMso.
But we have a problem because this info is not available for every context menu.
For example for the Cell, Row and Column menu there is no information.
This is the reason :
MS only support a small set of controls in RibbonX, some controls that are available in some context
menus are controls that carried over from legacy versions (e.g. O12) so they don’t support them for extensibility through RibbonX. In some cases you can use the same name’s that are used for the Ribbon,
but is not guaranteed that this will work with every control.
I have try to find Insert Comment that I used in the VBA example but no luck.
As far as I know there is no list of controls that are supported in RibbonX.
But you can always use VBA code example above if you can't find a specific control ID.
Note: See the RibbonX tips section below for a link to a file with every control idMso of
each control in almost every ContextMenu.
Tips for the VBA and RibbonX examples
VBA example tips for Excel 97-2010:
How do I find the name of the contextmenu that I want to change ?
The example macro below will add button on the bottom of each contextmenu with the menu name.
You will notice that you will not see a name on each context menu when you run it in Excel 2007-2010.
For example, you will not see it when you right click on a shape or Picture in Excel 2007-2010.
So it not seems to be possible to change these menus in Excel 2007-2010 with VBA.
How do I find the control ID's or FaceID's :
Use the BtnFace add-in from Jim Rech to find every FaceId
Download it from my site
If you want to find the ID's and FaceId's see this page from Ole P. Erlandsen
http://erlandsendata.no/?p=2694
Check out this page from John Walkenbach to find every FaceId
http://spreadsheetpage.com/index.php/site/tip/identifying_commandbar_images/
RibbonX example tips for Excel 2010:
Add-in:
You see that I use "ContextMenuCell" as idMso for the Cell menu
But how do you find the names of the contextmenus ?
Microsoft ContextMenu Add-in for Office 2010
This is an Office 2010 (Excel, Outlook, PowerPoint, Project, Publisher, Word) COM Add-in.
It adds a button at the end of the context menus. The button should help you to find the NameX for that particular context menu.This is a very easy way for developers to find the idMso of the contextmenu.
http://code.msdn.microsoft.com/contextmenusaddin
If you want to know what the add-in's options in backstage view are about, this is the answer :
By default the add-in is packaged with XML files containing the information about the context menus in each application.The options in the backstage are to override the packaged XML’s with updated or custom XML files.
Useful files:
I used this for example in the RibbonX to tell where I wanted the controls
insertBeforeMso="Cut"
Or if you want to insert a built-in control you must use the idMso like: idMso="FileSave"
If you are looking for imageMso values or the control idMso values see the downloads on my Ribbon page :
http://www.rondebruin.nl/ribbon.htm#names
and
http://www.rondebruin.nl/ribbon.htm#images
The only problem is that you can't find the idMso's of the controls of every context menu.
MS only supports a small set of controls in RibbonX, some controls that are available in some context menus are controls that carried over from legacy versions (e.g. O12) so they don’t support them for extensibility through RibbonX. In some cases you can use the same name’s that are used for the Ribbon,
but is not guaranteed that this will work with every control.
This is not good if you want to add your control after a specific built-in control and can't find the correct
idMso or want to re-purpose or disable one of the controls and not know it's idMso.
Other Articles
Customizing Context Menus in All Versions of Microsoft Excel
http://msdn.microsoft.com/en-us/library/gg469862.aspx
Customizing Context Menus in Office 2010 (MSDN: Frank Rice)
http://msdn.microsoft.com/en-us/library/ee691832.aspx
Creating a PopUp Menu that is working in every Excel version
http://www.rondebruin.nl/popup.htm
Conclusion
Excel 97-2003
You can add controls to every context menu with VBA code (though I have not tested them all)
Not possible to change context menus with RibbonX
Excel 2007
You can add controls to almost every contextmenu with VBA code
Not possible to change for example the Shapes and Picture contextmenu with VBA
Not possible to change Context menus with RibbonX
Excel 2010
You can add controls to almost every contextmenu with VBA code
Not possible to change for example the Shapes and Picture toolbar with VBA
But you can add buttons/menus to every ContextMenu with RibbonX but if you want
to disable or re-purpose controls you may not be able to find the correct idMso(read this)
Introduction Context Menus
Add button and menu to the Cell menu with VBA code(Every Excel version)
Add button and menu to the Cell menu with RibbonX (Only Excel 2010)
Add a dynamic menu to the Cell menu with VBA code or RibbonX
Disable or Enable a control on the Cell menu with VBA and RibbonX
Tips for the VBA and RibbonX examples
Other Articles
Conclusion
Introduction Context Menus
The most common Context Menu that most people know and use is the Cell menu.
This is the menu that you see when you right click on a worksheet cell or selection.
The screenshot below is from the Excel 2010 Cell menu.
Note: On the bottom of the menu you also see the name of the idMso of this
menu added by the Microsoft add-in discussed later in this article.

The only way to change this menu up to Excel 2007 is to use VBA code, but in Excel 2010
you can also change a context menu with RibbonX.
The advantage of RibbonX in Excel 2010 is that you can add controls that are not possible
to add with VBA, the following lists the controls allowed in context menus.
control
button
checkBox
dynamicMenu
gallery
menu
menuSeparator
splitButton
toggleButton
But this will only work in Excel 2010, so if not all your users use Excel 2010 it is better to use
VBA code and add controls that work in every Excel version.
Add button and menu to the Cell menu with VBA code(Every Excel version)
This example will add a custom button, built-in button (Save) and a Custom menu on top of the Cell menu. Other context menus that you can change are the Row and Column context menus for example.
These are the menus that you see when you right click on the row or column headers.
See theTips section for a tip how to find the names of the other context menus.
Note: There are two Cell menu's in Excel, the second one you see when you are in page break preview mode.
If you want to change this menu use this then in the code.
Set ContextMenu = Application.CommandBars(Application.CommandBars("Cell").Index + 3)
The same applies to the Row and Column context menus.
Copy the six macro's below into a General module of your workbook.
If you do not know where to copy the code check out this page.
http://www.rondebruin.nl/code.htm
The first macro adds the controls to the Cell menu (see how I add a Tag to the controls I add).
The second macro deletes the controls from the Cell menu (See how I use the Tag to delete the controls).
The other four macros will run when you click on the Button or on one of the three options in the menu.
As a example I use macros that change the Case of the text cells in the selection.
Sub AddToCellMenu()
Dim ContextMenu As CommandBar
Dim MySubMenu As CommandBarControl
'Delete the controls first to avoid duplicates
Call DeleteFromCellMenu
'Set ContextMenu to the Cell menu
Set ContextMenu = Application.CommandBars("Cell")
'Add one built-in button(Save = 3)to the cell menu
ContextMenu.Controls.Add Type:=msoControlButton, ID:=3, before:=1
'Add one custom button to the Cell menu
With ContextMenu.Controls.Add(Type:=msoControlButton, before:=2)
.OnAction = "'" & ThisWorkbook.Name & "'!" & "ToggleCaseMacro"
.FaceId = 59
.Caption = "Toggle Case Upper/Lower/Proper"
.Tag = "My_Cell_Control_Tag"
End With
'Add custom menu with three buttons
Set MySubMenu = ContextMenu.Controls.Add(Type:=msoControlPopup, before:=3)
With MySubMenu
.Caption = "Case Menu"
.Tag = "My_Cell_Control_Tag"
With .Controls.Add(Type:=msoControlButton)
.OnAction = "'" & ThisWorkbook.Name & "'!" & "UpperMacro"
.FaceId = 100
.Caption = "Upper Case"
End With
With .Controls.Add(Type:=msoControlButton)
.OnAction = "'" & ThisWorkbook.Name & "'!" & "LowerMacro"
.FaceId = 91
.Caption = "Lower Case"
End With
With .Controls.Add(Type:=msoControlButton)
.OnAction = "'" & ThisWorkbook.Name & "'!" & "ProperMacro"
.FaceId = 95
.Caption = "Proper Case"
End With
End With
'Add seperator to the Cell menu
ContextMenu.Controls(4).BeginGroup = True
End Sub
Sub DeleteFromCellMenu()
Dim ContextMenu As CommandBar
Dim ctrl As CommandBarControl
'Set ContextMenu to the Cell menu
Set ContextMenu = Application.CommandBars("Cell")
'Delete custom controls with the Tag : My_Cell_Control_Tag
For Each ctrl In ContextMenu.Controls
If ctrl.Tag = "My_Cell_Control_Tag" Then
ctrl.Delete
End If
Next ctrl
'Delete built-in Save button
On Error Resume Next
ContextMenu.FindControl(ID:=3).Delete
On Error GoTo 0
End Sub
Sub ToggleCaseMacro()
Dim CaseRange As Range
Dim CalcMode As Long
Dim cell As Range
On Error Resume Next
Set CaseRange = Intersect(Selection, _
Selection.Cells.SpecialCells(xlCellTypeConstants, xlTextValues))
On Error GoTo 0
If CaseRange Is Nothing Then Exit Sub
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
End With
For Each cell In CaseRange.Cells
Select Case cell.Value
Case UCase(cell.Value): cell.Value = LCase(cell.Value)
Case LCase(cell.Value): cell.Value = StrConv(cell.Value, vbProperCase)
Case Else: cell.Value = UCase(cell.Value)
End Select
Next cell
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
Sub UpperMacro()
Dim CaseRange As Range
Dim CalcMode As Long
Dim cell As Range
On Error Resume Next
Set CaseRange = Intersect(Selection, _
Selection.Cells.SpecialCells(xlCellTypeConstants, xlTextValues))
On Error GoTo 0
If CaseRange Is Nothing Then Exit Sub
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
End With
For Each cell In CaseRange.Cells
cell.Value = UCase(cell.Value)
Next cell
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
Sub LowerMacro()
Dim CaseRange As Range
Dim CalcMode As Long
Dim cell As Range
On Error Resume Next
Set CaseRange = Intersect(Selection, _
Selection.Cells.SpecialCells(xlCellTypeConstants, xlTextValues))
On Error GoTo 0
If CaseRange Is Nothing Then Exit Sub
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
End With
For Each cell In CaseRange.Cells
cell.Value = LCase(cell.Value)
Next cell
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
Sub ProperMacro()
Dim CaseRange As Range
Dim CalcMode As Long
Dim cell As Range
On Error Resume Next
Set CaseRange = Intersect(Selection, _
Selection.Cells.SpecialCells(xlCellTypeConstants, xlTextValues))
On Error GoTo 0
If CaseRange Is Nothing Then Exit Sub
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
End With
For Each cell In CaseRange.Cells
cell.Value = StrConv(cell.Value, vbProperCase)
Next cell
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
Copy the two event procedures below in the Thisworkbook module of your workbook
This will automatically add the controls to the Cell menu when you open or activate the workbook
and delete the controls when you close or deactivate the workbook
Private Sub Workbook_Activate()
Call AddToCellMenu
End Sub
Private Sub Workbook_Deactivate()
Call DeleteFromCellMenu
End Sub
Then save, close and reopen the workbook to see the changes in the Cell menu.Add button and menu to the Cell menu with RibbonX (Only Excel 2010)
We will create the same menu as the VBA example above with the RibbonX below.
If you do not know how to add RibbonX to your workbook see this page
http://www.rondebruin.nl/ribbon.htm
The Cell menu in page break preview mode in Excel 2010 hase a different name.
I am glad that Microsoft use a different idMso now in the RibbonX, see the Add-in in the
Tips part of this article for a easy way to find the idMso's for every context menu.
Open a new workbook and save it at as a Macro Enabled Workbook (xlsm)
Close the workbook in Excel
Open the file in the Custom UI Editor and Insert an Office 2010 Custom UI Part
Add the RibbonX below in the Office 2010 Custom UI Part of the workbook and save it.
Close the Custom UI Editor
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<contextMenus>
<contextMenu idMso="ContextMenuCell">
<button idMso="FileSave" insertBeforeMso="Cut" />
<button id="MyButton" label="Toggle Case Upper/Lower/Proper"
insertBeforeMso="Cut"
onAction="ToggleCaseMacro"
imageMso="HappyFace"/>
<menu id="MySubMenu" label="Case Menu" insertBeforeMso="Cut" >
<button id="Menu1Button1" label="Upper Case"
imageMso="U" onAction="UpperMacro"/>
<button id="Menu1Button2" label="Lower Case"
imageMso="L" onAction="LowerMacro"/>
<button id="Menu1Button3" label="Proper Case"
imageMso="P" onAction="ProperMacro"/>
</menu>
<menuSeparator id="MySeparator" insertBeforeMso="Cut" />
</contextMenu>
</contextMenus>
</customUI>
Open the workbook in Excel
Copy the four macros below into a General module of your workbook and save the file.
Now right click on a cell and if you followed the steps correctly you will see that the Cell menu is changed.
Sub ToggleCaseMacro(control As IRibbonControl)
Dim CaseRange As Range
Dim CalcMode As Long
Dim cell As Range
On Error Resume Next
Set CaseRange = Intersect(Selection, _
Selection.Cells.SpecialCells(xlCellTypeConstants, xlTextValues))
If CaseRange Is Nothing Then Exit Sub
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
End With
For Each cell In CaseRange
Select Case cell.Value
Case UCase(cell.Value): cell.Value = LCase(cell.Value)
Case LCase(cell.Value): cell.Value = StrConv(cell.Value, vbProperCase)
Case Else: cell.Value = UCase(cell.Value)
End Select
Next cell
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
Sub UpperMacro(control As IRibbonControl)
Dim CaseRange As Range
Dim CalcMode As Long
Dim cell As Range
On Error Resume Next
Set CaseRange = Intersect(Selection, _
Selection.Cells.SpecialCells(xlCellTypeConstants, xlTextValues))
If CaseRange Is Nothing Then Exit Sub
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
End With
For Each cell In CaseRange
cell.Value = UCase(cell.Value)
Next cell
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
Sub LowerMacro(control As IRibbonControl)
Dim CaseRange As Range
Dim CalcMode As Long
Dim cell As Range
On Error Resume Next
Set CaseRange = Intersect(Selection, _
Selection.Cells.SpecialCells(xlCellTypeConstants, xlTextValues))
If CaseRange Is Nothing Then Exit Sub
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
End With
For Each cell In CaseRange
cell.Value = LCase(cell.Value)
Next cell
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
Sub ProperMacro(control As IRibbonControl)
Dim CaseRange As Range
Dim CalcMode As Long
Dim cell As Range
On Error Resume Next
Set CaseRange = Intersect(Selection, _
Selection.Cells.SpecialCells(xlCellTypeConstants, xlTextValues))
If CaseRange Is Nothing Then Exit Sub
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
End With
For Each cell In CaseRange
cell.Value = StrConv(cell.Value, vbProperCase)
Next cell
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
Bug: When you close the workbook every control you add is removed from the Cell menu, but if you
select another workbook the built-in Save button that we added to the Cell menu is not removed.
This seems to be a problem when you add built-in controls to a context menu.
If this is a problem for you you can insert a custom button instead that calls a macro
that executes the built-in Save control in this example as a workaround.
Replace this line in the RibbonX that added the Built-in control
<button idMso="FileSave" insertBeforeMso="Cut" />
with this
<button id="DuplicateBuiltInButton1" label="Save"
insertBeforeMso="Cut"
onAction="BuiltInSaveCommand"
imageMso="FileSave"/>
The macro for the onAction looks like this
Sub BuiltInSaveCommand(control As IRibbonControl)
CommandBars.ExecuteMso "FileSave"
End Sub
For this example we can also use ActiveWorkbook.SaveBut with ExecuteMso you can execute every built-in control on the Ribbon or context Menu.
Add a dynamic menu to the Cell menu with VBA code or RibbonX
Excel 2010

Dynamic menus point to callback procedures that create the menus at runtime.
The dynamicMenu control includes the getContent attribute that points to a GetContent callback procedure.
This is the RibbonX that create a dynamic menu in the Cell context menu.
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<contextMenus>
<contextMenu idMso="ContextMenuCell">
<dynamicMenu id="MyDynamicMenu"
label= "My Dynamic Menu" imageMso="HappyFace"
getContent="GetContent" insertBeforeMso="Cut"/>
</contextMenu>
</contextMenus>
</customUI>
For example, the following VBA code builds a dynamic menu at runtime with two buttons,
which means that it is not created until the menu control on the context menu is clicked.
Sub GetContent(control As IRibbonControl, ByRef returnedVal) Dim xml As String xml = "<menu xmlns=""http://schemas.microsoft.com/office/2009/07/customui"">" & _ "<button id=""but1"" imageMso=""Help"" label=""Help"" onAction=""HelpMacro""/>" & _ "<button id=""but2"" imageMso=""FindDialog"" label=""Find"" onAction=""FindMacro""/>" & _ "</menu>" returnedVal = xml End Sub Sub HelpMacro(control As IRibbonControl) MsgBox "Help macro" End Sub Sub FindMacro(control As IRibbonControl) MsgBox "Find macro" End Sub
You can download three example workbooks here that add a dynamic menu to the cell menu based
on the username, language of Excel or the value of the active cell (Formula, Empty, Numeric or Text)
You can find all the information about the example in the relevant workbook.
Note: Remember that the RibbonX examples only work in Excel 2010
Download workbooks for Excel 2010
Excel 97-2010
In the VBA example on top of this page I showed you how to change the Cell menu and I used the
Activate and Deactivate event of the workbook to call a macro to create and delete the menu controls.
You can change the Activate event like this to create different menus for different users, this way
you can create a menu with different sets of custom controls for different users.
If you use the same Tags in the code there is no need to call a different macro to delete the menu.
Private Sub Workbook_Activate()
Dim sUserName As String
sUserName = Application.UserName
Select Case sUserName
Case "Ron de Bruin": Call AddToCellMenu
'Case "Dave Thomson": Call AddToCellMenu2
'Case Else: Call AddToCellMenu3
End Select
End Sub
In the example above you will see no changes in the menu if you are not Ron
de Bruin.See the two commented lines that show you how to call a different macro if another user opens the workbook.
Another example is to check for the Excel language in the activate event so you can create menu captions in the language of the user in the context menu. In this case if a Dutch or German user opens the workbook
no menu will be created because I commented out the two lines that call the macros you could make for these two languages. For all other languages in this example the macro AddToCellMenu is called and it creates a menu with English captions
Private Sub Workbook_Activate()
Dim LangID As Long
LangID = Application.International(xlCountryCode)
Select Case LangID
Case 31: 'Call AddToCellMenuInDutch
Case 49: 'Call AddToCellMenuinGerman
Case Else: Call AddToCellMenu
End Select
End Sub
For more information about International issues visit :http://www.rondebruin.nl/international.htm
Disable or Enable a control on the Cell menu with VBA and RibbonX
VBA example for Excel 97-2010
To disable a control use always the ID and not the caption in your code.
If you use the caption, your code will not work when your workbook is used
in a different language version of Excel.
This will disable the Insert comment control for example on the Cell menu in Excel 97-2010.
Application.CommandBars("Cell").FindControl(ID:=2031).Enabled = False
But how do you find the ID's of each control on a contextmenu ?
You can use the add-in from Ole P. Erlandsen that you can find in the Tips section below.
Another way is to use a macro like this that adds the ID to the caption.
Remember that the Cell menu is not exactly the same in every Excel version.
Sub Add_ID_To_ContextMenu_Caption() 'Works in Excel 97 - 2010 'Add the Id to the caption of the contextmenu controls Dim ctl As CommandBarControl For Each ctl In Application.CommandBars("Cell").Controls On Error Resume Next ctl.Caption = ctl.ID & " ::: " & ctl.Caption On Error GoTo 0 Next ctl End Sub Sub Reset_ContextMenu() 'Works in Excel 97 - 2010 'Remove the Id of the caption of the contextmenu controls Dim ctl As CommandBarControl Dim myPos As Long For Each ctl In Application.CommandBars("Cell").Controls myPos = InStr(1, ctl.Caption, " ::: ", vbTextCompare) If myPos > 0 Then ctl.Caption = Mid(ctl.Caption, myPos + 4) End If Next ctl End Sub Sub Reset_ContextMenu_To_Factory_Defaults() Application.CommandBars("Cell").Reset End Sub
You can use the Activate and Deactivate events, like I showed you in the example that added the buttons
and menu to the Cell menu, also to disable and to enable controls.
For more information about Command bars and controls in Excel 97-2003 visit also this page
Disable Command bars and controls in Excel 97-2003
http://www.rondebruin.nl/menuid.htm
RibbonX example for Excel 2010
For example if we want to disable Delete in the Cell menu we can add this to the RibbonX example above.
<button idMso="CellsDelete" enabled="false" />
You see that if we want to disable a control on a contextmenu we must know it's idMso.
But we have a problem because this info is not available for every context menu.
For example for the Cell, Row and Column menu there is no information.
This is the reason :
MS only support a small set of controls in RibbonX, some controls that are available in some context
menus are controls that carried over from legacy versions (e.g. O12) so they don’t support them for extensibility through RibbonX. In some cases you can use the same name’s that are used for the Ribbon,
but is not guaranteed that this will work with every control.
I have try to find Insert Comment that I used in the VBA example but no luck.
As far as I know there is no list of controls that are supported in RibbonX.
But you can always use VBA code example above if you can't find a specific control ID.
Note: See the RibbonX tips section below for a link to a file with every control idMso of
each control in almost every ContextMenu.
Tips for the VBA and RibbonX examples
VBA example tips for Excel 97-2010:
How do I find the name of the contextmenu that I want to change ?
The example macro below will add button on the bottom of each contextmenu with the menu name.
You will notice that you will not see a name on each context menu when you run it in Excel 2007-2010.
For example, you will not see it when you right click on a shape or Picture in Excel 2007-2010.
So it not seems to be possible to change these menus in Excel 2007-2010 with VBA.
Sub Add_Name_To_Contextmenus()
Dim Cbar As CommandBar
For Each Cbar In Application.CommandBars
With Cbar
If .Type = msoBarTypePopup Then
On Error Resume Next
With .Controls.Add(Type:=msoControlButton)
.Caption = "Name for VBA = " & Cbar.Name
.Tag = "NameButtonInContextMenu"
End With
On Error GoTo 0
End If
End With
Next
End Sub
Sub Delete_Name_From_Contextmenus()
Dim Cbar As CommandBar
Dim ctrl As CommandBarControl
For Each Cbar In Application.CommandBars
With Cbar
If .Type = msoBarTypePopup Then
For Each ctrl In .Controls
If ctrl.Tag = "NameButtonInContextMenu" Then
ctrl.Delete
End If
Next ctrl
End If
End With
Next
End Sub
How do I find the control ID's or FaceID's :
Use the BtnFace add-in from Jim Rech to find every FaceId
Download it from my site
If you want to find the ID's and FaceId's see this page from Ole P. Erlandsen
http://erlandsendata.no/?p=2694
Check out this page from John Walkenbach to find every FaceId
http://spreadsheetpage.com/index.php/site/tip/identifying_commandbar_images/
RibbonX example tips for Excel 2010:
Add-in:
You see that I use "ContextMenuCell" as idMso for the Cell menu
But how do you find the names of the contextmenus ?
Microsoft ContextMenu Add-in for Office 2010
This is an Office 2010 (Excel, Outlook, PowerPoint, Project, Publisher, Word) COM Add-in.
It adds a button at the end of the context menus. The button should help you to find the NameX for that particular context menu.This is a very easy way for developers to find the idMso of the contextmenu.
http://code.msdn.microsoft.com/contextmenusaddin
If you want to know what the add-in's options in backstage view are about, this is the answer :
By default the add-in is packaged with XML files containing the information about the context menus in each application.The options in the backstage are to override the packaged XML’s with updated or custom XML files.
Useful files:
I used this for example in the RibbonX to tell where I wanted the controls
insertBeforeMso="Cut"
Or if you want to insert a built-in control you must use the idMso like: idMso="FileSave"
If you are looking for imageMso values or the control idMso values see the downloads on my Ribbon page :
http://www.rondebruin.nl/ribbon.htm#names
and
http://www.rondebruin.nl/ribbon.htm#images
The only problem is that you can't find the idMso's of the controls of every context menu.
MS only supports a small set of controls in RibbonX, some controls that are available in some context menus are controls that carried over from legacy versions (e.g. O12) so they don’t support them for extensibility through RibbonX. In some cases you can use the same name’s that are used for the Ribbon,
but is not guaranteed that this will work with every control.
This is not good if you want to add your control after a specific built-in control and can't find the correct
idMso or want to re-purpose or disable one of the controls and not know it's idMso.
Other Articles
Customizing Context Menus in All Versions of Microsoft Excel
http://msdn.microsoft.com/en-us/library/gg469862.aspx
Customizing Context Menus in Office 2010 (MSDN: Frank Rice)
http://msdn.microsoft.com/en-us/library/ee691832.aspx
Creating a PopUp Menu that is working in every Excel version
http://www.rondebruin.nl/popup.htm
Conclusion
Excel 97-2003
You can add controls to every context menu with VBA code (though I have not tested them all)
Not possible to change context menus with RibbonX
Excel 2007
You can add controls to almost every contextmenu with VBA code
Not possible to change for example the Shapes and Picture contextmenu with VBA
Not possible to change Context menus with RibbonX
Excel 2010
You can add controls to almost every contextmenu with VBA code
Not possible to change for example the Shapes and Picture toolbar with VBA
But you can add buttons/menus to every ContextMenu with RibbonX but if you want
to disable or re-purpose controls you may not be able to find the correct idMso(read this)