Excel User Group
Microsoft Excel blogs, forums, files. Read, ask questions, provide answers.

Ribbon, Step-by-Step. Part 3 (The Office Menu and Re-purposing)

In our first two parts we covered the file structure of Excel 2007 and some very simple customisations which, in the main, do not require any VBA code. in this part we are going to try and accomplish two things.

  1. Customisation of the Office Menu (under the office button)
  2. Re-purposing built-in controls to do other things.

In the next one or two parts we will cover more details on the various controls, including Galleries and Contextual tabs and then how we can capture the ribbon object and change controls 'on the fly', so... on with Part 3

Customising the Office Menu

As we have already discovered, the access point to this menu, the Office Button, cannot currently be modified (although as we saw in Part 2, it can be removed), beneath this button is the Office Menu, which is analogous with the 'File' menu in previous versions.

In it's standard form, it looks as below. The controls with a simple image, such as 'New', are 'button' controls. Those with an arrow at the side are defined as 'splitButton', with 'menu' and 'button' controls on the fly-out menu presented from the 'splitButton' deployment.

As with all customUI code, the RibbonX starts with <customUI></customUI> tags and beneath that <ribbon></ribbon> tags. The <officeMenu></officeMenu> tags sit just below this and before any <tab></tab> members, like so: (notice we have left startFromScratch attribute off, so the code presumes "false", e.g. keep the existing ribbon):

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  <ribbon>
    <officeMenu>
    </officeMenu>
</ribbon>
</customUI>

The controls we require on the Office Menu, will sit between the <officeMenu></officeMenu> tags. in this example we will add one simple button, one split button with a 'sub menu' beneath, with button and checkbox and disable one of the built-in buttons.

To add a button we simply specify a new 'button' control and set a unique id, like so: (The label attribute sets the actual text that appears on the 'menu' item).

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  <ribbon>
    <officeMenu>
    <button id="OfficeButton0" insertBeforeMso="FileSave" imageMso="HappyFace" label="New Button" onAction="MBox"/>
    </officeMenu>
</ribbon>
</customUI>

NOTE:You may be wondering where you get all the existing control names, such as the "FileSave" above. It is actually pretty simple. If you go to Office Button>Excel Options>Customize, you can navigate to the command you want and hover over it and the tooltip that appears in braces (FileSave), is exactly (including case) how the control should be addressed as a parameter to the attribute.. below is the tooltip. You can use the same name for any imageMso, to get the built-in icon too.

 

Now as we grow in confidence, we will add the two 'splitButtons', with their related 'menu' and button' controls below. both these buttons are custom ones, declared with just an id (as apposed to a built-in one that would be declared idMso). Here is the code complete:

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  <ribbon>
    <officeMenu>
    <button id="OfficeButton0" insertBeforeMso="FileSave" imageMso="FileSave" 
            label="New Button" onAction="MBox"/>
      <splitButton idMso="FilePrintMenu">
        <menu>
          <button id="OfficeButton1" insertBeforeMso="FilePrintPreview" imageMso="HappyFace"
            label="Happy Print" description="Prints a random joke in the footer of each document" onAction="MBox"/>
        <checkBox idMso="ViewGridlinesToggleExcel"/>
        </menu>
      </splitButton>
    <button idMso="FileClose" enabled="false"/>
    </officeMenu>
</ribbon>
</customUI>

So, reading the code top down we have

  • A button (OfficeButton0), inserted before the 'Save' button with the 'Save' icon.
  • A sub menu on the splitButton 'Print' menu, with a button (OfficeButton1), inserted before the print preview button, with a Happy Face built-in icon.
  • The same 'sub-menu' also has a checkbox, which is the built-in one to display Excel Grid Lines. (see the idMso means a built-in control)
  • The 'Close' button ("FileClose") at the base of the Office menu is disabled.

The image below show the 'New Button', the disabled 'Close' button, the HappyFace button and checkbox on the 'sub menu'

You will have noticed the first use of 'Callbacks' in the parameters above, e.g. 'onAction'. There are many of these, but let's settle on the main one at the minute which is onAction. This defines the name of the VBA code that should run when the control (button, etc) is pressed, clicked or whatever the default 'action' is.

Working with 'callbacks' could not be simpler, when using the Office 2007 Custom UI editor. You simply press the 'callback' toolbar button and it will create a new tab with all the code for all the 'action' callbacks found in the RibbonX code. Now you can simply copy this from the callback pane and paste it into either standard or class modules in your workbook and write code between the stubs to connect actions to the controls.. (when pressing the callbacks button in our example I got the following code stub).

'Callback for OfficeButton0 onAction
Sub MBox(control as IRibbonControl)
End Sub

Why only one stub when there are two 'onAction' parameters? It's because all the 'onAction' parameters are asking for the same VBA code (MBox), so we can use just one code stub. This gives us an IRibbonControl object as a variable called 'control', which we can use to interrogate which control fired the MBox code, using the id property, thus:

'Callback for OfficeButton0 onAction
Sub MBox(control As IRibbonControl)
If control.ID = "OfficeButton1" Then
    MsgBox "Why did the chicken cross the road?", vbQuestion + vbOKOnly, control.ID
Else
    MsgBox "Nicole Smith is Dead!", vbExclamation + vbOKOnly, control.ID
End If
End Sub

This would give us the relevant message box depending on the id of the 'pressed' button.

Re-Purposing Existing Controls.

As you will hopefully be starting to realise, many things you want to do with the Ribbon are starting to work out fairly simply and re-purposing existing commands is no different. You will see a clue in the text just gone. The member we will be dealing with here is the 'command', which, because Excel obviously has many 'commands' the 'command' member 'nests' within the 'commands' collection member. (Like a 'tab' is contained within the 'tabs' collection).

You identify the commands in exactly the same way as we did above, by looking for it's idMso in the customize dialog's list. Once you have this idMso, there is little left to learn. The code below disables the 'Italic' functionality on the ribbon, by setting it's 'enabled' attribute to "false" and then re-purposes the 'Save' (FileSave) menu with a custom 'OnAction' attribute. This will override the built-in save functionality in Excel. Below that is a screen shot of the disabled Italics button and the dialog 'fired' when pressing 'Save'.

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
    <commands>
        <command idMso="Italic" enabled="false"/>
        <command idMso="FileSave" onAction="MySave"/>
    </commands>
</customUI>

I hope, now we have covered RibbonX a few times, that little explanation is needed for this procedure, but for completeness, below is the VBA code 'callback' generated by the CustomUI tool and placed in a standard module in the workbook.

'Callback for Save onAction
Sub MySave(control As IRibbonControl, ByRef cancelDefault)
    MsgBox "Sorry, like me, it can't be saved", vbExclamation + vbOKOnly, "Bog Off"
End Sub

As you can see, you will get an IRibbonControl object to identify the firing control and a parameter enabling you to enable or disable the default action (default is cancel=true). This enables you to only re-purpose on the pressing of a certain custom control, for example.

This will be enough for this part. next time we will extend our knowledge of other controls and then in the final part we will move on to changing control state on the fly by capturing the Ribbon object and invalidating it.

Stay tuned for the final one or two episodes! ;-)


Posted Feb 03 2008, 10:54 PM by Nick Hodge
Filed under: , ,

Comments

mayest wrote re: Ribbon, Step-by-Step. Part 3 (The Office Menu and Re-purposing)
on Wed, Mar 19 2008 2:43 AM

Nick, thanks for these posts. They have been very helpful. I don't know if you have linked to it or not, but Microsoft has a .zip file that contains all of the Control IDs available at [url=blogs.msdn.com/.../developer-resources-for-office-2007-rtm.aspx]Jensen Harris' blog[/url].

Tim

Nick Hodge wrote re: Ribbon, Step-by-Step. Part 3 (The Office Menu and Re-purposing)
on Wed, Mar 19 2008 3:51 AM

Tim

Yes, it is in the Ribbon Pack I posted here

excelusergroup.org/.../entry212.aspx

Glad the posts are working for you. I must get around to doing the final one... maybe this weekend.

mayest wrote re: Ribbon, Step-by-Step. Part 3 (The Office Menu and Re-purposing)
on Wed, Mar 19 2008 3:28 PM

Nick, a question. Your tip about looking in the Customize dialog in Excel Options to find the control names was a great tip. However, I think that there are some errors in the tooltips that pop up. I'm far too new at customizing the ribbon to be sure, but take a look at this:

Go to Excel Options --> Customize and then choose Office Menu from the drop-down. Now scroll down and hover over SaveAs. It says that the control name is FileSaveAsOtherFormats.

I was trying to disable most of the file types in the Save As splitButton and couldn't make it work with that name, Then I noticed that the Save As Other Format tooltip was saying that its control name is FileSaveAsMenu. I tried that and was finally able to get into the SaveAs splitButton.

FileSaveAsOtherFormats actually works as you would expect: it controls the Save As Other Formats command.

That's why I went looking for a complete list of control names from Microsoft. Anyway, are those tooltips wrong, or am I just reading them incorrectly?

Also, its seems that the Customize trick doesn't indicate whether something is a splitButton, menu, or button. To disable Publish, I discovered that I had to use menu instead of splitButton. It looks like a splitButton to me, but that didn't work.

Thanks again,

Tim

Nick Hodge wrote re: Ribbon, Step-by-Step. Part 3 (The Office Menu and Re-purposing)
on Thu, Mar 20 2008 7:21 PM

Tim

I think they maybe have this right, one brings up the save as dialog, the other brings in the types allowing you to specify a particular type, like if you select xlsm it still brings up the save as dialog, but set to xlsm, whereas selecting saveas brings up xlsx as a default. maybe not intuitive, but also maybe not wrong?

PK wrote re: Ribbon, Step-by-Step. Part 3 (The Office Menu and Re-purposing)
on Wed, Apr 16 2008 10:58 AM

Nick, thanks! This has been invaluable to me!

BTW, I guess you know you have an extra </menu> in your example?

Nick Hodge wrote re: Ribbon, Step-by-Step. Part 3 (The Office Menu and Re-purposing)
on Wed, Apr 16 2008 7:20 PM

PK

Thanks for the heads up, I have now changed it. Glad it worked for you

Franc wrote re: Ribbon, Step-by-Step. Part 3 (The Office Menu and Re-purposing)
on Mon, Apr 28 2008 7:25 PM

Hi Tim, I hope you can help.

I noticed that when I type in a worksheet most of the buttons on the ribbon get disabled(grayed out), once I move out of the cell I'm typing in, the disabled buttons get enabled again. I want to do that to my custom ribbon. What code do I need to use? How can I tell my custom ribbon to disable buttons when I type?

I've searched on the internet but haven't found the answer.

Franc

Nick Hodge wrote re: Ribbon, Step-by-Step. Part 3 (The Office Menu and Re-purposing)
on Sun, May 4 2008 5:51 AM

Who's Tim?

Excel internally knows when it is in edit mode and I know no way of replicating that using ribbonX.

I don't know if that is simply a ribbon issue. I have never known a way in VBA of ascertaining if excel is in 'edit' mode.

Sorry

Nick

roryfynn wrote re: Ribbon, Step-by-Step. Part 3 (The Office Menu and Re-purposing)
on Mon, Jun 30 2008 10:44 AM

Hi Nick,

Firstly thanks for this series of great articles; much appreciated.

I've got an interesting application for customisation... securing a remote/citrix instance.  I need to allow the user to view the spreadsheet in all it's glory ie formulae and data but there is absolutely no need for anything else.

So I've started from scratch and then disabled the remaining buttons in the office menu.  However... the last thing I need to do before achieving mission accomplished status is to get rid of or to disable the "excel options" button.

Do you know how I can achieve this in the customUI XML or in macros?  I tried to look for a reference to the button but haven't been successful.

Any immediate help would be greatly appreciated as this is time-critical my end.

Thanks so much

Regards,

Rory

Nick Hodge wrote re: Ribbon, Step-by-Step. Part 3 (The Office Menu and Re-purposing)
on Mon, Jun 30 2008 6:01 PM

Rory

I don't think it can be hidden, but it can be disabled...any good?

<customUI xmlns="schemas.microsoft.com/.../customui">

<commands>

<command idMso="ApplicationOptionsDialog" enabled="false"/>

</commands>

<ribbon startFromScratch="true">

</ribbon>

</customUI>

roryfynn wrote re: Ribbon, Step-by-Step. Part 3 (The Office Menu and Re-purposing)
on Tue, Jul 1 2008 4:13 AM

Nick... That is perfect.  Thank you.

I had found another workaround using group policy and your remove ribbon macro.  Group policy was essential to prevent keyboard shortcuts too.

Thanks again.

Best regards,

Rory

djessellis wrote re: Ribbon, Step-by-Step. Part 3 (The Office Menu and Re-purposing)
on Fri, Mar 20 2009 6:26 AM

Hi -

Just wondering if there is a quick and easy way of enabling a select number of the existing buttons under the Office Button.

I love the idea of stripping every thing away with the startFromScratch command, but would like to enable FileSaveAs as well.

Thanks!

Jesse

Nick Hodge wrote re: Ribbon, Step-by-Step. Part 3 (The Office Menu and Re-purposing)
on Sun, Mar 22 2009 4:53 AM

Jesse

The startFromScratch="True" will take away everything except New, Open and Save. Of course, if it is a new workbook you will get Save as, by pressing Save. However, to put it back in you just roll a custom button and write your own VBA code to Save As. The RibbonX looks like this

<customUI xmlns="schemas.microsoft.com/.../customui">

<ribbon startFromScratch="true">

<officeMenu>

<button id="btnSaveAs" insertBeforeMso="FilePrintPreview" imageMso="FileSaveAs" label="Save As" description="Save as" onAction="mySaveAs"/>

</officeMenu>

</ribbon>

</customUI>

and the VBA code, (IN A STANDARD MODULE), looks like this. (There is no error code here to decide if dialog was cancelled and nothing to default to say xlsx, but all that can be done very easily)

'Callback for btnSaveAs onAction

Sub mySaveAs(control As IRibbonControl)

Dim strFName As String

strFName = Application.GetSaveAsFilename

ThisWorkbook.SaveAs Filename:=strFName

End Sub

djessellis wrote re: Ribbon, Step-by-Step. Part 3 (The Office Menu and Re-purposing)
on Mon, Mar 23 2009 6:08 AM

Wow - thanks for that... I think this is great stuff... Really allows developers to take out the risk of models being mucked around with!

Thanks you so much.

Copyright Excel User Group and the relevant contributors, 2009. All Trade Marks acknowledged. This site is a peer-to-peer site and NOT affiliated in any way to Microsoft Corp. All rights reserved.