As mentioned in Part 5 of this series, this post will display how to change the value of a Ribbon control from a VBA procedure. For this example, we will continue to work with the case presented in Part 5, using a checkbox.Ms office 2007 is so Charismatic.
Essential Background
Basically, the application of the RibbonX code works like this:
- We create our XML markup via the CustomUI editor or manually
- We open the Excel file
- The RibbonX code is executed, and the Ribbon item is created
If Macros are enabled, then the following will occur next:
- Any Workbook_Open macros are executed (providing macros are enabled)
- Any OnLoad macros (specified in the XML code) are executed (providing macros are enabled).Office 2007 professionaland Office 2007 ultimate are so powerfull.
When a Ribbon item is first presented (the first time your controls are shown), RibbonX will also launch “callbacks” to check what values your controls will have.
To effectively work with RibbonX, one of the first things we need to understand is that RibbonX does not work the same way that VBA collections do. There is no collection of RibbonX items, so we need to store all of our values in our own code. To do this, my preference is to create workbook properties and store my values there. This approach offers the benefit that we can easily refer to our RibbonX items, as well as makes it obvious which workbook we’re dealing withMicrosoft Office 2007 is powerfull.
Modifying the XML Markup
Before we create a custom property to hold our defaults, we might as well get the XML Markup adjustments out of the way. We’re going to add two things to our XML for this example; and OnLoad statement, and a GetPressed statement. The use of these will become apparent later, so for now, change the XML of your file to read:
PLAIN TEXT
XML:
-
<customUI onLoad=“OnLoad” xmlns=“http://schemas.microsoft.com/office/2006/01/customui”>
-
<ribbon startFromScratch=“false”>
-
<tabs>
-
<tab id = “xlgTab” label=“XLG” insertAfterMso=“TabView”>
-
<group id=“TestTab” label=“My Testing Tab”>
-
<checkBox id=“chkbox1″ label=“MyCheckbox” onAction=“CallControl” getPressed=“GetPressed” />
-
</group>
-
</tab>
-
</tabs>
-
</ribbon>
-
</customUI>
Creating the Workbook Properties
We are going to create two new workbook properties for both reading and writing. The first will hold the default state of our checkbox. The second will hold our RibbonUI object so that we can refer to it later. All the following code will go in the ThisWorkbook module of the project:
PLAIN TEXT
Visual Basic:
-
‘Private variables to hold state of Ribbon and Ribbon controls
-
Private bChkBox1 As Boolean
-
Private pRibbonUI As IRibbonUI
-
-
Public Property Let chkBox1(b As Boolean)
-
‘Set value of chkBox1 property
-
bChkBox1 = b
-
End Property
-
-
Public Property Get chkBox1() As Boolean
-
‘Read value of chkBox1 property
-
chkBox1 = bChkBox1
-
End Property
-
-
Public Property Let ribbonUI(iRib As IRibbonUI)
-
‘Set RibbonUI to property for later use
-
Set pRibbonUI = iRib
-
End Property
-
-
Public Property Get ribbonUI() As IRibbonUI
-
‘Retrieve RibbonUI from property for use
-
Set ribbonUI = pRibbonUI
-
End Property
Integrating the Checkbox Value Property
In addition to the properties we defined, we’ll need one more piece in the ThisWorkbook module, and that is the code to actually set the default value when we open the workbook. IS Windows 7 Professional better than Windows 7 Home Premium ?
Copy the following procedure below the rest in the ThisWorkbook module:
PLAIN TEXT
Visual Basic:
-
Private Sub Workbook_Open()
-
‘Set the default properties of the ribbon controls
-
chkBox1 = True
-
End Sub
If you have continued on from Part 5, then you already have the “CallControl” procedure in a standard module. We’ll need to add a line to it to store the toggled value in our custom workbook property, so adjust your code to match the following:
PLAIN TEXT
Visual Basic:
-
Private Sub CallControl(control As IRibbonControl, pressed As Boolean)
-
‘Tell the user the state of the control when they physically click it.
-
ThisWorkbook.chkBox1 = pressed
-
Select Case pressed
-
Case True
-
MsgBox “The checkbox is checked!”
-
Case False
-
MsgBox “The checkbox is NOT checked!”
-
End Select
-
End Sub
Integrating the RibbonUI Property
Now, as I covered in the introduction, when we open the workbook, our Ribbon items will be created, and the Workbook_Open routine will fire, setting the value of the checkbox to True. How do we get the checkbox to actually return this value, though? Photoshop CS4 is so magic!
This is where the “OnLoad” procedure that we specified in the XML comes in. It forms the stepping stone to being able to do this. If you recall, I stated that there was no Ribbon collection and we’d have to hold our own objects if we wanted to use them. This is the exact purpose of the OnLoad procedure.
Copy the following code into the Standard module which holds the “CallControl” procedure:
PLAIN TEXT
Visual Basic:
-
Private Sub OnLoad(ribbon As IRibbonUI)
-
‘Set the RibbonUI to a workbook property for later use
-
ThisWorkbook.ribbonUI = ribbon
-
End Sub
What this code does is feed the RibbonUI object into our workbook property, allowing us to “hold onto” it for later use. We know have a way to access our Ribbon object!
“Great!”, you say, “But how?”
Before we go there, we want to do just one more thing. We are going to set up one more routine to feed information back to the RibbonUI. Acrobat 9 is so useful! Remember that we added a “GetPressed” specification to the XML? This also needs to call a procedure, (again in the standard module,) which looks like this:
PLAIN TEXT
Visual Basic:
-
Private Sub GetPressed(ByVal control As IRibbonControl, ByRef returnVal)
-
‘Query the property for the value of the chkbox, and feed it back
-
‘to the ribbon so that it can be set appropriately
-
If control.ID = “chkbox1″ Then returnVal = ThisWorkbook.chkBox1
-
End Sub
The purpose of this routine is to feed the checkbox value back to the RibbonUI so that it can be updated to reflect the value we have on hand for it. It can be initiated in a couple of different ways. The first time the control is presented, this routine will be called to return the default value. Also, we can invalidate the XML, which will trigger this routine as the Ribbon is “rebuilt”. The first happens naturally after the Ribbon is loaded, but it’s the second that we’re interested in, as it gives us the ability to rebuild the Ribbon control when we want to change the value.Dreamweaver CS4 is very easy-to-use!
Updating the Ribbon Control’s Value via VBA
And here it is, at long last. A very simple routine to do exactly that. We’re going to pretend that we have a lot more code, and a real reason to do this. At some point, we decide that we need to toggle the value of the checkbox and make it reflect in the menu. This routine works by toggling the checkbox property and invalidating the XML for the menu item, which forces the “GetPressed” method to be called and rebuild the menu:
PLAIN TEXT
Visual Basic:
-
Sub ToggleChkBox1()
-
‘Toggle the value of the checkbox via code, and have it trigger
-
‘a ribbon update to reflect the new value
-
-
‘Check value of checkbox and flip it
-
If ThisWorkbook.chkBox1 = True Then
-
ThisWorkbook.chkBox1 = False
-
Else
-
ThisWorkbook.chkBox1 = True
-
End If
-
-
‘Invalidate the control, forcing it to reload
-
ThisWorkbook.ribbonUI.InvalidateControl “chkbox1″
-
End Sub
Final Notes
The “CallControl” routine here is only to demonstrate the use of the property for toggling the value of the checkbox property when manually clicked. The “ToggleChkBox1″ routine demonstrates the ability to change the Ribbon display via VBA code alone.
If you are curious about the order that things fire, either step through the code, or put a “Stop” command at the beginning of the following routines:
- Workbook_Open
- OnLoad
- GetPressed
That should give you a fairly good feel for the order things go in.