Custom Excel Ribbon

The Excel Ribbon can be customized to provide a user-friendly way to use commands and VBA macros. There are different ways to customize the ribbon that provide different levels of customization and functionality.

XML Components

Note: This technique may no longer work.

The Excel ribbon can be customized using Office Open XML formats files. An Excel file is essentially a zip file containing the underlying components of the Excel file. Changing the file extension to .zip allows access to the underlying files of the Excel file and makes it possible to add XML components representing ribbon tabs, groups, and controls.

Process to Customize UI

1. Backup File

First make a backup of the original file you are going to customize. Files could be corrupted if the process is not done correctly.

2. Show File Extensions

In the Windows File Explorer check File Name Extensions to show file name extensions.

Show File Extensions

3. Change File Extension

Change the file extension of the file to zip. Right-click the file and select rename to edit the file extension. You will be prompted with a warning. Click yes.

Change File Extension From xlsm to zip
Change File Extension Warning

4. Add Custom UI Folder and File

Create a folder on the Desktop called customUI and inside the folder create a file called customUI.xml. Add XML to the file, save, and copy the folder into the zip folder.

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  <ribbon> 
    <tabs> 
      <tab id="MyCustomTab" label="Custom Tab"> 
        <group id="MyGroup" label="Custom Group">
          <button id="MyButton" imageMSO="HappyFace" label="Hello World" size="large" onAction="HelloWorld"/> 
        </group> 
      </tab> 
    </tabs> 
  </ribbon> 
</customUI>

The zip folder should like something like the image below:

Excel Zip Folder Items

5. Add a Relationship to rels file

Open the _rels folder and copy the .rels file to the Desktop. Inside the .rels file add a Relationship tag for the custom UI as the last tag inside the Relationships tag. Copy the .rels file back to the zip file and overwrite it.

<Relationship Id="MyCustomUI" Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility" Target="customUI/customUI.xml" />

6. Change Extension Back

Change the file extension back. If you recieve an error message saying the file was corrupted check that your XML is correct and the steps were followed correctly. If everything was done correctly you should be able to see your custom tab on the ribbon.

Custom XML Ribbon Tab

7. Add VBA to Handle Custom UI Controls

Add the procedures specified by callbacks and onAction attributes. To find the correct procedure signatures to use for a given type of control see here.

Option Explicit

Public Sub HelloWorld(ByVal Button As IRibbonControl)

    MsgBox "Hello, World!"

End Sub

Custom UI XML and VBA

To create the custom UI, XML elements must be added to the customUI.xml file. The root element is the customUI element. Inside the customUI element, there is a ribbon element which contains tabs which contain groups which contain controls. Elements can have certain attributes such as id, label, onAction, etc. Certain types of elements can be given specific attributes that use callback functions. For information about specific elements see the Elements section of the Microsoft Custom UI XML Specification. For more information about using these Elements, their attributes, and how to write VBA code to handle callbacks see this 3-part article: Part 1, Part 2, Part 3.

button

Custom Ribbon Button
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  <ribbon> 
    <tabs> 
      <tab id="MyCustomTab" label="Custom Tab"> 
        <group id="MyGroup" label="Custom Group">
          <button id="MyButton" imageMso="HappyFace" label="Hello World" size="large" onAction="HelloWorld"/> 
        </group> 
      </tab> 
    </tabs> 
  </ribbon> 
</customUI>
Option Explicit

Public Sub HelloWorld(ByVal Button As IRibbonControl)

    MsgBox "Hello, World!"

End Sub

checkBox

Custom Ribbon Checkbox
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui"> 
   <ribbon> 
     <tabs> 
       <tab id="MyCustomTab" label="Custom Tab"> 
         <group id="MyGroup" label="Custom Group"> 
           <button id="MyButton" imageMso="HappyFace" label="Hello World" size="normal" onAction="HelloWorld" />
           <checkBox id="checkBox" label="Check This" getPressed="CaptureState" onAction="CaptureState"/>
         </group > 
       </tab> 
     </tabs> 
   </ribbon> 
</customUI>
Option Explicit

Private CheckBoxValue As Boolean

Public Sub HelloWorld(ByVal Button As IRibbonControl)

    MsgBox "Checkbox Value is: " & CheckBoxValue

End Sub

Public Sub CaptureState(CheckBox As IRibbonControl, ByRef ReturnValue)

    CheckBoxValue = ReturnValue

End Sub

comboBox

Custom Ribbon Combobox

Comboboxes can be given static items by adding them directly into the XML or they can be filled dynamically using the combobox's callbacks.

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui"> 
   <ribbon> 
     <tabs> 
       <tab id="MyCustomTab" label="Custom Tab"> 
         <group id="MyGroup" label="Custom Group"> 
           <button id="MyButton" imageMso="HappyFace" label="Hello World" size="normal" onAction="HelloWorld" />
           <comboBox id="MyCombobox" label="Combo Box" getText="GetText" onChange="GetText">
             <item id="Item1" label="1" />
             <item id="Item2" label="2" />
             <item id="Item3" label="3" />
           </comboBox>
         </group > 
       </tab> 
     </tabs> 
   </ribbon> 
</customUI>
Option Explicit

Private ComboBoxText As String

Public Sub HelloWorld(ByVal Button As IRibbonControl)

    MsgBox "Combobox contains: " & ComboBoxText

End Sub

Public Sub GetText(ComboBox As IRibbonControl, Text)

    ComboBoxText = Text

End Sub
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="Init"> 
    <ribbon> 
        <tabs> 
        <tab id="MyCustomTab" label="Custom Tab"> 
            <group id="MyGroup" label="Custom Group"> 
            <button id="MyButton" imageMso="HappyFace" label="Hello World" size="normal" onAction="HelloWorld" />
            <comboBox id="MyCombobox" label="Combo Box" getText="GetText" getItemCount="GetItemCount" getItemID="GetItemID" getItemLabel="GetItemLabel" onChange="GetText"></comboBox>
            </group > 
        </tab> 
        </tabs> 
    </ribbon> 
</customUI>
Option Explicit

Private pRibbon         As IRibbonUI
Private ComboBoxItems() As String
Private ComboBoxText    As String

Public Sub Init(Ribbon As IRibbonUI)

    Set pRibbon = Ribbon

    ReDim ComboBoxItems(0 To 2)

    ComboBoxItems(0) = "One"
    ComboBoxItems(1) = "Two"
    ComboBoxItems(2) = "Three"

End Sub

Public Sub HelloWorld(ByVal Button As IRibbonControl)

    MsgBox "Combobox contains: " & ComboBoxText

End Sub

Public Sub GetText(ComboBox As IRibbonControl, Text)

    ComboBoxText = Text

End Sub

Public Sub GetItemCount(ComboBox As IRibbonControl, Count)

    Count = UBound(ComboBoxItems) - LBound(ComboBoxItems) + 1

End Sub

Public Sub GetItemID(ComboBox As IRibbonControl, Index As Integer, ID)

    ID = "ComboBoxItem" & Index + 1

End Sub

Public Sub GetItemLabel(ComboBox As IRibbonControl, Index As Integer, Label)

    Dim Arr(0 To 2) As String
    Arr(0) = "One"
    Arr(1) = "Two"
    Arr(2) = "Three"

    Label = ComboBoxItems(Index)

End Sub

dropDown

Custom Ribbon Dropdown
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="OnLoad"> 
    <ribbon> 
        <tabs> 
            <tab id="MyCustomTab" label="Custom Tab"> 
                <group id="MyGroup" label="Custom Group">  
                    <dropDown id="dropDown" label="DropDown" getItemCount="GetItemCount" getItemID="GetItemID" getItemLabel="GetItemLabel" onAction="OnAction">
                    <button id="MyButton" label="Button" onAction="ButtonOnAction" />
                    </dropDown>
                </group > 
            </tab> 
        </tabs> 
    </ribbon> 
 </customUI>
Option Explicit

Private pRibbon          As IRibbonUI
Private pDropDownItems() As String
Private pSelectedID      As String
Private pSelectedIndex   As String

Public Sub OnLoad(Ribbon As IRibbonUI)

    Set pRibbon = Ribbon

    ReDim pDropDownItems(0 To 2)

    pDropDownItems(0) = "One"
    pDropDownItems(1) = "Two"
    pDropDownItems(2) = "Three"

End Sub

Public Sub GetItemCount(DropDown As IRibbonControl, Count)

    Count = UBound(pDropDownItems) - LBound(pDropDownItems) + 1

End Sub

Public Sub GetItemID(DropDown As IRibbonControl, Index As Integer, ID)

    ID = "Item" & Index + 1

End Sub

Public Sub GetItemLabel(DropDown As IRibbonControl, Index As Integer, Label)

    Label = pDropDownItems(Index)

End Sub

Public Sub OnAction(DropDown As IRibbonControl, SelectedID As String, SelectedIndex As Integer)

    pSelectedID = SelectedID
    pSelectedIndex = SelectedIndex

End Sub

Public Sub ButtonOnAction(Button As IRibbonControl)

    If pSelectedIndex = vbNullString Then
        MsgBox "No Item Selected"
    Else
        MsgBox "Selected Item: " & pSelectedIndex & ", " & pSelectedID & ", " & pDropDownItems(pSelectedIndex)
    End If

End Sub

editBox

Custom Ribbon EditBox
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui"> 
    <ribbon> 
        <tabs> 
        <tab id="MyCustomTab" label="Custom Tab"> 
            <group id="MyGroup" label="Custom Group"> 
                <editBox id="MyEditBox" label="Edit Box" getText="CaptureText" onChange="CaptureText" />
                <button id="MyButton" label="Button" imageMso="HappyFace" onAction="ButtonClick" />
            </group > 
        </tab> 
        </tabs> 
    </ribbon> 
</customUI>
Option Explicit

Private EditBoxText As String

Public Sub CaptureText(EditBox As IRibbonControl, Text As String)

    EditBoxText = Text

End Sub

Public Sub ButtonClick(Button As IRibbonControl)

    MsgBox EditBoxText

End Sub

Menu

Custom Ribbon Menu
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui"> 
    <ribbon> 
        <tabs> 
            <tab id="MyCustomTab" label="Custom Tab"> 
                <group id="MyGroup" label="Custom Group">  
                    <menu id="MyMenu" label="Menu" imageMso="HappyFace" >
                        <button id="MyMenuButton1" label="Menu Button 1" imageMso="Heart" onAction="Heart"/>
                        <button id="MyMenuButton2" label="Menu Button 2" imageMso="Spade" onAction="Spade" />
                        <menuSeparator id="MyMenuSeparator" />
                        <button id="MyMenuButton3" label="Menu Button 3" imageMso="Diamond" onAction="Diamond" />
                        <button id="MyMenuButton4" label="Menu Button 4" imageMso="Club" onAction="Club" />
                    </menu>
                </group > 
            </tab> 
        </tabs> 
    </ribbon> 
 </customUI>
Option Explicit

Public Sub Heart(Button As IRibbonControl)

    MsgBox "Heart"

End Sub

Public Sub Spade(Button As IRibbonControl)

    MsgBox "Spade"

End Sub

Public Sub Diamond(Button As IRibbonControl)

    MsgBox "Diamond"

End Sub

Public Sub Club(Button As IRibbonControl)

    MsgBox "Club"

End Sub

splitButton

Custom Ribbon Split Button
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui"> 
    <ribbon> 
        <tabs> 
        <tab id="MyCustomTab" label="Custom Tab"> 
            <group id="MyGroup" label="Custom Group">  
                <splitButton id="MySplitButton" size="large" >
                    <button id="MyButton" imageMso="HappyFace" label="Split Button" onAction="MyButtonClick" />
                    <menu id="MyMenu">
                        <button id="MyMenuButton1" label="Menu Button 1" onAction="MyMenuButtonClick1" />
                        <button id="MyMenuButton2" label="Menu Button 2" onAction="MyMenuButtonClick2" />
                    </menu>
                </splitButton>
            </group > 
        </tab> 
        </tabs> 
    </ribbon> 
</customUI>
Option Explicit

Public Sub MyButtonClick(Button As IRibbonControl)

    MsgBox "My Button Clicked"

End Sub

Public Sub MyMenuButtonClick1(Button As IRibbonControl)

    MsgBox "My First Menu Button Clicked"

End Sub

Public Sub MyMenuButtonClick2(Button As IRibbonControl)

    MsgBox "My Second Menu Button Clicked"

End Sub

toggleButton

Custom Ribbon Toggle Button
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui"> 
    <ribbon> 
        <tabs> 
        <tab id="MyCustomTab" label="Custom Tab"> 
            <group id="MyGroup" label="Custom Group"> 
                <toggleButton id="MyToggleButton" label="Toggle Button" getPressed="CaptureState" onAction="CaptureState" />
            </group > 
        </tab> 
        </tabs> 
    </ribbon> 
 </customUI>
Option Explicit

Private ToggleState As Boolean

Public Sub CaptureState(ToggleButton As IRibbonControl, State)

    ToggleState = State

    MsgBox ToggleState

End Sub

VSTO

Visual Studio Tools for Office or VSTO are tools that can be installed and used with Visual Studio to develop solutions that work with Microsoft Office. VSTO can be used to customize the Excel ribbon either as an Add-In which works with any Excel Workbook or as a standalone Excel Workbook. VSTO solutions can be created using C# or VB.

Create VSTO Project

Add a new item to a VSTO project and select Ribbon (XML or Visual Designer).

Add Ribbon Visual Designer

When using the Visual Designer add controls using the Toolbox. Open the toolbox by pressing Ctrl + Alt + X or by selecting it from the View dropdown.

Visual Studio Toolbox

Drag controls from the Toolbox to the ribbon and then add code to the controls.

VSTO Customize Ribbon

Office Add-Ins

Office Add-Ins can be used to customize the UI. To customize the ribbon use Add-In Commands. See the Microsoft documentation for:

Manually Edit the Ribbon

Ribbon tabs can be added manually by navigating to File → Options → Customize Ribbon and then clicking the New Tab button. Groups can be added to a tab by clicking New Group. Macros and built-in commands can be added to the custom tab to provide functionality. Commands added to a custom tab can be renamed and assigned a new icon by highlighting the command and clicking rename. Customizations can be exported to customization files and then imported again later. To reset an individual ribbon or all ribbons, select from the Customizations drop down.

Add Custom Ribbon Tab Custom Ribbon Tab Rename Icon Custom Ribbon Tab

Add-Ins Tab

Adding a custom CommandBar will cause the Add-Ins tab to appear on the ribbon. To add a CommandBar use the Application.CommandBars property to retrieve the CommandBars collection and call the CommandBars.Add method. To add controls to the CommandBar, use the CommandBar.Controls property to get the CommandBarControls collection and use the CommandBarControls.Add method.

When using the CommandBarControls.Add method only certain types of controls can be created. Pass a valid member of the MsoControlType enumeration to the Type argument of the Add method to create a specific control.

Type Description
msoControlButton Creates a button.
msoControlEdit Creates a Text Box.
msoControlDropdown Creates a Dropdown.
msoControlComboBox Creates a combo box.
msoControlPopup Creates a button which opens a popup.

Some types of controls have a dedicated class that can be declared and others do not.

Class Description
CommandBarControl A generic control class that can be used to represent various types of controls.
CommandBarButton Represents a button on the CommandBar.
CommandBarComboBox Represents a combo box on the CommandBar.
CommandBarPopup Represents a popup control on the CommandBar.
'ThisWorkbook

Option Explicit

Private Const COMMAND_BAR_NAME As String = "CustomCommandBar"

Public CustomCommandBar As CommandBar

Private Sub Workbook_AddinInstall()
    
    Dim CBColl As CommandBars
    Set CBColl = Application.CommandBars
    
    'https://docs.microsoft.com/en-us/office/vba/api/office.commandbars.add
    Set CustomCommandBar = _
    CBColl.Add(Name:=COMMAND_BAR_NAME, Position:=msoBarTop, MenuBar:=False, Temporary:=True)
    CustomCommandBar.Visible = True
    
    'https://docs.microsoft.com/en-us/office/vba/api/office.commandbarcontrols.add
    
    'Button
    With CustomCommandBar.Controls.Add(Type:=msoControlButton, Temporary:=True)
        .Style = msoButtonCaption
        .Caption = "Button"
        .OnAction = "HelloWorld"
    End With
    
    'Combobox
    With CustomCommandBar.Controls.Add(Type:=msoControlComboBox, Temporary:=True)
        .AddItem "A"
        .AddItem "B"
        .AddItem "C"
        .Caption = "Combobox:"
    End With
    
    'Popup
    With CustomCommandBar.Controls.Add(Type:=msoControlPopup, Temporary:=True)
        .Caption = "Popup"
        'PopupButton
        With .Controls.Add(Type:=msoControlButton, Temporary:=True)
           .Style = msoButtonCaption
           .Caption = "Popup Button!"
           .OnAction = "HelloWorld"
        End With
    End With
    
    'TextEdit
    With CustomCommandBar.Controls.Add(Type:=msoControlEdit, Temporary:=True)
        .Caption = "TextEdit:"
    End With
    
    'Dropdown
    With CustomCommandBar.Controls.Add(Type:=msoControlDropdown, Temporary:=True)
        .AddItem "A"
        .AddItem "B"
        .AddItem "C"
        .Caption = "Dropdown:"
    End With
    
End Sub

Private Sub Workbook_AddinUninstall()

    'Delete Custom CommandBar
    
    If Not CustomCommandBar Is Nothing Then
        CustomCommandBar.Delete
        Set CustomCommandBar = Nothing
    End If
    
End Sub
'Module1

Option Explicit

Public Sub AlertMessage()

    MsgBox "Hello, World!"

End Sub
Add-Ins Ribbon Tab