0

I have a macro in Powerpoint that gives me Information of a Shape. To bypass the error if no shape is selected I insert an errormask. However, this is very annoying.

Is it therefore possible to grey out the button if e.g. no Shape is selected. That way the user would npot even have a chance to click it.

Custom UI XML: http://pastebin.com/T6NQ8WF8

David Zemens
  • 53,033
  • 11
  • 81
  • 130
Kibou
  • 63
  • 1
  • 2
  • 8
  • I don't know much about vba in powerpoint, but if the button has properties. `ButtoneName.enabled=false`? – Elias Aug 19 '13 at 11:57
  • @Elias ribbon controls can only be manipulated via Ribbon XML extensibility, in PPT 2007+. – David Zemens Aug 19 '13 at 13:54
  • @Kibou what version of PowerPoint are you using? – David Zemens Aug 19 '13 at 13:55
  • Well, I dont wanna have the message. And after the macro is clicked it is to late. So ignore the macro itself. Is there a setting that greys your all buttons that don't have an effect. E.g.: Open your powerpoint. You will see that e.g. the font selection is greyed out if you have nothing selected. I want this, for my buttons that I insert with Custom UI Editor. – Kibou Aug 20 '13 at 10:41
  • @Kibou If you really don't want to see the message, then simply remove that line, and the macro will have no effect when nothing is selected. That is the easiest solution. Otherwise, please provide the XML from CustomUI Editor. Perhaps I can expand on my answer below. There is **not** a simple "setting" or VBA command that will do this, you **must** use ribbon extensibility as I mentioned above, and in my answer, below. – David Zemens Aug 20 '13 at 14:04
  • @Kibou I have provided a solution for you, below. Please note that it is relatively complicated to implement and manage this solution. I still think it is not necessary to do this, but provide you a reference file. I hope it can help you. – David Zemens Aug 20 '13 at 17:59

1 Answers1

1

Assuming you are using a 2007+ version of PowerPoint, the only way to manipulate the ribbon controls, buttons, etc., is through ribbon extensibility. It is possible to do this at run-time, with a vba hook, but it is much more difficult than in previous versions of PowerPoint where you could just use VBA to manipulate the controls' .Enabled or .Visible properties.

Here is an example of using ribbon extensibility to customize the ribbon at run-time. As you can see, it is not easy. I will show this in Option 2, below.

In this case, you have an error condition that you can easily identify using the .Type property of the Selection.ShapeRange. I think that attempting to conditionally disable this button at run-time (Option 2, below) is probably more trouble than it is worth.

Update

Is there a setting that greys your all buttons that don't have an effect.

No. The macros are the "effect", even if the result of the macro is that no action is performed. What you are asking is whether there is a setting which can compile and interpret your macros, determine whether that macro performs "an action" (e.g., manipulates a shape, changes a property assignment, etc.) and then disable buttons based on this determination. There is no such setting.

OPTION 1 -- Simply Do Not Display the MsgBox; Perform No Action if Invalid Selection

I will make some edits to clean up your code and use a better method of avoiding that error:

Sub Infos()

   Dim n as String
   Dim w as String
   Dim h as String
   Dim l as String
   Dim T as String

   With ActiveWindow.Selection.ShapeRange
   Select Case .Type
        Case 0
            'MsgBox ("No shape selected.")
            Exit Sub
        Case Else
            n = .Name
            w = .Width
            h = .Height
            l = .Left
            T = .Top

            MsgBox "Name: " & n & Chr$(CharCode:=13) & "Länge: " & w & _
                   Chr$(CharCode:=13) & "Höhe: " & h & Chr$(CharCode:=13) & _
                   "Linkeposition: " & l & Chr$(CharCode:=13) & "Höhenposition: " & T
    End Select
End Sub

OPTION 2 -- Use an Application Event Handler and Manipulate Ribbon at Run-Time

I mentioned that this is not easy. I uploaded an example file to Google Docs Presentation1.pptm. This should get you started. You can see now how much difficult this method is. If you are creating a PPAM/Add-In file, there are further considerations and complexities you may encounter. Good luck!

There are several errors in your code.

1. Your XML is not valid when I check in Custom UI Editor. I edited it here:

http://pastebin.com/SpG0Rtqq

2. Your Infos macro contains errors. You omit the End With statement, also, your n assignment will fail (and the rest of them will produce strange result) if the selection is multiple shapes. You can fix that by:

n = IIf(.ShapeRange.Count > 1, "Multiple shapes", .ShapeRange(1).Name)
w = IIf(.ShapeRange.Count > 1, "Multiple shapes", .ShapeRange(1).Width)
h = IIf(.ShapeRange.Count > 1, "Multiple shapes", .ShapeRange(1).Height)
l = IIf(.ShapeRange.Count > 1, "Multiple shapes", .ShapeRange(1).Left)
T = IIf(.ShapeRange.Count > 1, "Multiple shapes", .ShapeRange(1).Top)

Once you have fixed those components...

Add a module called mod_EventHandler, which includes this code. This will create an application event-handler class object, cEventClass:

Option Explicit
Public cPPTObject As New cEventClass
Public TrapFlag As Boolean

Sub TrapEvents()
'Creates an instance of the application event handler
If TrapFlag = True Then
   MsgBox "Relax, my friend, the EventHandler is already active.", vbInformation + vbOKOnly, "PowerPoint Event Handler Example"
   Exit Sub
End If
   Set cPPTObject.PPTEvent = Application
   TrapFlag = True
End Sub

Sub ReleaseTrap()
If TrapFlag = True Then
   Set cPPTObject.PPTEvent = Nothing
   Set cPPTObject = Nothing
   TrapFlag = False
End If
End Sub

Since we need this class object, add a class module to your PowerPoint file, named cEventClass. In this module, put this code below. This code forces a refresh of the ribbon. This procedure implicitly calls the EnabledBtInfo subroutine, which then tests if the current selection is Shape(s).

Option Explicit
Public WithEvents PPTEvent As Application
Private Sub PPTEvent_WindowSelectionChange(ByVal Sel As Selection)
    'Force refresh of the "btInfo" button:
    RefreshRibbon "btInfo"
End Sub

And finally, another standard code module with this code to control the Button's visibility/enabled. Note that EnabledBtInfo is the VBA Hook for this button, and it tests whether Selection is shapes, before refreshing the ribbon:

Option Explicit
Public Rib As IRibbonUI
Public xmlID As String

'Callback for customUI.onLoad
Sub RibbonOnLoad(ribbon As IRibbonUI)
    TrapEvents  'instantiate the event handler
    Set Rib = ribbon
End Sub

Sub EnabledBtInfo(control As IRibbonControl, ByRef returnedVal)
    'Check the ActiveWindow.Selection.ShapeRange
    returnedVal = (ActiveWindow.Selection.Type = ppSelectionShapes)
    Call RefreshRibbon(control.Id)
End Sub

Sub RefreshRibbon(Id As String)
    xmlID = Id
    If Rib Is Nothing Then
        MsgBox "Error, Save/Restart your Presentation"
    Else
        Rib.Invalidate
    End If
End Sub

When a shape(s) is selected, the magnifying glass icon is enabled:

enter image description here

When shape(s) is not selected, button is disabled:

enter image description here

And finally, when multiple shapes are selected:

enter image description here

Community
  • 1
  • 1
David Zemens
  • 53,033
  • 11
  • 81
  • 130
  • Well, but I know that this is a macro that edits shapes: – Kibou Aug 20 '13 at 16:23
  • You *know* this macro edits shapes, but the compiler doesn't know this, because the application doesn't *know* anything. It simply executes commands. Please add your full XML to the original question. Above you have included only partial XML. I need the full XML to be of any more assistance. – David Zemens Aug 20 '13 at 16:29
  • Thanks, I see this. I will take a look and try to help. – David Zemens Aug 20 '13 at 16:30
  • Cheers! Please do consider marking this answer as "Accepted" if it's solved your problem :) – David Zemens Aug 21 '13 at 14:29