Skip to main content

MS Office - How to create a ribbon in Excel

Step-by-step guide on creating a custom VBA Excel Ribbon. Use XML and VBA to add your own tabs, groups, buttons, and powerful features to your Excel workbooks.

· 12 min read
View raw
Christophe
Markdown, WSL and Docker lover ~ Insatiable curious.
Cet article existe aussi en français — lire la version française.

Changelog

Latest
Updated two dead links: imageMso PNG download (hintdesk 404 → GitHub christianarielli/ImageMso) and Office Control Identifiers (MS Download 2010 404 → OfficeDev/office-fluent-ui-command-identifiers).

MS Office - How to create a ribbon in Excel

⚡
TL;DR

This article walks through building a custom Excel ribbon using the free CustomOfficeUIEditor tool and hand-written XML (the customUI14.xml manifest): defining tabs, groups, and controls like buttons and edit boxes, wiring their onAction/onChange events to VBA callback subroutines, and finding standard imageMso icon IDs to use on buttons.

In this post, we'll learn how to create a ribbon (i.e. a toolbar) in Microsoft Excel.

We'll create our custom ribbon for an Excel file, save the ribbon in the file so our users will have a nice and intuitive interface to work with our worksheet.

A ribbon is only useful if its buttons do something interesting. For a concrete example, MS Excel - Connect to a SQL Server database, run a query and get the results gives you the VBA behind a "Refresh data" button.

What we're going to build​

Here is the end result: our own tab, in Excel, with a button and an input field.

Smiley_and_edit

The button is wired to a VBA subroutine, so clicking it runs your code:

Button clicked

The whole thing is about fifteen lines of XML stored inside the workbook. Anyone opening your .xlsm file gets the ribbon; there's nothing to install on their machine.

Why it works​

  • An .xlsx / .xlsm file is not a binary blob: it's a ZIP archive with files and folders inside. You can open one with 7-Zip and look around.
  • Adding a ribbon means adding one file to that archive: a manifest called customUI14.xml, which describes the tabs, groups and controls in XML.
  • When MS Office opens the workbook, it reads that manifest, draws the ribbon and, on each click, calls the VBA subroutine named in the control's onAction attribute. Your macro and your interface are thus stored in the same single file.

Download the editor for free​

To be able to "easily" (in a not WYSIWYG interface) create a ribbon in MS Office, I'm using a very old tool called CustomOfficeUIEditor. Until now, I've not found any other free tool for doing this.

The tool can be downloaded from https://bettersolutions.com/vba/ribbon/custom-ui-editor-download.htm.

CustomOfficeUIEditor is an external tool (outside MS Office) which can open an Office file and add the needed files to create a ribbon. It's possible to do this without an editor, for instance by using a software like 7-Zip since a .xlsx / .xlsm file is an archive with files and folders.

For this exercise; please extract all files and folders to your C:\tmp\ribbon folder (create it).

Create an empty file​

As a support for this blog post, please create a new, empty, file in Excel called Ribbon.xlsm in your C:\tmp\ribbon folder (or elsewhere).

Excel Ribbon.xlsm

Just creates an empty file

Right now, we don't need to do anything other than File - New - Save as - FileType - Excel Macro-Enabled Workbook.

Add a ribbon in MS Office​

The CustomOfficeUIEditor tool isn't a user-friendly tool: you'll need to type yourself the XML of the ribbon. That XML is also called the manifest file.

By default, a standard MS Office document doesn't contain any ribbon so, when you open such files with the CustomOfficeUIEditor tool, you'll get an empty document.

Outlook is the exception: there, no XML is needed at all since the built-in Customize the Ribbon dialog can host a macro button, as done in Microsoft Outlook - VBA - Save emails as PDF.

Please start CustomOfficeUIEditor and open your Ribbon.xlsm file:

UI - Open Ribbon.xlsm

Make sure to close it first if still open in Excel

When using the editor, the file itself can't be opened in Excel! Imagine the following situation: the workbook is open both in the editor and in Excel. You make a lot of changes in Excel, switch to the editor and change the manifest. By saving the file in the editor, you'll lose every change made in Excel so... be careful.

The first time, you'll need to add a new ribbon: click on the Insert menu and select Office 2010 Custom UI Part.

Insert

You'll then obtain a screen like this:

Office 2010 Custom UI Part

When customUI14.xml is selected (like illustrated above), click somewhere in the right pane and start to code your XML content.

Now, in the right pane, just copy/paste the XML source below:

<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<ribbon>
<tabs>
<tab id="customTab" insertAfterMso="TabView" label="Tab">
<group id="customGroup" label="Group">
<button
id="customButton"
label="Button"
imageMso="HappyFace"
size="large"
onAction="OnButtonClicked" />
<editBox
id="customEditBox"
label="Edit Box"
onChange="OnEditBoxTextChanged" />
</group>
</tab>
</tabs>
</ribbon>
</customUI>

This XML file defines a custom ribbon interface for Microsoft Office, adding a new tab to the ribbon bar with a group containing a button and text input field. When the user clicks the button or changes the text, it triggers callback functions to handle those actions.

Manifest added

Before saving your file, be sure to click on the Validate button so a check is made to verify the quality of the content.

Check

Since the ribbon is correct, save the file and open it in Excel. If everything goes fine, you'll obtain this:

Sample

Your ribbon has been created

Congratulations, you've added a ribbon to your workbook. It was not too hard I think.

Under the Hood — the manifest, tag by tag (skip this if you just want a ribbon)​

Time to understand what has happened...

The root customUI node and the namespace​

<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">

This is the opening tag of a custom user interface (UI) definition file for Microsoft Office. It declares the XML namespace that tells Office which version of the custom UI schema this file follows, allowing Office to properly interpret all the UI elements that will be defined inside.

The manifest is an XML content and should be valid. You'll need to define your content into a <customUI> node (mandatory) and you'll need to specify the xmlns (for namespace) attribute (mandatory).

The namespace file will define what attributes exist, are mandatory or not, for each node type. The referred URL is the Document Type Definition (aka DTD).

For instance, when the user will click on the button of your ribbon, you'll wish to be able to capture the click and start a subroutine that you've coded in VBA. The "on click event" should be defined in the onAction attribute as defined in the DTD. Microsoft maintains the documentation here: https://msdn.microsoft.com/en-us/library/dd909370(v=office.12).aspx.

So, if you know that the attribute is onAction you can then add your own subroutine by typing something like onAction="OnButtonClicked".

The job of the DTD is to make sure that the syntax of your manifest is correct; therefore, the attribute xmlns="http://schemas.microsoft.com/office/2009/07/customui" is indeed mandatory.

Define the ribbon​

The ribbon should be defined inside the <ribbon> node but not immediately since a ribbon is, in fact, always defined in a tab.

Below we can see the standard ribbon of Excel and you can see a lot of tabs: File, Insert, Page layout, Formulas, Data, Review, View, ...

Tabs

Each tab comes with features (buttons, checkboxes, ...). For the Insert tab, we've first a group of three buttons into a group called Tables:

Insert - Group Tables

So, a ribbon should be:

  1. Define it in a tab (its own tab or an existing one)
  2. Add features in one or more groups (own groups or existing ones)

Below, our manifest now, with the definition of the ribbon.

<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<!-- highlight-next-line -->
<ribbon>
<!-- highlight-next-line -->
<tabs>
<!-- highlight-next-line -->
<tab id="customTab" insertAfterMso="TabView" label="Tab">
<!-- highlight-next-line -->
<group id="customGroup" label="Group">
<!-- highlight-next-line -->
YOUR FEATURES HERE
<!-- highlight-next-line -->
</group>
<!-- highlight-next-line -->
</tab>
<!-- highlight-next-line -->
</tabs>
<!-- highlight-next-line -->
</ribbon>
</customUI>

This is an XML configuration file that customizes the ribbon interface in Microsoft Office applications. It defines a custom tab named 'Tab' that will appear after the built-in 'View' tab, containing a group where you can add your own features or controls.

Define the tab​

You'll need to give an identifier to the tab (in the attribute called id): your own code for a new tab or the id of an existing tab.

The standard names are:

  • TabHome
  • TabInsert
  • TabPageLayoutExcel
  • TabFormulas
  • TabData
  • TabReview
  • TabView
  • TabDeveloper

So, if you want to add a button to the Home tab, just use TabHome as value for the id, f.i.,

<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<ribbon>
<tabs>
<!-- highlight-next-line -->
<tab id="TabHome">
<!-- highlight-next-line -->
ADD A BUTTON TO TabHome
<!-- highlight-next-line -->
</tab>
</tabs>
</ribbon>
</customUI>

This is an XML template for customizing the Microsoft Office ribbon interface. It defines the structure where you would add custom buttons and controls to the Home tab of an Office application like Word or Excel.

The XML below will, in one line,

  1. Create a new tab since the id customTab is not an existing id,
  2. Put the new tab after the existing View tab (use insertBeforeMso to add the tab before),
  3. And give it Tab as caption.
<tab id="customTab" insertAfterMso="TabView" label="Tab">

This XML snippet defines a custom tab element that will be inserted into a UI framework (likely Microsoft Office). The tab is given a unique identifier, positioned after an existing component called 'TabView', and labeled with the text 'Tab' for users to see.

Here is our added tab:

Add_new_tab

Implement our ribbon​

Inside the <tab> declaration, you need to define at least one <group>. And here too, you'll to define the identifier: an existing one for, f.i., adding a button in an existing group or a new one to create a new group.

The XML below will:

  1. Create a new group since the id is a new one (customGroup),
  2. And give it Group as name.
<group id="customGroup" label="Group">

This XML snippet defines a group element with a unique identifier and a display label. It's the opening tag for a container that will likely hold other XML elements inside it.

Our tab with its group:

Just a group defined

As you can see here above, just adding a group isn't enough, you'll need to define which features (buttons, checkboxes, ...) should be added in the group.

Add features​

The XML here below will add two things: a button and an edit box.

<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<ribbon>
<tabs>
<tab id="customTab" insertAfterMso="TabView" label="Tab">
<group id="customGroup" label="Group">
<!-- highlight-next-line -->
<button
<!-- highlight-next-line -->
id="customButton"
<!-- highlight-next-line -->
label="Button"
<!-- highlight-next-line -->
imageMso="HappyFace"
<!-- highlight-next-line -->
size="large"
<!-- highlight-next-line -->
onAction="OnButtonClicked" />
<!-- highlight-next-line -->
<editBox
<!-- highlight-next-line -->
id="customEditBox"
<!-- highlight-next-line -->
label="Edit Box"
<!-- highlight-next-line -->
onChange="OnEditBoxTextChanged" />
</group>
</tab>
</tabs>
</ribbon>
</customUI>

This XML defines a custom ribbon interface for Microsoft Office. It creates a new tab labeled 'Tab' that appears after the View tab, containing a group with a large button that triggers a function when clicked and an editable text box that calls a function whenever its text changes.

The XML below will create a button

  1. With an id initialized to customButton,
  2. Its label (the text that is displayed under the button) set to Button,
  3. Use the HappyFace standard image (imageMso is, indeed, the way to reuse a standard image while image allows you to define your own),
  4. The size of the button will be large (a big button),
  5. The action assigned will be the VBA function called OnButtonClicked.
<button
id="customButton"
label="Button"
imageMso="HappyFace"
size="large"
onAction="OnButtonClicked" />

This XML defines a button control for what appears to be an Office application (like Word or Excel). It sets up a large button labeled 'Button' with a happy face icon that will trigger a function called OnButtonClicked when someone clicks it.

This will result in this:

Smiley

OnButtonClicked is the VBA callback: to make it work, add a module in your Excel file, create a subroutine like this:

Public Sub OnButtonClicked(control As IRibbonControl)
MsgBox "You've clicked on the button", vbInformation
End Sub

To do this, in MS Excel, please press ALT-F11, in the Project explorer, right-click on the VBAProject (Ribbon.xlsm) entry (1), then select Insert (2) and Module (3).

Insert a module

A Module1 will be added and, in the right pane, please copy/paste the code given here above and save the file.

Add code

Now, you can close the Microsoft Visual Basic for Application window, go back to the well-known Excel window and click on the smiley button: you'll get the message box shown in the second screenshot at the top of this article.

And we can add other features, like an edit box:

<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<ribbon>
<tabs>
<tab id="customTab" insertAfterMso="TabView" label="Tab">
<group id="customGroup" label="Group">
<button
id="customButton"
label="Button"
imageMso="HappyFace"
size="large"
onAction="OnButtonClicked" />
<!-- highlight-next-line -->
<editBox
<!-- highlight-next-line -->
id="customEditBox"
<!-- highlight-next-line -->
label="Edit Box"
<!-- highlight-next-line -->
onChange="OnEditBoxTextChanged" />
</group>
</tab>
</tabs>
</ribbon>
</customUI>

This XML file defines a custom ribbon interface for Microsoft Office. It creates a new tab in the Office ribbon containing a group with a button and an editable text box, each wired up to trigger specific functions when the user interacts with them.

Save, reopen the file, and your tab now looks like the very first screenshot of this article.

The list of properties depends on the type: for a button, we have an onAction attribute while it's an onChange for an editBox.

List of objects​

As exhaustively defined in the ribbon's namespace, here is the list of valid objects:

  • box,
  • button,
  • buttonGroup,
  • checkBox,
  • control,
  • comboBox,
  • dropDown,
  • dynamicMenu,
  • editBox,
  • gallery,
  • labelControl,
  • menu,
  • splitButton and
  • toggleButton

Be careful: XML is case sensitive, editBox is the only valid syntax, editbox or EditBox aren't.

Each object comes with its own attributes, some are mandatory while the others are optional.

Find images​

By adding a button f.i., you'll assign an image to it.

You'll most probably use an existing, standard, image. This can be done by using the imageMso attribute and telling Office which image to use; f.i. AddFolderToFavorites:

Favorites

The manifest is this one:

<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<ribbon>
<tabs>
<tab idMso="TabHome" visible="false" />
<tab id="customTab" insertAfterMso="TabView" label="Tab">
<group id="customGroup" label="Group">
<button
id="customButton"
label="Button"
<!-- highlight-next-line -->
imageMso="AddFolderToFavorites"
size="large"
onAction="OnButtonClicked" />
</group>
</tab>
</tabs>
</ribbon>
</customUI>

This XML file defines a custom ribbon interface for Microsoft Office. It hides the standard Home tab, creates a new tab labeled 'Tab' after the View tab, adds a group within that tab, and puts a button in the group that calls a function named OnButtonClicked when clicked.

But ... how to retrieve the list of images?

Microsoft maintains Excel files with the list of existing IDs that can be used as icons in our ribbon. The Office Fluent User Interface Control Identifiers are maintained on the OfficeDev GitHub repository (current versions for all Office releases). You'll get Excel files, one file per application (Access, Excel, Outlook, ...).

This will give the list of existing IDs in plain text but you'll not see the associated images.

You can download all images (as PNG) for MS Office from the ImageMso GitHub repository (8,899 icons with a built-in Excel Add-In to browse them).

Assign callbacks​

This term means: which code (VBA in this case) should be fired when an event is raised.

When the user clicks on a button of the ribbon which subroutine should be called?

The XML code below assigns the OnButtonClicked subroutine to the onAction event of the button.

<button
id="customButton"
label="Button"
imageMso="AddFolderToFavorites"
size="large"
onAction="OnButtonClicked" />

This XML snippet defines a custom button control for an Office ribbon interface. It specifies the button's appearance (a large button with a folder icon), gives it an identifier and label, and wires it up to call a function named OnButtonClicked whenever someone clicks it.

So, if we wish to catch that event, we'll need to add a public subroutine in our Excel file, that subroutine can be placed in any module, should be public and should have OnButtonClicked as name.

But... depending on the callbacks (click, change, toggle state, change, ...), the definition of the subroutine is not the same.

For a button, the VBA should be something like:

Public Sub OnButtonClicked(control As IRibbonControl)
' YOUR CODE
End Sub

For an edit box and the onChange event, the callback is different:

<editBox
id="customEditBox"
label="Edit Box"
onChange="OnEditBoxTextChanged" />

This XML snippet defines a user interface element called an edit box—a text input field that users can type into. It gives the element an ID for reference, a label that describes it to users, and wires up a callback function that runs whenever the text inside changes.

Public Sub OnEditBoxTextChanged(control As IRibbonControl, sText As String)
' YOUR CODE
End Sub

The declaration of callbacks can be found on the official site: How can I determine the correct signatures for each callback procedure?. Pay attention to the Signatures columns; you need to look for VBA.

Conclusion​

A workbook that used to be "open the VBA editor, find the macro, run it" now has a tab of its own with real buttons; and it's all stored in the .xlsm file, so it follows the workbook wherever it goes. The two things to remember: the manifest is customUI14.xml inside the archive, and each control points to a public VBA subroutine through onAction (or onChange).

Once your ribbon is in place, a common next step is to feed one of its controls (like a dropdown) with data coming straight from your worksheet — see MS Office - Load dropdown from Excel's range. And to give your buttons something worth clicking, MS Excel - Connect to a SQL Server database is a good place to continue.


Was this article helpful?
Did you try the steps in this article?