[Some of the links in this Excel Tutorial are affiliate links, which means that if you choose to make a purchase, I will earn a commission. This commission comes at no additional cost to you.]
The Excel Ribbon is the main component of Excel's user interface.
If you do a quick online search, you'll notice that there are several forum threads where people ask for advice regarding the topic of customizing the Excel Ribbon with VBA.
If you're working with Visual Basic for Applications, you may be interested in creating a custom Excel Ribbon from time to time.
This is understandable. After all, there are several reasons why you may want to create a custom Excel Ribbon. In Mastering VBA for Microsoft Office 2016, author Richard Mansfield provides the following examples:
- Create dynamic Ribbon effects (for example, hiding, disabling or displaying particular items during run-time) based on particular criteria, such as the behavior of the user (for example, opening or closing a particular Excel workbook or an add-in).
- Hide features.
- Add-step through wizards.
- Create custom-designed Ribbons.
- Automate the management of the Ribbon.
Here's the deal:
Usually, customizing the Excel Ribbon has been considered to be unintuitive and difficult. For starters, if you follow the usual approach to customizing the Ribbon, you'll realize that your VBA knowledge isn't enough, but you also need to learn and understand XML (which I introduce below).
My purpose with this Excel tutorial is to provide you with the tools and information that will help you start creating custom Excel Ribbons immediately in just 7 steps (plus an optional eighth step), without the need to become an advanced VBA developer or having to learn XML. I discuss the main approaches to customizing the Excel Ribbon, along with the main reasons why I chose the approach and tools that I cover in this tutorial, below.
The following table of contents lists the main sections within this Excel tutorial:
Table of Contents
Let's start by understanding…
Excel Ribbon, Tabs, Groups And Buttons
If you've been using Excel for enough time, you probably know what the Ribbon, Ribbon tabs, Groups of Commands and Buttons are. However, as I show below, you'll probably work a lot with these elements whenever customizing the Ribbon.
Therefore, in this section, I provide a few screenshots and brief explanations of what each of these objects looks like within the Excel interface. Let's start with…
The Excel Ribbon
The following screenshot shows an Excel Ribbon.
The Ribbon was introduced in Excel 2007. The Ribbon replaces the previously existing menus and toolbars. Overall, as explained by Excel guru John Walkenbach in the Excel 2016 Bible, the Ribbon is simply “a collection of icons at the top of the screen“.
The Ribbon, as mentioned in Excel 2016 Power Programming with VBA, is organized in a hierarchy where:
- Tabs are across the top of the Ribbon.
- Tabs consist of Groups of Commands.
- Groups of Commands are composed of buttons and other controls.
The following sections show each of these items.
Ribbon Tabs
The Excel Ribbon groups commands in different tabs. Therefore, the commands that appear within the Ribbon change depending on which tab you've selected.
You can identify the different tabs using their labels, which appear above the icons of the Ribbon. The following screenshot shows an Excel Ribbon with 10 different tabs: (i) File, which takes you to the Backstage View, (ii) Home, (iii) Insert, (iv) Page Layout, (v) Formulas, (vi) Data, (vii) Review, (viii) View, (ix) RC, which is the Ribbon Commander tab, and (x) Developer.
The precise appearance of your Excel Ribbon may differ from the above. The following are some possible reasons for this:
- Add-Ins or other programs may add tabs to the Excel Ribbon. This is the case, for example, with the RC (Ribbon Commander) tab that appears in the screenshot above.
- Excel includes certain Contextual tabs. These tabs are displayed whenever needed. This is usually the case when you select certain objects (such as charts, shapes or tables) and Excel displays a Contextual tab that includes particular tools and features that you can use on that particular object.
- As I explain below, you can customize the Ribbon by, among others, adding new tabs or Groups of Commands.
Groups Of Commands
As I anticipate in the previous section, what commands that you can see in the Ribbon depends on which tab you've selected.
Within each tab, commands are further organized (or grouped) in different Groups of Commands.
For example, the following image displays the Home tab and its 7 Groups of Commands: (i) Clipboard, (ii) Font, (iii) Alignment, (iv) Number, (v) Styles, (vi) Cells, and (vii) Editing.
Buttons And Other Controls
At its most basic level, the Ribbon is composed of different controls. You access or execute commands through buttons and other controls that appear in the Ribbon.
There are several different styles of controls. I explain several of the most important ones, and how you can start creating them, below.
For the moment, as an example, let's take a look at the Font Group of Commands within the Home tab of the Ribbon.
This particular Group of Commands contains the following controls:
- Simple buttons, such as those corresponding to Increase Font Size and Decrease Font Size.
Whenever you click on a simple button, the relevant command is executed. - Toggle buttons, such as the Bold and Italics buttons.
Toggle buttons have 2 basic characteristics:
Characteristic #1: When you click on a toggle button, it toggles between 2 different states. In the example above, the Bold and Italics buttons toggle between applying or removing bold or italic formatting.
Characteristic #2: They display information about which of the 2 options is currently enabled. For example, the screenshot above shows that neither the bold or italic formatting is currently applied. The following screenshot shows how the Font Group of Commands looks like in Excel 2016 (the actual look is different if you're using an earlier version of Excel) if the italic formatting is currently applied: - Drop-down lists, such as the Font Face and Font Size drop-downs.
When you click on the arrow of a drop-down list, additional options appear below. For example, the following screenshot shows an expanded Font Face drop-down list. - Split buttons, such as the Underline, Borders, Fill Color and Font Color split buttons.
Split buttons are, roughly, a combination of (i) simple buttons and (ii) drop-downs. In other words, they have the following 2 parts:
Part #1: The simple button part. If you click on this part of the split button, the relevant command is executed.
Part #2: The drop-down part. If you click on this part, additional commands appear. - A dialog box launcher.
If you click on a dialog box launcher, Excel displays a dialog box that provides access to further commands that may not be available in the Ribbon. For example, when you click on the Font dialog box launcher that appears above, Excel displays the Format Cells dialog box, with the Font tab selected.
Custom Excel Ribbon: The Basics
The most basic way in which you can customize the Excel Ribbon is by using the features within the Excel Options dialog.
The Excel Options dialog allows you to customize a few aspects of the Ribbon, including the following:
- Adding new tabs and Groups of Commands.
- Adding additional commands.
- Hiding or unhiding tabs.
- Renaming tabs.
This way of modifying the Ribbon isn't what this post focuses on. I may write about this particular topic in a future blog post. If you want to receive an email when I publish new content in Power Spreadsheets, please feel free to register for our Newsletter by entering your email address below:
This doesn't mean that I consider these basic modifications useless. In fact, I usually use the Excel Options dialog for purposes of customizing the Ribbon and Quick Access Toolbar. I appreciate how easy and simple is to customize the Ribbon using the Excel Options dialog box.
However, if you rely solely on the Excel Options dialog box when customizing the Ribbon, you'll be subject to a few limitations.
In other words, modifying the Ribbon through the Excel Options dialog is easy and simple. It isn't particularly flexible nor powerful. As stated in Mastering VBA for Microsoft Office 2016:
VBA programmers may want to customize the Office applications' Ribbons programmatically (via macro code as opposed to the user manually manipulating the Options dialog box).
If you're searching for ways to modify the Ribbon with code, you may find that most resources make reference to RibbonX. I provide a few examples of useful resources and add-ins about this particular topic further below.
Following a similar line of thought, in Excel 2016 Power Programming with VBA, authors Dick Kusleika and Mike Alexander state that:
You can’t perform any Ribbon modifications using VBA. Rather, you must write RibbonX code and insert the code into the workbook file — outside of Excel.
This post doesn't focus on RibbonX either. As explained in Excel 2016 Power Programming with VBA:
The topic is complex enough to be the subject of an entire book.
For purposes of this tutorial, you probably just need to know that RibbonX:
- Is Extensible Markup Language (XML).
I provide a brief introduction to XML below. - Describes the characteristics of the controls within the Ribbon. These characteristics include the location and appearance of the control.
I may cover the topic of RibbonX in more detail within future blog posts. If you want to be notified whenever I publish new content in Power Spreadsheets, please feel free to register for our Newsletter by entering your email address below:
Another relatively common (although even more complex) way of modifying the Ribbon involves writing Component Object Model (COM) add-ins.
This post doesn't cover COM add-ins either.
The main reason why I chose to focus on the Ribbon Commander Framework within this Excel tutorial (instead of RibbonX or COM add-ins) is that, in my opinion, the Ribbon Commander is simply more convenient. In particular, I consider the Ribbon Commander Framework to be significantly easier to understand and use than the more traditional approaches to Ribbon customization.
For example, in Excel VBA Programming for Dummies, Excel guru John Walkenbach states that:
You can make automatic changes to the Ribbon with Excel 2007 and later versions, but it's not a simple task.
Walkenbach also states that (i) users may realize that modifying the Ribbon isn't particularly intuitive and (ii) XML “is way too complex for the beginner VBA programmer”.
Along similar lines, in Excel 2016 VBA and Macros, experts Bill Jelen (Mr. Excel) and Tracy Syrstad describe the process as being “not that simple” but “not impossible”.
The resources and Excel authorities I cite above were making reference (mostly) to how to customize the Ribbon using XML. Therefore, the comments above don't apply to the Ribbon Commander Framework that I cover in this blog post. As I mention at the beginning of this blog post, I consider that the Ribbon Commander Framework (combined with this Excel tutorial) allows you to easily start customizing the Excel Ribbon without the need to become an advanced VBA developer.
Despite this tutorial not focusing on RibbonX, you may find that some basic knowledge of XML helps you to better understand the procedure and example for customizing the Excel Ribbon that I describe further below, therefore, let's take a look at:
Extensible Markup Language (XML): A Brief Introduction
In Mastering VBA for Microsoft Office 2016, Author Richard Mansfield provides a good basic description of XML:
It's a way to surround data with descriptions of that data.
XML (as implied by its name) is a markup language. As explained in this thread at Stack Exchange, you can use markup languages “to control the presentation of data”. In other words, XML doesn't really do anything. It provides formatting or description information.
As a consequence of the above, statements that use XML usually have a structure such as the following:
- #1: A descriptive tag.
- #2: The data being described.
- #3: A closing tag.
In other words, when you use XML, data is usually enclosed by an opening and a closing tag.
However, as explained by experts Dick Kusleika and Michael Alexander in Excel 2016 Power Programming with VBA, XML sometimes uses self-closing tags. In this case, the structure of a statement is slightly different from the one I mention above.
Further to the above, the elements within XML are organized in a hierarchy. In other words, similar to what happens in the Excel VBA object model, each XML element can contain further (child) elements.
I provide further details of the Ribbon Commander object model in a section below.
For the moment, let's start to take a look at what you need to do to customize the Excel Ribbon. For these purposes, you must…
Download, Install And Activate The Ribbon Commander Before Beginning
As I mention in the previous sections, the method of customizing the Excel Ribbon that I explain in this blog post relies on the Ribbon Commander Framework. The Ribbon Commander is a framework for rapid Office user interface development.
The main purpose of the Ribbon Commander is to both simplify and extend the prevalent XML-based programming model for the Office user interface.
Therefore, for purposes of following through with this tutorial, and customizing the Excel Ribbon in the 7 (plus 1 optional) steps that I describe below, you must be able to access and use the Ribbon Commander framework. To achieve this, simply do the following:
Step #1: Download The Ribbon Commander
You can download the latest version of the Ribbon Commander by clicking here.
The Ribbon Commander comes with a 30-day free trial without restrictions to the framework functionality. You can also purchase a 1-year subscription by clicking here.
Step #2: Install The Ribbon Commander
You can find the instructions to install the Ribbon Commander here.
Step #3: Activate The Ribbon Commander
If necessary, please refer to the activation instructions here.
Once you have downloaded, installed and activated the Ribbon Commander, you're ready to continue with this tutorial and follow the example. Let's start the journey into the Ribbon Commander Framework.
Introduction To The Ribbon Commander Object Model
For this particular blog post focusing on the Excel Ribbon, I (mostly) make reference to the 2 following resources:
- Resource #1: The Ribbon Commander Documentation.
- Resource #2: The Custom UI XML Markup Version 2 Specification [MS-CUSTOMUI2] at the Microsoft Dev Center.
Some of the concepts that I introduce in other blog posts (such as The Essential Guide to Excel's VBA Object Model And Object References, VBA Object Properties: An Excel Tutorial or Object Methods In Excel VBA: Fundamentals Training) are roughly applicable and may help you understand the Ribbon Commander Framework. In my opinion, this is one of the main advantages of customizing the Excel Ribbon with the Ribbon Commander Framework.
Despite the above, the differences between the Ribbon Commander Framework and some of the other topics I cover in Power Spreadsheets are substantial enough to justify spending some time going through the main elements and the basic structure of the Ribbon Commander Framework's object model.
The object model is an object hierarchy of all the objects you can use. An object hierarchy has several levels:
- Level #1: At the top of the hierarchy, you have a single element.
This may be referred to as the root. - Level #2: The root contains some child elements or contained controls.
- Level #3: The elements in level #2 may contain further child elements or controls.
- …
- Level ##: Elements may contain other controls. If you continue going down the hierarchy long enough, you eventually reach a point where elements don't have any children.
To a certain extent, this way of organizing the different elements can help you understand what's going on within the Ribbon Commander Framework. More precisely, as explained in Mastering VBA for Microsoft Office 2016:
In XML, the order of the elements matters. XML is hierarchical (also known as nested or a tree), meaning that you need to put elements inside each other in the proper order.
In order to understand the Ribbon Commander Framework, let's start by taking a look at the root element, which sits at the top of the model hierarchy: rxCustomUI. This object models the CT_CustomUI element of the Custom UI XML Markup Version 2 Specification.
In other words, rxCustomUI is the root element that serves as the parent of all other elements within the custom user interface hierarchy.
As a consequence of the above, you'll see rxCustomUI being used constantly throughout this blog post.
rxCustomUI contains 6 controls:
- Control #1: rxBackstage.
rxBackstage models the CT_Backstage element of the Custom UI XML Markup Version 2 Specification. This element specifies a reference to the Backstage. - Control #2: rxCommands.
rxCommands models the CT_Commands element of the Custom UI XML Markup Version 2 Specification. This element specifies a list of commands. - Control #3: rxContextMenus.
rxContextMenus models the CT_ContextMenus element of the Custom UI XML Markup Version 2 Specification. It specifies a list of built-in context menu controls. - Control #4: namespaces.
Namespaces help you avoid conflicts of element names. Within the Ribbon Commander Framework, the namespaces element contains a collection of XML namespaces that can be used within the control's context. - Control #5: rxRibbon.
rxRibbon models the CT_Ribbon element of the Custom UI XML Markup Version 2 Specification. CT_Ribbon sets a reference to the main Ribbon of the relevant application. In this particular case, the specified reference is to Excel's Ribbon. - Control #6: ribbonXControls.
ribbonXControls makes reference to the collection of all Dynamic RibbonX controls contained within the relevant context.
Each of these controls, in turn, is capable of containing other controls. For example, rxRibbon (control #5 above) can contain the following 5 controls:
- Control #1: rxContextualTabs.
rxContextualTabs models the CT_ContextualTabs element of the Custom UI XML Markup Version 2 Specification. This element specifies a list of contextual tab sets. - Control #2: rxOfficeMenu.
rxOfficeMenu models the CT_officeMenu element of the Custom UI XML Markup Version 2 Specification. It specifies (and you use it to reference) the built-in Office Menu in Office 2007. - Control #3: rxQat.
rxQat models the CT_Qat element of the Custom UI XML Markup Version 2 Specification. This element specifies the Quick Access Toolbar. - Control #4: ribbonXControls.
As I explain above, ribbonXControls makes reference to the collection of contained RibbonX controls. - Control #5: tabs.
tabs models the CT_Tabs element of the Custom UI XML Markup Version 2 Specification. It specifies a collection of tab controls.
The process repeats itself. Each of these 5 controls can contain other controls. For example, a tab control (rxTab) contains the following 2 controls:
- Control #1: groups.
groups is a collection of Groups of Commands within a Ribbon tab. - Control #2: ribbonXControls.
ribbonXControls, as in the previous levels explained above, refers to the collection of contained RibbonX controls.
To finish the exploration of the section of the Ribbon Commander object model that is most relevant for purposes of this Excel tutorial, let's take a look at the 17 controls contained within a group (rxGroup) control:
- Control #1: boxes.
boxes is a collection of rxBox controls.
rxBox models the CT_Box element of the Custom UI XML Markup Version 2 Specification. More precisely, rxBox is a grouping container. The child controls of this container are then aligned horizontally or vertically. - Control #2: buttonGroups.
buttonGroups is a collection of rxButtonGroup controls.
rxButtonGroup models the CT_ButtonGroup element of the Custom UI XML Markup Version 2 Specification. rxButtonGroup is also a grouping container. Child controls of rxButtonGroup are visually grouped together. - Control #3: buttons.
buttons is a collection of rxButton controls.
rxButton models the CT_Button element within the Custom UI XML Markup Version 2 Specification. You can use rxButton to specify a standard push button. In other words, these are what I describe above as simple buttons. - Control #4: checkBoxes.
checkBoxes is a collection of rxCheckBox controls.
rxCheckBox models the element CT_CheckBox of the Custom UI XML Markup Version 2 Specification. You can use rxCheckBox to specify a standard check box control. - Control #5: comboBoxes.
comboBoxes is a collection of rxComboBox controls.
rxComboBox models the CT_ComboBox element of the Custom UI XML Markup Version 2 Specification. You can use rxComboBox to specify a standard combo box control. - Control #6: controls.
controls is a collection of rxControlClone controls.
rxControlClone models the element CT_ControlClone of the Custom UI XML Markup Version 2 Specification. You can use the controls of this collection to enable, disable or clone built-in controls. - Control #7: dialogLauncher.
dialogLauncher is a collection of rxDialogLauncher controls.
rxDialogLauncher models the CT_DialogLauncher element of the Custom UI XML Markup Version 2 Specification. rxDialogLauncher allows you to specify a button that opens an additional UI. I show an example of a built-in dialog box launcher above. - Control #8: dropDowns.
dropDowns is a collection of rxDropDownRegular controls.
rxDropDownRegular models the element CT_DropDownRegular within the Custom UI XML Markup Version 2 Specification. You can use rxDropDown to specify a standard drop-down control. - Control #9: dynamicMenus.
dynamicMenus is a collection of rxDynamicMenu controls.
rxDynamicMenu models the CT_DynamicMenu element of the Custom UI XML Markup Version 2 Specification. rxDynamicMenu allows you to specify a particular menu control where the contents are dynamically populated at run time. - Control #10: editBoxes.
editBoxes is a collection of rxEditBox controls.
rxEditBox models the element CT_EditBox within the Custom UI XML Markup Version 2 Specification. You can use rxEditBox to specify a standard edit box control. - Control #11: galleries.
galleries is a collection of rxGallery controls.
rxGallery models the CT_Gallery element of the Custom UI XML Markup Version 2 Specification. rxGallery allows you to specify “a gallery control that displays a drop-down grid of selection items”. - Control #12: labelControls.
labelControls is a collection of rxLabelControl controls.
rxLabelControl models the element CT_LabelControl within the Custom UI XML Markup Version 2 Specification. You can use rxLabelControl to specify a control displaying a string. - Control #13: menus.
menus is a collection of rxMenu controls.
rxMenu models the CT_Menu element of the Custom UI XML Markup Version 2 Specification. rxMenu allows you to specify a standard drop-down menu control. - Control #14: ribbonXControls.
ribbonXControls is the collection of all contained RibbonX controls. - Control #15: separators.
separators is a collection of rxSeparator controls.
rxSeparator models the element CT_Separator within the Custom UI XML Markup Version 2 Specification. You can use rxSeparator to specify a vertical line separator control. - Control #16: splitButtons.
splitButtons is a collection of rxSplitButton controls.
rxSplitButton models the CT_Splitbutton element of the Custom UI XML Markup Version 2 Specification. rxSplitButton allows you to specify a split button. Split buttons, as I explain above, contain (i) a primary (or simple) button, and (ii) a drop-down menu. - Control #17: toggleButtons.
toggleButtons is a collection of rxToggleButton controls.
rxToggleButton models the element CT_ToggleButton within the Custom UI XML Markup Version 2 Specification. You use rxToggleButton to specify a toggle button control. I provide some examples of built-in toggle buttons within Excel above.
Notice how several of these controls match the 5 types of commands that appear within the Font Group of Commands within the Home Tab of the Ribbon.
Going into the details (such as properties and delegates) of all of these controls exceeds the scope of this tutorial. I may, however, cover them in future blog posts. If you want to receive an email whenever I publish new content in Power Spreadsheets, please register for our Newsletter by entering your email address below:
Graphically, the portion of the Ribbon Commander Framework object model that I describe above looks roughly as follows:
The image above shows a limited portion of the Ribbon Commander Framework. Based on this, it may seem that identifying the elements you need for purposes of working with the Ribbon Commander Framework is a complicated task.
Fortunately, this isn't really the case. As explained by author Richard Mansfield in Mastering VBA for Microsoft Office 2016, when you're working with the Ribbon, the usual order of elements you need to understand is as follows:
- Element #1: Ribbon.
- Element #2: Tabs.
- Element #3: Tab.
- Element #4: Group.
- Element #5: Button, or other relevant control.
In fact, below, you can see how I use precisely this hierarchy when customizing the Excel Ribbon with the Ribbon Commander Framework. Additionally, notice that the list of elements suggested by Mansfield precisely matches the main Ribbon elements that I introduce at the beginning of this tutorial.
Now that you have a good idea of how the object model of the Ribbon Commander Framework works, and the main objects you'll be working with, let's take a look at…
Properties, Methods, Delegates And Events In The Ribbon Commander Framework
In addition to containing other elements (as I explain in the previous section), each of the elements within the Ribbon Commander Framework has properties, methods, delegates and events.
- Properties are, generally, the attributes of an object. In other words, they describe the objects.
- Methods are, from a general perspective, the actions or operations that you can perform with a particular object.
A special type of method you'll be working with in the Ribbon Commander Framework are static methods. Generally, you can use static methods even if you haven't initialized the relevant class. In other words, you can invoke a static method even if an instance of the relevant class doesn't exist yet. - Delegates are, from a broad perspective, pointers.
To understand delegation, it may be helpful if you think in terms of sender and receiver. Usually, when the sender receives a request, it points to the receiver. The receiver is generally the element that actually does the work. - Events are, as implied by their name, simply something (an action) that happens.
Don't worry if things aren't absolutely clear at the moment. In the sections below, I explain some of the most important properties, methods, delegates and events you need to understand when working with the Ribbon Commander Framework.
To do this, let's take a look at a practical example of a program you can use to customize the Ribbon by using the Ribbon Commander Framework.
Create A Custom Excel Ribbon Using VBA: Example
For purposes of this tutorial, I'll show you how to create a custom Excel Ribbon using the Ribbon Commander Framework in 7 (plus 1 optional) easy steps. The resulting sample Sub procedure is called “Custom_Ribbon”.
This Excel VBA Custom Ribbon Tutorial is accompanied by an Excel workbook containing the macros I use (including the “Custom_Ribbon” Sub procedure). You can get immediate free access to this example workbook by subscribing to the Power Spreadsheets Newsletter.
Step #1: Create A Reference To rxCustomUI
As I explain above, the object at the top of the Ribbon Commander Framework model is rxCustomUI.
Therefore, rxCustomUI is the parent of all the other elements you'll be working with throughout this example.
For purposes of getting the reference to the relevant rxCustomUI instance, you can use either of the following 2 static methods of rxCustomUI:
- Static Method #1: create.
create is the factory method you use for purposes of working with rxCustomUI objects. The consequence of using create depends on whether the relevant context already exists or not:
If the context doesn't exist, the create method creates a new context.
If the context already exists, the rxCustomUI object created by the create method joins the previously existing context. - Static Method #2: defaultInstance.
defaultInstance, as implied by its name, makes reference to the default rxCustomUI object within the current session.
For this particular example, I'll use defaultInstance. defaultInstance doesn't have any parameters.
Therefore, I start the Custom_Ribbon procedure by inserting the following 2 statements:
Dim myCustomUI As rxCustomUI
Set myCustomUI = rxCustomUI.defaultInstance
Let's take a closer look at the 2 lines of code above to understand what they do:
Line #1: Dim myCustomUI as rxCustomUI
This line of code uses the Dim statement to declare the myCustomUI object variable. myCustomUI is declared as of the rxCustomUI object type.
Line #2: Set myCustomUI = rxCustomUI.defaultInstance
You can use the Set statement to assign an object to an object variable. In this particular case:
- The assigned object is rxCustomUI.defaultInstance (the default rxCustomUI object).
- The object variable to which the object is assigned is myCustomUI.
Despite the above, whenever you're creating production code, the recommendation is to rely on the create method for purposes of avoiding potential conflicts with other applications. Therefore, let's take a quick look at the main parameters of…
The Create Method
The create method has the following 4 parameters:
- Parameter #1: contextID.
contextID is a string that identifies the context. It's default value is null. - Parameter #2: description.
As implied by its name, description is a string that describes the context. It's default value is “Ribbon Commander”.
The description parameter only has an effect when you're creating a new context. In other words, if the rxCustomUI object created by the create method joins a previously existing context, description doesn't have an effect. - Parameter #3: dispatchScope.
dispatchScope allows you to determine the dispatch mode of the rxCustomUI context. The dispatch scope is what determines which parts of a program can access or refer to the rxCustomUI context. The dispatchScope parameter can take either of the following 2 rxDispatchScope values:
Value #1: DispatchScope_local which, as implied by its name, results in local (VBA class) dispatch.
DispatchScope_local is the default value of the dispatchScope parameter.
Value #2: DispatchScope_global which, as you may imagine, results in global (VBA standard module) dispatch.
One of the main differences between using DispatchScope_local and DispatchScope_global is the lifetime of the relevant context.
If you use DispatchScope_local, the lifetime of the context is tied to the lifetime of the rxCustomUIs within the context. As explained within the Ribbon Commander documentation, “when the last rxCustomUI of the context is destroyed, the context is also destroyed”.
On the other hand, when you use DispatchScope_global, the relevant rxCustomUI is added to the globalCustomUIs collection. This collection includes all the rxCustomUIs within the current session that have a global dispatch. This includes, among others, the default rxCustomUI object (defaultInstance) to which I make reference above. This particular member of the collection is read-only. As a consequence, you can't remove the default rxCustomUI object from the globalCustomUIs collection.
Once an rxCustomUI is added to the globalCustomUIs collection, you must explicitly remove it from the collection for purposes of destroying it. - Parameter #4: customUIMode.
You can use customUIMode to specify the state or mode of the relevant rxCustomUI context. The customUIMode parameter can take either of the following 2 rxCustomUIMode values:
Value #1: CustomUIMode_static, which refers to static mode.
Value #2: CustomUIMode_dynamic, which refers to dynamic mode.
CustomUIMode_dynamic is the default parameter value. Since it generally allows for smoother rendering, it's also the suggested choice.
In a previous section, I quote technology author Richard Mansfield, who states that the usual order of elements you work with within the Excel Ribbon is as follows:
- Element #1: Ribbon.
- Element #2: Tabs
- Element #3: Tab.
- Element #4: Group.
- Element #5: Button, or other relevant control.
In the following steps, I show how you can start working with each of these elements when using the Ribbon Commander framework to create a custom Excel Ribbon. Let's start with element #1:
Step #2: Create A Reference To The Ribbon
As explained within this example within the Ribbon Commander documentation:
Each rxCustomUI object owns a unique rxRibbon object.
As I explain above, rxRibbon:
- Is one of the controls contained within rxCustomUI.
- Models the CT_Ribbon element of the Custom UI XML Markup Version 2 Specification.
- Creates a reference to the main Ribbon of the relevant application.
To create a reference to the Ribbon, I use the following 2 statements. Notice that they're materially similar to those that I use above when creating a reference to rxCustomUI.
Dim myRibbon As rxRibbon
Set myRibbon = myCustomUI.ribbon
At this point, the sample Custom_Ribbon Sub procedure looks as follows:
The 2 new lines of code proceed in a substantially similar way as that I explain in the previous step #1. In other words:
- Line #1 (Dim myRibbon As rxRibbon) uses the Dim statement to declare the myRibbon object variable. myRibbon is declared as of the rxRibbon object type.
- Line #2 (Set myRibbon = myCustomUI.ribbon) uses the Set statement to (i) assign the main Ribbon within the rxCustomUI instance (myCustomUI.ribbon) to (ii) the myRibbon object variable.
Once the Sub procedure has the reference to the Ribbon, we can proceed to the next element we need to work with:
Step #3: Create A New Tab
When I introduce the object model of the Ribbon Commander Framework above, I list tabs as one of the controls contained within rxRibbon. As I explain there, tabs:
- Models the CT_Tabs element of the Custom UI XML Markup Version 2 Specification.
- Specifies a collection of tab controls.
However, most of the time you work with a particular object from a collection.
This is the rule that applies in this case. Therefore, to insert a new Ribbon tab, you use rxTab. rxTab:
- Models the CT_Tab element of the Custom UI XML Markup Version 2 Specification.
- Specifies a Ribbon tab control.
rxTab has 15 properties. Several of them model the equivalent attributes of the CT_Tab element within the Custom UI XML Markup Version 2 Specification.
Within the sample Custom_Ribbon Sub procedure that I show within this tutorial, I only use 2 properties. These are keytip and label, which I explain below.
However, since you may need to work with other properties of rxTab, let's take a look at them. For these purposes, I group the 15 properties of rxTab in the following 4 groups:
Group #1: ID Properties (3 Properties)
You can use the following 3 properties to specify identifiers of different elements or controls:
- Property #1: id.
id makes reference to the identifier of the custom UI element. id models a ST_UniqueID attribute of the Custom UI XML Markup Version 2 Specification. - Property #2: idMso.
idMso refers to the identifier of a built-in control. idMso models an ST_ID attribute of the Custom UI XML Markup Version 2 Specification. - Property #3: idQ.
idQ is a qualified control identifier. Qualified control IDs can be useful, as they allow different add-ins to modify the same custom object (such as a group or tab).
idQ models a ST_QID attribute of the Custom UI XML Markup Version 2 Specification. You can generally use idQ to refer to controls or elements that are created by other custom UI documents.
As a general rule:
- Identifiers should be unique. Therefore, all custom UI elements must have a unique ID.
- id, idMso and idQ are mutually exclusive. Therefore, you shouldn't use them together. Specify a single one of the properties on your custom controls.
In general, as explained in Mastering VBA for Microsoft Office 2016, “Mso” stands for Microsoft Office and, when appended to a particular property, it makes reference to built-in items. Similarly, “Q” stands for qualified. Plain properties that don't use the Mso or Q suffixes (such as id above), are generally references to custom elements.
Group #2: Insertion Location Properties (4 Properties)
You can use the following 4 properties for purposes of specifying the location where the new tab is to be inserted:
- Property #1: insertAfterMso.
insertAfterMso allows you to specify the built-in control after which the control you're referring to is inserted.
insertAfterMso works with built-in controls. Therefore, you work with idMso identifiers, as I explain in the previous section. - Property #2: insertBeforeMso.
insertBeforeMso is the opposite of insertAfterMso. In other words, you can use insertBeforeMso to specify the built-in control before which the control you're working with is inserted. - Property #3: insertAfterQ.
insertAfterQ is similar to insertAfterMso. Therefore, you can use it to specify the control after which the control you're referring to is inserted.
The main difference is that insertAfterMso works with built-in controls, which insertAfterQ works with qualified controls. Therefore, when working with insertAfterQ, you use idQ identifiers, as I explain in the previous section. - Property #4: insertBeforeQ.
insertBeforeQ is the opposite of insertAfterQ. Therefore, you use insertBeforeQ to specify the qualified identifier of the control before which the control you're working with is inserted.
Generally:
- insertAfterMso, insertAfterQ, insertBeforeMso and insertBeforeQ are mutually exclusive. Therefore, you shouldn't use these properties together.
- If you don't specify any of these properties: (i) the relevant control is appended to the existing controls and (ii) the order in which controls are organized is that set forth in the applicable XML.
Group #3: Read-Only Properties (2 Properties)
The following 2 properties are read-only. Therefore, you can't modify them.
- Property #1: isEmpty.
isEmpty allows you to check if the relevant control is empty or not. If the control is empty, isEmpty returns the Boolean value rxTrue. - Property #2: isLive.
isLive can be used to check if the relevant control is live or not. If the control is live, isLive returns rxTrue.
Group #4: Other Properties (6 Properties)
The following are the remaining 6 properties of rxTab:
- Property #1: keytip.
keytip allows you to specify a particular string that acts as the KeyTip for a control. If you don't specify a keytip string, no KeyTip is displayed.
keytip models a ST_Keytip attribute of the Custom UI XML Markup Version 2 Specification. - Property #2: label.
label allows you to specify a string to be displayed as the control label. If you don't specify the label property, no label is displayed. - Property #3: parent.
parent makes reference to the parent object of the control you're working with. - Property #4: tag.
tag is custom data. - Property #5: visible.
visible is a Boolean property (rxTrue or rxFalse) that allows you to specify whether the control you're working with is visible or not. The default value is to make the control visible. - Property #6: xml.
xml, as explained within the Ribbon Commander documentation, “returns the xml node that corresponds to the state of the control.”
Now that you have a good idea of the different properties of rxTab, let's go back to the sample Custom_Ribbon Sub procedure and see how we can create a new tab:
For these purposes, I include the following statements in the sample macro:
Dim myTab As rxTab
Set myTab = New rxTab
With myTab
.keytip = “Y2”
.Label = “Power Spreadsheets”
End With
myRibbon.tabs.Add myTab
Let's take a closer look at each of the new lines of code:
Line #1: Dim myTab As rxTab
As in the previous 2 steps (creating references to the rxCustomUI and the Ribbon), I start by using the Dim statement to declare the myTab object variable. I declare myTab as an rxTab object.
Line #2: Set myTab = New rxTab
Once again, as in the previous 2 steps, I use the Set statement to assign an object to an object variable. In this case:
- The assigned object is a new rxTab (New rxTab). For these purposes, I use the New keyword.
- The object variable to which the object is assigned is myTab.
Lines #3 And #6: With myTab | End With
These 2 lines of code are the opening and closing lines of a With… End With block.
The main purpose of a With… End With block is to simplify the syntax of the macro. This is achieved by executing several statements on a single object.
In the example we're looking at, all of the statements within the With… End With block (lines #4 and #5 below) are executed on the object represented by the myTab object variable.
Line #4: .keytip = “Y2”
This statement sets the keytip property of myTab to be equal to the string “Y2”. In other words, this line of code specifies that the KeyTip of the newly created tab is “Y2”.
As a consequence of the above, the resulting keyboard shortcut is “Alt + Y2”.
In case you're curious, the reason why I chose “Y2” as keytip is because the keytip for the Ribbon Commander is “Y1”.
When you're creating your own custom Excel Ribbon, you can set a different keytip property value, or avoid specifying one. If you choose to set up a KeyTip for your new tab, bear in mind any other previously existing KeyTips for purposes of avoiding conflicts.
Line #5: .Label = “Power Spreadsheets”
This line of code sets the label property of myTab. I set the label to be equal to the string “Power Spreadsheets”.
Line #7: myRibbon.tabs.Add myTab
As I mention above, tabs specifies a collection of tab controls.
In the previous lines of code within this step #3, I make reference to myRibbon. myRibbon is an object variable holding an rxTab. In other words, I use rxTab for purposes of specifying an individual tab control.
This line of code #7 makes reference to the tabs RibbonX collection. More precisely, it uses the add method to add an item (myTab) to the collection.
Now that the custom Ribbon has a new tab, we can move on to the next element we need to work with:
Step #4: Create A New Group Of Commands
rxTab is the parent of 2 controls, which are contained within it:
- groups, which is a collection of groups.
- ribbonXControls, which is a collection that includes all contained ribbonX controls.
In other words, any rxTab has a collection of rxGroup objects.
rxGroup models the CT_Group element of the Custom UI XML Markup Version 2 Specification. rxGroup “specifies a grouping of controls” within a tab.
rxGroup has 21 different properties. However, 15 of these properties mirror properties of rxTab, which I explain above. Therefore, let's start by pointing out which are these properties, whose basic characteristics I introduce in the previous section.
- Property #1: id.
You can use id to specify the identifier of a custom control. - Property #2: idMso.
idMso allows you to specify the identifier of a built-in control. - Property #3: idQ.
idQ specifies the qualified identifier of a control. - Properties #4 And #5: insertAfterMso and insertBeforeMso.
insertAfterMso and insertBeforeMso allow you to specify the built-in control after (in the case of insertAfterMso) or before (with insertBeforeMso) which the control you're working with is inserted. - Properties #6 And #7: insertAfterQ and insertBeforeQ.
insertAfterQ and insertBeforeQ work in a similar way to insertAfterMso and insertBeforeMso. The main difference between insertAfterQ (vs. insertAfterMso) and insertBeforeQ (vs. insertBeforeMso) is that insertAfterQ and insertBeforeQ work with qualified identifiers of controls, whereas insertAfterMso and insertBeforeMso work with identifiers of built-in controls. - Properties #8 And #9: isEmpty and isLive.
isEmpty and isLive are read-only properties (you can't modify them) that you can use for purposes of checking (i) whether the control is empty (with isEmpty) or (ii) where the control is live (with isLive). These properties return the Boolean values rxTrue and rxFalse. - Property #10: keytip.
keytip allows you to set a KeyTip for the control. - Property #11: label.
You can use label to specify the label of the control. - Property #12: parent.
parent is the parent of the control. - Property #13: tag.
tag is custom data. - Property #14: visible.
You can use visible to determine whether the control is visible or not. - Property #15: xml.
xml returns the xml node corresponding to the control's state.
As mentioned above, I explain all of these properties more thoroughly in the relevant section above.
Considering the above, there are only 6 properties of rxGroup that I don't explain in previous sections of this blog post. Let's take a closer look at them:
- Property #1: autoScale.
You can use autoScale to determine whether the contents within the relevant control resize automatically as the size of the window in which they're displayed changes.
autoScale is a Boolean property. Its default value is rxFalse. Therefore, if you omit the autoScale property, the contents of the Group of Commands aren't automatically resized. - Property #2: centerVertically.
centerVertically allows you to specify whether the contents of the control are centered vertically within the relevant container.
centerVertically is also a Boolean property. Its default value is also rxFalse. As a consequence, whenever you omit the centerVertically property, the contents of the Group of Commands are aligned at the top of the applicable container (instead of being centered vertically). - Property #3: image.
image which is the property you use to specify a custom image or icon for the control.
image models an ST_Uri attribute of the Custom UI XML Markup Version 2 Specification. - Property #4: imageMso.
You can use imageMso to specify a built-in image or icon for the control.
imageMso models an ST_ID attribute of the Custom UI XML Markup Version 2 Specification.
imageMso is substantially similar to the image property. Their main difference is that image works with a custom image or icon, whereas imageMso works with a built-in image.
image and imageMso are mutually exclusive. Therefore, you should use one or the other. If you use neither, no icon is displayed. - Property #5: screentip.
screentip allows you to specify a string for a ToolTip (a small window with descriptive text displayed on mouse hover) for the control.
If you don't use the screentip property, no ToolTip is displayed. - Property #6: supertip.
You use supertip to specify a string for an Enhanced ScreenTip (larger than regular ToolTip).
If you don't specify the supertip property, no Enhanced ScreenTip is displayed.
Now that you're aware of the different properties of rxTab, let's take a look at how you can use this information to include a new Group of Commands within the new tab created in step #3 above for the custom Ribbon:
For these purposes, I add the following statements:
Dim myCommandGroup As rxGroup
Set myCommandGroup = New rxGroup
With myCommandGroup
.autoScale = rxTrue
.CenterVertically = rxFalse
.Label = “Example Macros”
End With
myTab.groups.Add myCommandGroup
Notice that the structure of the newly added lines of code is substantially similar to the code added in step #3 above (when I created a new tab):
Let's take a look at new lines of code:
Line #1: Dim myCommandGroup As rxGroup
As in the other similar statements explained previously, this line of code uses the Dim statement to declare the myCommandGroup object variable. myCommandGroup is declared as of the rxGroup object type.
Line #2: Set myCommandGroup = New rxGroup
Following other similar statements, this line of code uses the Set statement to assign an object to an object variable. More precisely, this statement (i) assigns a new rxGroup (New rxGroup) to (ii) the myCommandGroup object variable.
Lines #3 & #7: With myCommandGroup | End With
These statements are exactly the same as those in lines #3 and #6 of the previous step #3, where I created a new tab. They are the opening and closing lines of a With… End With block.
As a consequence of using the With… End With construct, all of the statements within the block (lines #4, #5 and #6 below) are executed on the object represented by the myCommandGroup object variable.
Line #4: .autoScale = rxTrue
This statement sets the autoScale property of myCommandGroup to rxTrue.
As a consequence, the contents within myCommandGroup automatically resize when the size of the containing window changes.
Line #5: .CenterVertically = rxFalse
This line of code sets the CenterVertically property of myCommandGroup to rxFalse.
The consequence of this is that the contents of myCommandGroup aren't centered vertically. Rather, they're aligned at the top of the container.
Line #6: .Label = “Example Macros”
This is the equivalent of line #5 in the previous step #3 (adding a new tab).
The statement sets the label property of myCommandGroup to be “Example Macros”.
Line #8: myTab.groups.Add myCommandGroup
This line mimics line #7 of the previous step #3 (when I added a new tab to the Ribbon).
This line #8 uses the add method to add myCommandGroup to the groups collection.
Now that we have added a Group of Commands (myCommandGroup) to the newly created Ribbon tab (myTab), we can move to the last element we'll be working with (following the hierarchy suggested by author Richard Mansfield above).
Step #5: Create New Buttons Or Controls
When introducing the Ribbon Commander object model above, I list and explain the 17 different controls that are contained within rxGroup:
- boxes.
- buttonGroups.
- buttons.
- checkBoxes.
- comboBoxes.
- controls.
- dialogLauncher.
- dropDowns.
- dynamicMenus.
- editBoxes.
- galleries.
- labelControls.
- menus.
- ribbonXControls.
- separators.
- splitButtons.
- toggleButtons.
For this particular tutorial, I focus solely on one of the most basic control: rxButton.
Some of the controls I list above contain themselves the button control. In other words, what I explain below may also help you when working with controls such as rxBox, rxDialogLauncher and rxSplitButton.
Let's take a closer look at rxButton:
rxButton: The Standard Ribbon Button Control
As I explain above, rxButton:
- Models the CT_Button element of the Custom UI XML Markup Version 2 Specification.
- Allows you to specify a standard (push) button control.
rxButton has 24 different properties. Several of these properties are the rough equivalents of other object properties that I cover in previous sections of this tutorial.
Therefore, let's start by taking a look at the properties whose basic characteristics I introduce when explaining rxTab and rxGroup.
I explain the following 15 properties in more detail when covering rxTab above:
- Property #1: id, is an identifier of a custom UI element.
- Property #2: idMso, makes reference to the identifier of a built-in control.
- Property #3: idQ, refers to a qualified control identifier.
- Properties #4 And #5: insertAfterMso and insertBeforeMso allow you to specify the built-in control after (in the case of insertAfterMso) or before (when using InsertBeforeMso) which a particular control should be inserted.
- Properties #6 And #7: insertAfterQ and insertBeforeQ allow you to specify the qualified control after (when using insertAfterQ) or before (in the case of InsertBeforeQ) which a certain control is inserted.
The main difference between the 2 sub-groups properties above is that one works with built-in controls (insertAfterMso and insertBeforeMso), whereas the other works with qualified controls (insertAfterQ and insertBeforeQ). - Property #8: isEmpty allows you to check if a control is empty.
- Property #9: isLive allows you to check if a control is live.
- Property #10: keytip allows you to set the control's KeyTip.
- Property #11: label allows you specify the control label.
- Property #12: parent is the parent of the control.
- Property #13: tag is custom data.
- Property #14: visible determines whether the control is visible.
- Property #15: xml returns the xml node corresponding to the control's state.
Similarly, I provide more details about the following 4 properties when introducing rxGroup:
- Property #1: image.
image allows you to specify a custom image or icon for the control. - Property #2: imageMso, which allows you to specify a built-in image or icon for the control.
- Property #3: screentip, which you can use to specify a ToolTip string for the control.
- Property #4: supertip, which allows you to set up an Enhanced Screen Tip.
All of these leaves the following 5 properties:
- Property #1: description.
description models an ST_LongString attribute within the Custom UI XML Markup Version 2 Specification.
More precisely, description allows you to set a string that is the extended description of the relevant control. This description is displayed in menus with itemSize set to large. - Property #2: enabled.
enabled is a Boolean property. You can use enabled to specify whether the control is enabled. - Property #3: showImage.
showImage is a Boolean property. You use showImage for purposes of specifying whether to display the control's image. - Property #4: showLabel.
showLabel is, again, a Boolean property. You can use showLabel to specify whether the control's label is displayed. - Property #5: size.
size models an ST_Size attribute within the Custom UI XML Markup Version 2 Specification. You can use size to specify the size of the control (usually rxsNormal or rxsLarge).
Considering all of the above, I add the following statements to the sample Custom_Ribbon Sub procedure for purposes of adding a new button:
Dim myButton1 As rxButton
Set myButton1 = New rxButton
With myButton1
.imageMso = “_3DPerspectiveDecrease”
.keytip = “L”
.Label = “Last Row”
.ScreenTip = “Find last row with data”
.Size = rxsLarge
.supertip = “Finds the last row with data in the active worksheet”
End With
myCommandGroup.Buttons.Add myButton1
Let's take a look at each of the new lines of code:
Line #1: Dim myButton1 As rxButton
This line is substantially the same as that used in previous steps. It uses the Dim statement to declare a new object variable (myButton1). myButton1 is declared as of the rxButton object type.
Line #2: Set myButton1 = New rxButton
This line of code follows the same structure as that used in previous steps. It uses the Set statement to assign an object (a new rxButton) to an object variable (myButton1).
Lines #3 And #10: With myButton1 | End With
As the previous lines #1 and #2, code lines #3 and #10 are substantially the same as those used in previous steps. They open and close a With… End With block.
All of the statements within the block (lines #4 through #9 below) are executed on the object that the myButton1 object variable represents.
Line #4: .imageMso = “_3DPerspectiveDecrease”
This line of code uses the imageMso property for purposes of specifying the image that is used as icon for Button1.
Since the property that I use is imageMso (instead of image), the Sub procedure uses a built-in image. The identifier of the built-in image that I chose is “_3DPerspectiveDecrease”. This is the identifier of the following built-in image:
There is a huge amount of unique icons in Office 2013. The Ribbon Commander Framework allows you to benefit from the Dynamic Icon & Image Ribbon Browser add-in. This add-in allows you to easily search and use the appropriate names to use in your code.
Line #5: .keytip = “L”
Line #5 uses the keytip property for purposes of setting up a KeyTip for Button1. The KeyTip that I've chosen is the letter L.
As a consequence of this, and the Keytip of the Power Spreadsheets tab that I add in step #3 above, the complete keyboard shortcut for the command associated with Button1 is “Alt + Y2 + L”.
Line #6: .Label = “Last Row”
This line uses the label property. It sets the string “Last Row” as its value.
Line #7: .ScreenTip = “Find last row with data”
Line #7 sets a ToolTip for Button1. In this case, the string I choose as Tooltip states “Find last row with data”.
Line #8: .Size = rxsLarge
This line of code makes reference to the size property, which specifies the control's size. For Button1, I choose the value rxsLarge.
Line #9: .supertip = “Finds the last row with data in the active worksheet”
This line uses the supertip property for purposes of creating an Enhanced ScreenTip for Button1. The string that is displayed as Enhanced ScreenTip is “Finds the last row with data in the active worksheet”.
Line #11: myCommandGroup.Buttons.Add myButton1
Line #11 is substantially similar to other lines code used in previous steps. It uses the add method for purposes of adding myButton1 to the buttons collection.
Once you've completed this step #5, you've gone through the main elements you work with when customizing the Excel Ribbon:
- The Ribbon itself in step #2 above.
- Tabs in step #3 above.
- Groups of Commands in step #4 above.
- Buttons (or other controls) in the current step #5.
As you can probably imagine, you're almost done customizing the Ribbon. Let's move on to…
Step #6: Render The Context UI
The steps I describe above allow you to modify and customize the Ribbon.
However, for purposes of optimizing performance, the Ribbon Commander Framework carries UI updates in the following 2 steps:
- Step #1: Update the rxCustomUI state.
- Step #2: Render the updated UI.
If you've followed the previous steps in this tutorial, you've already updated the rxCustomUI state (step #1).
To render the updated UI (step #2), you use the refresh method of rxCustomUI. To do this in the sample Custom_Ribbon Sub procedure, I add the following statement:
myCustomUI.Refresh
Strictly speaking, we're now ready to execute the Custom_Ribbon Sub procedure. However, I suggest that you wait until we're fully done with step #7 below before actually running the Sub procedure.
The following screenshots show the results of the customizations to be carried out by this sample code. Notice the following things”
- The following elements are added: (i) a tab labeled “Power Spreadsheets”, (ii) a Group of Commands labeled “Example Macros” and (iii) a large simple button labeled “Last Row” with the chosen icon (blue arrow pointing down).
- When I hover the mouse over the Last Row button, a ToolTip displays the chosen ToolTip (“Find last row with data”) and Enhanced ScreenTip (“Finds the last row with data in the active worksheet”).
- The KeyTip for the Power Spreadsheets tab is “Y2”.
- The KeyTip for the Last Row button is “L”.
The previous 6 steps show how you can create a custom Ribbon with tabs, Groups of Commands and buttons (or other commands). However, the work isn't complete…
In particular, up until now, the button (or other commands) added to the Ribbon don't do anything when clicked. The following step shows you how to fix and complete the creating of your customized Ribbon:
Step #7: Add A Callback
rxButton has 12 delegates. However, for purposes of adding a callback (to handle when a user clicks on a button) within this tutorial you only need to understand 1:
onAction.
The onAction delegate of rxButton allows you to specify the name of the callback function that is called when there's a user action. You use the onAction delegate for purposes of specifying what happens when the user clicks the relevant button.
In other words:
This step is what allows you to execute a specified macro when a user clicks on the button.
To understand callbacks, it may help if you draw a parallel with VBA events. More precisely, as explained in Excel 2016 Power Programming with VBA:
VBA responds to user actions using events. The Ribbon uses a different technique: callback procedures.
Let's go back to the onAction delegate:
Within the Ribbon Commander Framework, delegates are:
- Of the rxDelegate type. You create delegates by using the make_delegate method of rxCustomUI.
- Always associated with (or owned by) and created via a unique rxCustomUI instance.
Therefore, for purposes of specifying what happens when the user clicks on a button, you proceed as follows:
- Step #1: Create an rxDelegate object by using the make_delegate method.
- Step #2: Use the onAction delegate to hook up the rxDelegate object you created in step #1 and the already existing button in the custom Excel Ribbon.
In the sample Custom_Ribbon Sub procedure, I do this by adding the following statement:
myButton1.OnAction = myCustomUI.make_delegate(“myCallback1”)
This statement connects the onAction delegate with myCallback1.
Notice that we haven't (yet) provided myCallback1. You can, however, do this in the following 3 easy steps:
Step #1: Right-Click On The Name String
Within the Visual Basic Editor, go to the relevant callback name string, and right-click on it. In this case, this string is “myCallback1”.
After you've done this, the Visual Basic Editor displays the following contextual menu:
Step #2: Select “Insert [rxButton.onAction] stub”
Click on the following items within the contextual menu:
- “Ribbon Commander”.
- “Insert Delegate Stubs”.
- “Insert [rxButton.onAction] stub”.
Once you do this, an empty delegate stub is automatically added. This looks roughly as follows (the name will vary depending on the callback name string you use):
Step #3: Modify The VBA Code Within The Delegate Stub
The delegate stub created by the Ribbon Commander raises an error and, therefore, it won't work.
You need to update the code by including the statements that you want to be executed when the button you've created is clicked on.
In this example, I include the following VBA code:
Dim myLastRow As Long
myLastRow = ActiveSheet.Cells.Find(What:=”*”, LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
MsgBox prompt:=”The last row is Row No. ” & myLastRow
The purpose of this VBA code is to:
- #1: Find the last row in the active worksheet.
- #2: Display a message box indicating the number of the last row with data.
I explain this particular macro, along with pretty much everything you need to know about finding the last row in Excel with VBA, in this VBA tutorial.
Now the custom Ribbon is ready. You can now execute the Sub procedure you've created to customize the Ribbon. Once you've done this:
- The Excel Ribbon is customized in accordance with the code you've created using the Ribbon Commander Framework.
You can see the Ribbon that results after executing the sample Custom_Ribbon Sub procedure above. - Once a button within the custom Ribbon is clicked by a user, it is appropriately handled.
In the case of the example that I show throughout this tutorial, once the Last Row button is clicked: (i) the last row in the active worksheet is found and (ii) a message box displays its number.
To test whether this is working properly, I type “Test for macro customizing the Excel Ribbon” in cell B34 of the example workbook that accompanies this Excel tutorial.
This Excel VBA Custom Ribbon Tutorial is accompanied by an Excel workbook containing the macros I use . You can get immediate free access to this example workbook by subscribing to the Power Spreadsheets Newsletter.
The following image shows the message box that Excel displays after I click on the Last Row button. Notice that, as expected, the message box displays the number of the last row with data (34):
Strictly speaking, the 7-step process I describe above is enough for you to start creating custom Excel Ribbons with the Ribbon Commander Framework. However, if you want to make your code more compact, you may be interested in…
Step #8 (Optional): Make Your Code More Compact
The Ribbon Commander API is designed to take advantage of the With… With End VBA construct.
Therefore, whenever you use the Add method to add a particular object to a collection, the method returns the added object.
As a consequence of the above, you can write your code using a different structure from the one I use in the previous steps of this tutorial by relying on:
- The Add method.
- The With… End With statement.
For example, the sample Custom_Ribbon Sub procedure that we developed above can be rewritten by using a series of nested With… End With blocks as follows:
- Block #1, works with the myCustomUI variable created to reference the rxCustomUI (as explained in step #1 above).
Additionally, just before the End With statement that ends the With… End With block, it renders the updated UI (the rough equivalent of step #6 above). - Block #2: Creates a new tab, the rough equivalent of step #3 above.
- Block #3: Creates a new Group of Commands, the rough equivalent of step #4 above.
- Block #4: Creates a new button, the rough equivalent of step #5 above.
The following Sub procedure (Custom_Ribbon_Compact) shows this:
Reset The State Of The Ribbon
The Sub procedure structure that I use throughout this Excel tutorial creates a new tab (labeled “Power Spreadsheets”) every single time you execute the Sub procedure. This is probably not what you want.
Furthermore, in other cases, you may want to clear the old state of the Ribbon and reset the default rxCustomUI.
To do this, you just need to proceed as follows:
- Step #1: Use the clear method of rxCustomUI, to clear the control's state.
- Step #2: Use the refresh method of rxCustomUI to render the updated UI.
The following sample macro (Clear_Custom_Ribbon) does this:
Conclusion
After completing this Excel tutorial, you're ready to start crafting code that customizes the Excel Ribbon. In addition to knowing how to create a custom Excel Ribbon in 7 (or 8) steps, as well as how to reset the state of the Ribbon, you have a good understanding of the following topics:
- The main components of the Excel Ribbon.
- The most common approaches to customizing the Excel Ribbon, and why they're less powerful and/or more complicated than using the Ribbon Commander.
- What is the Ribbon Commander Framework, and why this is a better approach (vs. the more common ones) to use when you want to customize the Excel Ribbon.
- What is XML.
- How is the Ribbon Commander object model organized, and how you can use it to customize the Ribbon.
Books And Resources Referenced In This Excel Tutorial
- Alexander, Michael and Kusleika, Dick (2016). Excel 2016 Power Programming with VBA. Indianapolis, IN: John Wiley & Sons Inc.
- Jelen, Bill and Syrstad, Tracy (2015). Excel 2016 VBA and Macros. United States of America: Pearson Education, Inc.
- Mansfield, Richard (2016). Mastering VBA for Microsoft Office 2016. Indianapolis, IN: John Wiley & Sons Inc.
- Martin, Robert, et. al. (2008). RibbonX: Customizing the Office 2007 Ribbon. Indianapolis, IN: John Wiley & Sons Inc.
- Walkenbach, John (2015). Excel 2016 Bible. Indianapolis, IN: John Wiley & Sons Inc.
- Walkenbach, John (2013). Excel VBA Programming for Dummies. Hoboken, NJ: John Wiley & Sons Inc.
The following links are affiliate links, which means that if you choose to make a purchase, I will earn a commission. This commission comes at no additional cost to you.