Ribbon.InvalidateControl not working on PPT 2010 - vba

I have a an add-in within the Insert Ribbon of PPT 2010. Basically what I want to do is to make a selection in a combo box, then run a macro, then set the combo box to blank. Unfortunately I´v been unable to clear the selection.
I have searched all over the web with various methods and nothing helps. Hope someone can help.
My XML
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="VirtusInitialize">
<ribbon>
<tabs>
<tab idMso="TabInsert">
<group id="CustomGroup1" label="Sticker">
<box id="box1" boxStyle="horizontal">
<comboBox id="ddlItem" label="STICKER 1" onChange="Sticker1">
<item id="BU" label="BACK UP" />
</comboBox>
</box>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
VBA code:
Private MyRibbonV As IRibbonUI
Public Sub VirtusInitialize(ByVal ribbon As Office.IRibbonUI)
Set MyRibbonV = ribbon
End Sub
Sub Sticker1(ByVal control As IRibbonControl, text As String)
'do stuff
MyRibbonV.InvalidateControl ("ddlItem")
End Sub

Alternatively use a Dropdown control instead of combobox
I found some information here, at least enough to get started...
http://gregmaxey.mvps.org/word_tip_pages/customize_ribbon_main.html
Use XML like:
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="VirtusInitialize">
<ribbon>
<tabs>
<tab idMso="TabInsert">
<group id="CustomGroup1" label="Sticker">
<box id="box1" boxStyle="horizontal">
<dropDown id="ddlItem" label="STICKER 1"
getItemCount="GetItemCount"
getItemLabel="GetItemLabel"
getSelectedItemIndex="GetSelectedItemIndex"
onAction="Sticker1" >
</dropDown>
</box>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
And VBA callbacks:
Private MyRibbonV As IRibbonUI
Public Sub VirtusInitialize(ByVal ribbon As Office.IRibbonUI)
Set MyRibbonV = ribbon
End Sub
Sub Sticker1(ByVal control As IRibbonControl, id As String, index As Integer)
'do stuff
Select Case index
Case 0
Case 1
'do stuff
Case 2
'do stuff
End Select
MyRibbonV.Invalidate
End Sub
'Callback for ddlItem getItemCount
Sub GetItemCount(control As IRibbonControl, ByRef returnedVal)
'puts 3 items in the dropdown and triggers the GetItemLabel
returnedVal = 3
End Sub
'Callback for ddlItem getItemLabel
Sub GetItemLabel(control As IRibbonControl, index As Integer, ByRef returnedVal)
Dim str$
Select Case index
Case 0
str = " "
Case 1
str = "BACK UP"
Case 2
str = "GO FORWARD"
End Select
returnedVal = str
End Sub
'Callback for ddlItem getSelectedItemIndex
Sub GetSelectedItemIndex(control As IRibbonControl, ByRef returnedVal)
'not used
End Sub
'Callback for ddlItem getText
Sub GetText(control As IRibbonControl, ByRef returnedVal)
'not used
End Sub
'Callback for ddlItem getItemID
Sub GetItemID(control As IRibbonControl, index As Integer, ByRef id)
'not used...
End Sub

try this:
Sub Sticker1(ByVal control As IRibbonControl, text As String)
'do stuff
Call MyRibbonV.InvalidateControl ("ddlItem")
End Sub
Notice the keyword "Call" added to the original code.

Related

Button activated on ribbon. After click, it is deactivated for two seconds and is activated again

In the xml I have a button for the ribbon:
<button id="PRUEBA" label="Boton Prueba" size="normal" onAction="Macro11" imageMso="DirectRepliesTo" tag="EtiquetaG" getEnabled="Habilitado"/>
For vba:
I would like this button to appear enabled to work on the ribbon, but once pressed, do the macro for which it is defined, then the button is disabled for two seconds and is enabled again.
Thanks.
In the ribbon XML you use the getEnabled callback which returns the control's state as a boolean value:
getEnabled="Habilitado"
You need to make sure it always returns a valid result depending on which your control can be disabled and enabled dynamically at runtime.
I dont speak english, sorry. I use a translator. Well, What I intend is that when pressing the button on the ribbon, it is disabled a couple of seconds after executing the macro. The macro does nothing, it just inserts a content block of Word. Although the example I give is a test in an excel sheet, it would be for a word document. It is related to the post: Enable/Disable Ribbon Controls Independently But I would only like it to work with a button and put a timer. I do not know how to do it.
Option Explicit
Dim Rib As IRibbonUI
Public MyTag As String
'Public EnableButton1 As Boolean
Sub Habilitado(control As IRibbonControl, ByRef Enabled)
If MyTag = "Enable" Then
Enabled = True
Else
If control.Tag Like MyTag Then
Enabled = True
Else
Enabled = False
End If
End If
End Sub
Sub EnableControlsWithCertainTag3()
'Habilita solo el control con la etiqueta Tag "SoloUno"
Call RefrescarCinta(Tag:="SoloUno")
End Sub
Sub EnabledAllControls()
'Habilita todos
Call RefrescarCinta(Tag:="*")
End Sub
Sub DisableAllControls()
'Deshabilita todos
Call RefrescarCinta(Tag:="")
End Sub
Sub RefrescarCinta(Tag As String)
MyTag = Tag
If Rib Is Nothing Then
MsgBox "Cierra y vuelve a abrir" & vbNewLine & _
"Visit this page for a solution:
http://www.rondebruin.nl/ribbonstate.htm"
Else
Rib.Invalidate
End If
End Sub
Sub RibbonOnLoad(ribbon As IRibbonUI)
Set Rib = ribbon
End Sub
Lines on XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customUI onLoad="RibbonOnLoad"
xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<!-- Add two custom groups on the Home Tab with a few buttons -->
<ribbon>
<tabs>
<tab idMso="TabHome" >
<group id="MyCustomGroup1" label="Group1"
tag="MyPersonalGroup1" >
<button id="G1B1" label="Caption 1" size="normal"
onAction="Macro1" imageMso="DirectRepliesTo"
tag="SoloUno" getEnabled="Habilitado"/>
<button id="PRUEBA" label="Boton Prueba" size="normal"
onAction="Macro11" imageMso="DirectRepliesTo"
tag="EtiquetaG" getEnabled="Habilitado"/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
Macros:
Sub Macro1(control As IRibbonControl)
MsgBox "This is Macro 1 in group 1"
End Sub
Sub Macro11(control As IRibbonControl)
Application.OnTime Now + TimeValue("00:00:02"), "Macro12"
End Sub
Sub Macro12()
MsgBox "El mensaje funciona; intenta incluir en el modulo macro del
mensaje, un timer, a ver que pasa"
End Sub

Microsoft Visio VBA CustomUI Ribbon help - Changing Default Value of EditBox

I have a customUI with an EditBox and want to set the default value when the User opens the Visio template file.
Here is the customUI xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="CustomRibbonOnLoad">
<ribbon>
<tabs>
<tab id="CustomTab1" label="My Tab">
<group
id="BOMGroup"
label="BOM"
autoScale="true"
>
<editBox id="BOMLink" label="BOM Link:" onChange="ThisDocument.BOMLink_onChange" getText = "ThisDocument.BOM_getText"/>
<button
id="GoToBOMLink"
label="Go To BOM Link"
screentip="Opens Browser to go to BOM Link"
size="large"
imageMso="HyperlinkOpenExcel"
onAction="ThisDocument.OpenBOM"
/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
So I expect BOMLink to have its default text updated through its getText callback function.
Here is my vba code:
Dim MyRibbon As IRibbonUI
Sub CustomRibbonOnLoad(ribbon As IRibbonUI)
Set MyRibbon = ribbon
Debug.Print "CustomRibbonOnLoad called"
MyRibbon.InvalidateControl ("BOMLink") ' Invalidates the cache of a single control
End Sub
Sub myFunction()
MyRibbon.InvalidateControl ("BOMLink") ' Invalidates the cache of a single control
End Sub
'Callback for BOMLink onChange
Sub BOMLink_onChange(control As IRibbonControl, text As String)
End Sub
'Callback for BOMLink getText
Sub BOM_getText(control As IRibbonControl, ByRef returnedVal)
Debug.Print "Callback UpdateBOMLinkText"
MyRibbon.InvalidateControl ("BOMLink") ' Invalidates the cache of a single control
returnedVal = "test default text"
End Sub
'Callback for GoToBOMLink onAction
Sub OpenBOM(control As IRibbonControl)
Debug.Print "Callback OpenBOM"
End Sub
As it stands right now, I do not get the "CustomRibbonOnLoad called" debug print, but I do get the "Callback UpdateBOMLinkText" called. However the text does not change to the default test text as expected.
When I open the document and click the Custom Tab I get this in the debug:
>invokeVBA: ThisDocument.BOM_getText
Callback UpdateBOMLinkText
<invokeVBA: 0x80020009
I am attempting to fill it with "test default text" for now, but in the future want to call upon the Shapesheet and pull data from there to fill by default.
Any help would be appreciated, thanks!
You need to remove this line because it overwrites the value you set in the line before that.
'Callback for BOMLink getText
Sub BOM_getText(control As IRibbonControl, ByRef returnedVal)
Debug.Print "Callback UpdateBOMLinkText"
' MyRibbon.InvalidateControl ("BOMLink") ' <<<< remove this line
returnedVal = "test default text"
End Sub

VBA Ribbon getPressed for a toggleButton

I am trying to set the value of a toggleButton. This is my Ribbon XML
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<ribbon startFromScratch="false">
<tabs>
<tab id="customTab" label="CC">
<group id="grpSegments" label="Segments">
<dropDown id="cbLeaves" label="Segments" onAction="LeavesChanged" getSelectedItemID="GetCBLeavesSelectedID">
<item id='item4' label='4'/>
<item id='item6' label='6'/>
<item id='item8' label='8'/>
<item id='item12' label='12'/>
</dropDown>
<button id="cGenerate" label="Generate" size="large" onAction="ArrangeRosette"/>
</group>
<group id="grpGuides" label="Guides">
<toggleButton id="cToggleGuide" label="Show Guides" onAction="GuideToggled" getPressed="GetGuideState"/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
I have a method with the signature
Sub GuideToggled(control As IRibbonControl, ByRef Pressed As Boolean)
However, this always results in an error about macro not being accessible.
whereas, the getSelectedItemID for the dropDown has no trouble
Sub GetCBLeavesSelectedID(control As IRibbonControl, ByRef ItemID As Variant)
I cannot find any resource which has the getPressed callback documented.
You reference GuideToggled and GetGuideState in your ribbon XML, so you need them both:
'Callback for cToggleGuide onAction
Sub GuideToggled(control As IRibbonControl, pressed As Boolean)
End Sub
'Callback for cToggleGuide getPressed
Sub GetGuideState(control As IRibbonControl, ByRef returnedVal)
End Sub
Have you tried the custom UI editor tool? It will help you find the right signatures for your VBA callbacks.
Try this
Callback for HighlightTBtn onAction
Sub GoTo_onAction(control As IRibbonControl, pressed As Boolean)
MsgBox pressed
If pressed Then
MsgBox "Button On"
Else
MsgBox "Button Off"
End If
End Sub

How to disable (Record Macro) menu (by macro codes)

In (Microsoft Excel) In (Tools > Macro) There is a menu with name of (Record Macro)
How to disable (Record Macro) menu by a macro code?
You can use a loop like this:
Dim ctl As CommandBarControl
For Each ctl In Application.CommandBars.FindControls(ID:=184)
ctl.Enabled = False
Next ctl
For Excel 2007+, you need to manipulate the ribbon. This is as good as I can come up with, the problem as Rory and I discussed in comments to his answer is that the MacroRecord command can be added to the Status Bar, and the Status Bar is not part of the ribbon model. The hack is to disable the status bar, but since that is an application-level property, you need an event handler to re-enable it for other workbooks.
Ribbon XML to disable the controls:
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="ribbonOnLoad">
<commands>
<command idMso="MacroRecord"
enabled="false"
/>
</commands>
<ribbon>
<tabs>
<tab>
<group idMso="GroupMacros">
<button idMso="MacroRecord"
enabled="false"
/>
</group>
<group idMso="GroupCode">
<button idMso="MacroRecord"
enabled="false"
/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
VBA in a standard module to handle the ribbon callbacks and associated procedures:
Option Explicit
Option Private Module
Public XLEvents As New cEventClass
'Callback for customUI.onLoad
Sub ribbonOnLoad(ribbon As IRibbonUI)
Call SetEventHandler
Call ToggleStatusBar(ThisWorkbook)
End Sub
Sub SetEventHandler()
If XLEvents.appevent Is Nothing Then
Set XLEvents.appevent = Application
End If
End Sub
Sub ToggleStatusBar(wb As Workbook, Optional ret$)
If (wb.Name = ThisWorkbook.Name) Then
Application.StatusBar = "Status Bar Disabled"
Else
Application.StatusBar = False
End If
End Sub
VBA in a Class module called "cEventClass" to do application event-handling:
Option Explicit
Public WithEvents appevent As Application
Dim ret As String
Private Sub appevent_WorkbookActivate(ByVal wb As Workbook)
Call ToggleStatusBar(wb, ret)
End Sub

How to set a text on a Editbox Ribbon via VBA (Excel)

How can I set a text in a Ribbon Editbox? I can't find it on internet :/
I just can find examples of click event but nothing about set a text from a Sub.
So for example, I want something like this:
Sub settingText()
editboxname = "my text"
end sub
The solution I found on this link: http://www.shulerent.com/2011/08/16/changing-the-value-of-an-editbox-office-ribbon-control-at-runtime/
Here is an example that I tested and it worked well:
'Global Variables:
Public MyRibbonUI As IRibbonUI
Public GBLtxtCurrentDate As String
Private Sub OnRibbonLoad(ribbonUI As IRibbonUI)
Set MyRibbonUI = ribbonUI
GBLtxtCurrentDate = ""
End Sub
Private Sub ocCurrentDate(control As IRibbonControl, ByRef text)
GBLtxtCurrentDate = text
MyRibbonUI.InvalidateControl (control.id)
End Sub
Private Sub onGetEbCurrentDate(control As IRibbonControl, ByRef text)
text = GBLtxtCurrentDate
End Sub
Public Sub MyTest()
'Here is an example which you are setting a text to the editbox
'When you call InvalidateControl it is going to refresh the editbox, when it happen the onGetEbCurrentDate (which is the Gettext) will be called and the text will be atributed.
GBLtxtCurrentDate = "09/09/2013"
MyRibbonUI.InvalidateControl ("ebCurrentDate")
End Sub
<?xml version="1.0" encoding="UTF-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="OnRibbonLoad">
<ribbon>
<tabs>
<tab id="Objects" label="Objects">
<group id="grp" label="My Group">
<editBox id="ebCurrentDate" label="Date" onChange="ocCurrentDate" getText="onGetEbCurrentDate"/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
It's a little while since this answer was posted, and there looks to be a recent-ish change to the behaviour of the ribbon, which means the original answer posted may not be a solution any more. For the record, I'm using Excel 2013 with some updates that are dated after Braulio's answer.
The heart of the difference is that Invalidate and InvalidateControl on the ribbon don't behave the same way as previously. This means that InvalidateControl does not call the getText callback on the editBox. I replaced the InvalidateControl calls with Invalidate (so forces a re-draw on the entire ribbon), and that does trigger the callback as expected.
So here's the code of my solution for a filename/browse button (note I've included extra code for caching the ribbon UI reference on a very hidden sheet so that resets during development don't make the ribbon inaccessible).
Private sobjRibbon As IRibbonUI
Private strFilename As String
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (destination As Any, source As Any, ByVal length As Long)
Private Function GetRibbon() As IRibbonUI
If sobjRibbon Is Nothing Then
Dim objRibbon As Object
CopyMemory objRibbon, ThisWorkbook.Worksheets("Ribbon_HACK").Range("A1").Value, 4
Set sobjRibbon = objRibbon
End If
Set GetRibbon = sobjRibbon
End Function
'Callback for customUI.onLoad
Sub Ribbon_Load(ribbon As IRibbonUI)
Set sobjRibbon = ribbon
Dim lngRibPtr As Long
lngRibPtr = ObjPtr(ribbon)
' Write pointer to worksheet for safe keeping
ThisWorkbook.Worksheets("Ribbon_HACK").Range("A1").Value = lngRibPtr
strFilename = ""
End Sub
'Callback for FileName onChange
Sub OnChangeFilename(control As IRibbonControl, text As String)
strFilename = text
End Sub
'Callback for FileName getText
Sub GetFileNameText(control As IRibbonControl, ByRef returnedVal)
returnedVal = strFilename
End Sub
'Callback for FilenameBrowse onAction (I'm looking for XML files here)
Sub OnClickFilenameBrowse(control As IRibbonControl)
Dim objFileDialog As Office.FileDialog
Set objFileDialog = Application.FileDialog(msoFileDialogFilePicker)
With objFileDialog
.AllowMultiSelect = False
.Title = "Please select the file."
.Filters.Clear
.Filters.Add "XML", "*.xml"
If .Show = True Then
strFilename = .SelectedItems(1)
GetRibbon().Invalidate ' Note the change here, invalidating the entire ribbon not just the individual control
End If
End With
End Sub
For the record, here's the XML for the two objects I'm dealing with here:
<editBox id="FileName" onChange="OnChangeFilename" screentip="Filename of the XML file to upload" label="XML file name" showImage="false" getText="GetFileNameText" />
<button id="FilenameBrowse" imageMso="ImportExcel" onAction="OnClickFilenameBrowse" screentip="Find the file to upload" label="Browse" />