Consulting

Results 1 to 16 of 16

Thread: PowerPoint vba - Event not fired when screen is empty

  1. #1

    PowerPoint vba - Event not fired when screen is empty

    Note: I did post this question also on StackOverflow and Docs.Microsoft.com:
    https://stackoverflow.com/questions/...creen-is-empty. Here I have had many help already, but not for this problem.
    https://docs.microsoft.com/en-us/ans...owerpoint.html.
    I could not solve the problem yet, so that is why I post it here also and hope to find a solution ...

    I am making an add-in with a custom Ribbon Tab. When PowerPoint is opened, and the add-in is loaded, the user only sees three buttons on the custom Tab (= the choice between three templates) which can be used to start a new presentation.
    When template A is choosen to make a new presentation, group 1 (with a set of buttons) gets visible on the custom Ribbon Tab.
    When the presentation is closed, the group disappears. When template B is choosen, group 2 appears. When template C is choosen, group 3 appears. The groups are never visible all together.
    So everytime a presentation is new created, closed or opened, the Ribbon has to refresh. The Getvisible code is checking the Design name of the template to see which group has to be visible.

    This works fine as long as there is already a presentation open on screen. But as soon as there is no presentation open (empty PowerPoint screen) and a new presentation is made via the custom Tab, the Ribbon does not refresh. The template-depended group does not appear in the Ribbon. This also happens when I open an existing presentation on an empty screen. I can also see in another way that the Ribbon is not refreshed because of the fact that after the Event, the Ribbon does not go back to the Home Tab.
    I can't figure out where it goes wrong. Here is my code:

    XML:

    <customUI onLoad="RibbonOnLoad"  …>
     
    <group id="MyCustomGroup1" label="Name" getVisible="GetVisible" tag="MyPersonalGroup1"
    And there I've added some custom buttons.
    I also made "MyPersonalGroup2" and "MypersonalGroup3" like this.
    VBA:

    Dim Rib As IRibbonUI
    Dim MyTag As String
     
    'Callback for customUI.onLoad
    Sub RibbonOnLoad(ribbon As IRibbonUI)
        Set Rib = ribbon
        MsgBox "Ribbon Loaded"
    End Sub
     
    Sub getVisible(control As IRibbonControl, ByRef returnedVal)
    Select Case control.Tag
        Case "MyPersonalGroup1"
            returnedVal = ActiveWindow.Selection.SlideRange.Design.Name = ("TemplateA")
        Case "MyPersonalGroup2"
            returnedVal = ActiveWindow.Selection.SlideRange.Design.Name = ("TemplateB")
        Case "MyPersonalGroup3"
            returnedVal = ActiveWindow.Selection.SlideRange.Design.Name = ("TemplateC")
    End Select
    End Sub
    Class module ApplicationEventClass:

    Public WithEvents PPTEvent As Application
     
    Private Sub PPTEvent_WindowSelectionChange(ByVal Sel As Selection)
        MyTag = Tag
        If Rib Is Nothing Then
            MsgBox "Error, restart your presentation"
        Else
            Rib.Invalidate
        End If
    End Sub
    I repeated this code for 'PPTEvent_NewPresentation' 'PPTEvent_AfterNewPresentation' 'PPTEvent_AfterPresentationOpen' 'PPTEvent_PresentationOpen' 'PPTEvent_PresentationClose'

    And this Module going with the code above:

    Dim X As New ApplicationEventClass
    Sub InitializePPTEvent()
    Set X.PPTEvent = Application
    End Sub
    Help is very much appreciated!
    Last edited by VeronicaStr; 04-04-2022 at 08:51 AM.

  2. #2
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    I'm not sure I understood all of what is happening, but here's something to look at

    I've found it usually works out better (= less confusing) to set and read boolean status variables
    Attached Files Attached Files
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  3. #3
    Hi Paul, thanks a lot!
    I immediately implemented your code into my PPTM. I saved as an add-in, but now the events do not fire at all...
    I first tried it without the btnAction code (as I want the custom groups to be visible only by checking the template name, not by clicking a button), but then the custom groups did not appear.
    Then I put in only the first part (btnA, btnB, btnC). My custom groups are quite extensive, so I thought that would be better. When I click one of the buttons, my custom group appears. But the Ribbon does not refresh on opening, starting new or closing a presentation.

    There is one other thing I don't understand. The code does not declare what bFormatA, bFormatB and bFormatC actually is. In my previous code I referred to the tags of the groups in the Custom UI ("MyPersonalGroup1" etc).
    Should I not declare that somewhere?

    I could send you my complete code if you want to take a look at it?

    Thanks for your help!
    Veronica
    Last edited by VeronicaStr; 04-05-2022 at 04:19 AM.

  4. #4
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    Module 1 --

    Option Explicit
    
    
    Public oRibbon As IRibbonUI
    Public bFormatA As Boolean, bFormatB As Boolean, bFormatC As Boolean   ' <<<<<<<<<<<<<<<<<<<<<<
    Public oApp As ApplicationEventClass
    Right click on variable and select [Definition] and the editor will take you to where it's defined

    Picture1.jpg

    Edit - forgot to attach latest attempt

    Format_Addin.pptm is the source for the addin
    I left a bunch of MsgBox lines in for now
    It seems to throw an error on closing when the addin (PPAM) is also loaded and I open and close the PPTM. No error it the PPAM is not loaded
    Attached Files Attached Files
    Last edited by Paul_Hossler; 04-05-2022 at 12:53 PM.
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  5. #5
    Thanks a lot, this has been of so much help!
    I changed on thing:
    When there was no presentation open (empty screen) and I click on one of the template buttons, I got the run-time error "There is no currently active document window" See image:
    Run-time error no currently active document window.jpg
    So I changed the Sub GrpVisible code from "If ActiveWindow is Nothing Then" to "If Windows.Count = 0 Then" and now it works fine, I don't get that run-time error anymore.

    Now there is only one thing I have to solve. If the cursor is between two slides in the left-hand pane with slide thumbnails (so no slides selected), I get the run-time error "Nothing appropriate is currently selected". The debugger point to the Sub GrpVisible line "With ActiveWindow.Selection.SlideRange.Design" Could it be the WindowSelectionChange Event? I'm not sure, as the msg box "change" never appears... It happens when I save the PPTM to PPAM and load the add-in
    Last edited by VeronicaStr; 04-06-2022 at 10:11 AM. Reason: changed picture

  6. #6
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    So I changed the Sub GrpVisible code from "If ActiveWindow is Nothing Then" to "If Windows.Count = 0 Then" and now it works fine, I don't get that run-time error anymore.
    That's good. I tried a number of things to get rid of the error

    I only got it some times and it's hard to debug an addin

    Try this and see if it works

    'Callback for grpA / grpB / grpC getVisible
    Sub GrpVisible(control As IRibbonControl, ByRef returnedVal)
        If Windows.Count = 0 Then
            returnedVal = False
        
        ElseIf ActiveWindow.Selection.Type = ppSelectionNone Then
            returnedVal = False
        
        ElseIf ActiveWindow.Selection.Type = ppSelectionSlides Then
            returnedVal = False
        
        Else
            With ActiveWindow.Selection.SlideRange.Design
                Select Case control.Id
                    Case "grpA"
                        returnedVal = (.Name = "TemplateA")
                    Case "grpB"
                        returnedVal = (.Name = "TemplateB")
                    Case "grpC"
                        returnedVal = (.Name = "TemplateC")
                End Select
            End With
        End If
        
        oRibbon.Invalidate
    
    
    End Sub
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  7. #7
    VBAX Master
    Joined
    Feb 2007
    Posts
    2,093
    Location
    AFAIK there is no way to detect where the cursor is if it is between slides.

    A workaround is to change the view and then change it back. The slide before the cursor is now selected

    ActiveWindow.ViewType = ppViewOutline
    
    ActiveWindow.ViewType = ppViewNormal
    John Wilson
    Microsoft PowerPoint MVP
    Amazing Free PowerPoint Tutorials
    http://www.pptalchemy.co.uk/powerpoi...tutorials.html

  8. #8
    Isn't is possible to say something like:
    If selection is nothing Then do nothing?
    That way the Ribbon stays as is at the time when the cursor is placed between slides, which is OK.

    ActiveWindow.ViewType = ppViewOutline
    ActiveWindow.ViewType = ppViewNormal
    When I put these two lines in the code (after Else), PowerPoint is flashing non-stop and crashes eventually
    I removed the event WindowSelectionChange, because I thaught it was causing the problem, but it didn’t.

    I tried the two options ppSelectionNone and ppSelectionSlides too.
    With the ppSelectoinNone the tabgroup also disappears if I don’t have anything selected on the slide.
    With ppSelectionSlides the run-time error appears too.

    I now have this code:
    [CODE]
    'Callback for grpA / grpB / grpC getVisible
    Sub GrpVisible(control As IRibbonControl, ByRef returnedVal)
        If Windows.Count = 0 Then
            returnedVal = False
      
     'In the slide sorter view I get the run-time error too, so I added this code. That works fine.
        ElseIf ActiveWindow.ActivePane.ViewType = ppViewSlideSorter Then
        returnedVal = False
       
        Else
            With ActiveWindow.Selection.SlideRange.Design
                Select Case control.Id
                    Case "grpA"
                        returnedVal = (.Name = "TemplateA")
                    Case "grpB"
                        returnedVal = (.Name = "TemplateB")
                    Case "grpC"
                        returnedVal = (.Name = "TemplateC")
                End Select
            End With
        End If
       
        oRibbon.Invalidate
     
    End Sub

  9. #9
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    I took this ...

    If the cursor is between two slides in the left-hand pane with slide thumbnails (so no slides selected), I get the run-time error "Nothing appropriate is currently selected".
    ... to mean

    Capture.JPG

    which isn't the same as Slide Sorter View

    Capture2.JPG


    With the cursor between slides on the left, then ActiveWindow.Selection.Type = ppSelectionNone

    With one of the slides on the left selected, then ActiveWindow.Selection.Type = ppSelectionSlides


    Sub test()
    
    
        Stop
    
    
        If ActiveWindow.Selection.Type = ppSelectionNone Then
            MsgBox "None1"
        ElseIf ActiveWindow.Selection.Type = ppSelectionSlides Then
            MsgBox "None2"
        End If
    End Sub
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  10. #10
    Hi!
    The first picture describes the problem correctly! The reason I added code for the slide sorter view, is that I get the run-time error there too, if the cursor is between two slides.
    So I get this run-time error in two occassions. Slide Sorter View is fixed now, but "If the cursor is between two slides in the left-hand pane with slide thumbnails" not...

    I was now thinking about something like "
    If Selection is nothing Then do nothing" Or maybe "Exit Sub" to skip the whole refreshing in that case. But I don't know if that is possible...


  11. #11
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    Try adding the code I added in #6 and see if something like that works

    'Callback for grpA / grpB / grpC getVisible
    Sub GrpVisible(control As IRibbonControl, ByRef returnedVal)
    If Windows.Count = 0 Then
    returnedVal = False
    ElseIf ActiveWindow.Selection.Type = ppSelectionNone Then
    returnedVal = False
    ElseIf ActiveWindow.Selection.Type = ppSelectionSlides Then
    returnedVal = False
    ElseIf ActiveWindow.ActivePane.ViewType = ppViewSlideSorter Then
    returnedVal = False
    Else
    With ActiveWindow.Selection.SlideRange.Design            
    Select Case control.Id                
    Case "grpA"                    
    returnedVal = (.Name = "TemplateA")                
    Case "grpB"                    
    returnedVal = (.Name = "TemplateB")                
    Case "grpC"                    
    returnedVal = (.Name = "TemplateC")            
    End Select        
    End With    
    End If        
    oRibbon.Invalidate 
    End Sub
    Last edited by Aussiebear; 04-08-2022 at 03:37 PM.
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  12. #12
    I think I found a workaround. Referring to the design name turns out to be very unstable. All kinds of tricks have to be used to make it work without run-time errors.
    So then I thought it might be better to refer to a fixed value, while it doesn't matter if you select something or not. So now I refer to Keywords in the Document Properties. I entered the template name there and it works! See below the code:

    'Callback for grpA / grpB / grpC getVisible
    Sub GrpVisible(control As IRibbonControl, ByRef returnedVal)
       
        If Windows.Count = 0 Then
        returnedVal = False
        
        'I think i can delete this but for now it is still here
        ElseIf ActiveWindow.ActivePane.ViewType = ppViewSlideSorter Then
        returnedVal = False
            
        Else
            With ActivePresentation.BuiltInDocumentProperties
                Select Case control.Id
                    Case "grpA"
                        returnedVal = .Item("keywords").Value = ("TemplateA")
                    Case "grpB"
                        returnedVal = .Item("keywords").Value = ("TemplateB")
                    Case "grpC"
                        returnedVal = .Item("keywords").Value = ("TemplateC")
                    Case Else
                        returnedVal = False
                End Select
            End With
        
        End If
        
    oRibbon.Invalidate
    
    End Sub
    What do you think of it?

  13. #13
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    Seems like it'd be a better choice

    I'd suggest that you use

    If ActivePresentation.BuiltInDocumentProperties("Template") = "FormatA" Then
    since 'keywords' might have multiple ... well, keywords ... like "Sales, 2021, FormatA, Ver3" and

    1. A straight equality test won't work
    2. A user might change or delete keywords
    3. The only way I know to set the Template property is via the Immediate Window, which is beyond your typical user, or by creating the PPTX (File, New) from a POTX

    Capture2.JPG


    Capture.JPG
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  14. #14
    That's a good idea!
    I start a new presentation from a template. I can't store the template name in the template itself, but when a new presentation is started, the name is there, so that should work.
    Or is setting a Customdocumentproperty maybe an even better idea? For instance I create TemplateName. I can set that already in the properties. If someone changes the template name it has no effect than.

  15. #15
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    The way I believe it works makes me think that

    Using FormatA.potx to create SalesJan.pptx (example) then the built in Template property for SalesJan.pptx = "FormatA".

    Using FormatB.potx to create CostsJan.pptx (example) then the built in Template property for CostsJan.pptx= "FormatB".

    I'd think that would be enough


    If you're concerned, then when a new PPTX is created, you could add a CustomDocumentProperty ("OriginalTemplate") = BuildinDocumentProperty ("Template") and test against that

    Personally I think that's overkill, but then you should never trust Users
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  16. #16
    but then you should never trust Users
    Hahaha, that is so true. They ruin things you did not know could be ruined ....

    Many thanks for all your help! Have a nice weekend!
    All the best, Veronica

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •