View Full Version : Catching the button label on a ribbon from a shape name

06-15-2015, 02:44 PM
Hi all,

maybe I'm missing something obvious, but as I'm still a beginner and ran out of ideas, I hope, one of you is able to identify, what is going wrong in my actual project.

The idea of the project is, to give a user the chance to save some of his favorite creations to a hidden presentation with one click and get it back with another click on a another button. (Not the slide as a whole, but the objects he selected)

First piece of work was to create a macro, copying and saving the selected objects to a slide in a hidden presentation. This works well.

Second step was to create a macro copying these objects back to the active presentation. This works well, too.

Part 3 was to create a ribbon with two menus. An "Add to" menu with, e.g., 5 buttons, always button 1 related to slide 1 of the hidden presentation (copying the selection into it), button 2 related to slide 2 and so on. And the second menu is called "Insert", and the five buttons are related to the same slides, catching the content and copying it back to the active slide. This works well, too.

Well, of course, I don't want to force the user to remember forever what he added to the hidden slide 1, to slide 2, etc. He should have the chance to give things a name. So I created an input box to let him type a name. This name is saved as a name for the selected shapes (I mean the function "shape.Name"). Even this works well.

But now the ice is getting thin.

The idea to uses shape names came up, because I want to create dynamic buttons, catching the names with help of the getLabel function.

I created the following XML code - for testing purposes I only prepared the third button (Callback3 for adding to slide 3 of hidden presentation, Callback 8 for inserting from slide 3 of hidden presentation).

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="RibbonControl.OnRibbonLoad" >
<ribbon startFromScratch="false">
<tab id="InputTab" label="Input Tab">
<group id="Input" label="Input">
<menu id="addfav" label="Add to MyFiles" screentip="Add to MyFiles" supertip="Select your favorite shapes on the slide and add them to your personal collection.">
<button id="addfav1" label="Add Me 01" onAction="Callback1"/>
<button id="addfav2" label="Add Me 02" onAction="Callback2"/>
<button id="addfav3" onAction="Callback3" getLabel = "RibbonControl.buttonLabel3"/>
<button id="addfav4" label="Add Me 04" onAction="Callback4"/>
<button id="addfav5" label="Add Me 05" onAction="Callback5"/>
<menu id="insfav" label="Insert MyFiles" screentip="Insert MyFiles" supertip="Insert your favorite shapes from your personal collection.">
<button id="insfav1" label="Empty 01" onAction="Callback6"/>
<button id="insfav2" label="Empty 02" onAction="Callback7"/>
<button id="insfav3" onAction="Callback8" getLabel = "RibbonControl.buttonLabel8"/>
<button id="insfav4" label="Empty 04" onAction="Callback9"/>
<button id="insfav5" label="Empty 05" onAction="Callback10"/>

I guess (although I'm not sure) this is okay. Validation says "Well formed".

Next was the VBA code to read the shape name and put it into the label.

Option Explicit
Dim oRibbon As IRibbonUI

'Callback for customUI.onLoad
Sub OnRibbonLoad(ribbon As IRibbonUI)
Set oRibbon = ribbon
End Sub

'Callback for addfav3 getLabel
Sub buttonLabel3(control As IRibbonControl, ByRef returnedVal)
Select Case control.Id
Case Is = "addfav3"
returnedVal = Application.Presentations("C:\Users\Chef\Desktop\MyFiles.pptx").Slides(3).Shapes(1).Name
End Select

oRibbon.InvalidateControl "addfav3"
End Sub

Fact is, nothing happens, while debugging doesn't alert me as long as I don't close and re-open the presentation. Then it says: "Item MyFiles not found in the presentations collection." And this is leaving me helpless, as the presentation exists and is exactly where I defined. The macros for adding and inserting use the same path - and they work. So, the first question is: Is it impossible to use a path like this for "returnedVal"? If yes, what can I do? If not, what's wrong with mine?

Due to my lack of expertise there maybe more mistakes, but until now I didn't get that far, as debugging stops at the line with returnedVal and my thoughts circle around the question what might be wrong with my path. Maybe I return with other problems later ... (well, if you already see them coming, feel free to let me know ;-)

Thanks for your time and your thoughts!


Btw.: The name of the module is RibbonControl.

06-15-2015, 07:45 PM
Item MyFiles not found in the presentations collection."

I believe that it needs to be open, and that you need to refer to it as "MyFiles.pptx"


returnedVal = Presentations("MyFiles.pptx").Slides(3).Shapes(1).Name

06-16-2015, 04:06 AM
Hi Paul,

thank you for your advice. The shorter reference doesn't work either, so your belief that MyFiles has to be open to make the getLabel function catch the shape names seems to be true. This is bad news. I dislike the idea of having MyFiles open all time as it makes it difficult to manage which presentation is the active one when the macros copy shapes from one to the other. Is there any other way to give the user the possibility to name his selection and make these names visible on the toolbar?

This is the code I used for the copy and paste from a to b and back, including the input box to rename shape names. As the shape names seem to be not the ideal way to solve it, that part seems to be obsolete now, but maybe I could name something else in a similar way ...

Public Sub Callback3(control As IRibbonControl)
Dim trg As Presentation
Dim sld As Slide
Dim target As Presentation
Dim shp As Shape
Dim Message As String
Dim Title As String
Dim Default As String
Dim MyValue3 As String

On Error GoTo err
If ActiveWindow.Selection.ShapeRange.Count < 1 Then
MsgBox "Please select a shape"
Exit Sub
End If
'Create an InputBox
Message = "Please give your selection a name (please use letters and numbers only, and no blanks)"
Title = "Add to MyFiles"
Default = "ObjectName"
MyValue3 = InputBox(Message, Title, Default)

'Let the user's input define the name
For Each shp In ActiveWindow.Selection.ShapeRange
shp.Name = MyValue3

'Copy the selected objects

'Open the target presentation
Set target = Application.Presentations.Open("C:\Users\Chef\Desktop\MyFiles.pptx")
Set trg = Presentations("MyFiles.pptx")

'Go to the wanted slide
ActiveWindow.View.GotoSlide (3)

'Select all shapes on the slide

'Delete what has been stored there

'Go to target slide and paste
Set sld = ActiveWindow.View.Slide

'Close the target presentation
With Application.Presentations("MyFiles.pptx")
End With
Exit Sub

MsgBox "Select at least one shape"

End Sub

And getting it back:

Public Sub Callback8(control As IRibbonControl)
Dim src As Presentation
Dim trg As Slide
Dim shp As Shape
Dim target As Presentation
'Open the source presentation
Set target = Application.Presentations.Open("C:\Users\Chef\Desktop\MyFiles.pptx")
Set src = Presentations("MyFiles.pptx")

'Go to the wanted slide
ActiveWindow.View.GotoSlide (3)

'Select all shapes on the slide

'Copy the whole selection

'Close the source presentation
With Application.Presentations("MyFiles.pptx")
End With

'Go to target slide and paste
Set trg = ActiveWindow.View.Slide

End Sub

Is it a possibility to work with five different files (each with only one slide) and let the user define their names via Input box, which then is caught and displayed on the ribbon by the getLebel function or would it come to exactly the same problem - the files have to be open?

06-16-2015, 06:33 AM
Could you use a hidden slide in the presentation itself and not in a 'master library'?

06-16-2015, 07:07 AM
Well, when it is stored in the presentation itself, it won't be accessable while working in other presentations as far as I understand. I would like to make the buttons adding to/inserting from the 'master library' part of a ppam.

06-16-2015, 07:48 AM
As you can see in the codes for add to/insert from these macros are independent from the shape names. They act on the slide number. Would it be an idea to store the names given by the user somewhere else and let getLabel take it from there? Maybe paste the names given by the user into some cells of a hidden Excel sheet? Or would this have the same problem - that the Excel sheet has to be open, to be read by the getLabel function?

07-22-2015, 08:15 AM
Your callback would need to open the presentation, do whatever is required, and then close it again. That seems like a lot of overhead simply to change the caption though.

07-22-2015, 09:41 AM
That's true. I'm still open for better ideas.