Search code examples
vbapowerpoint

VBA Script not recognizing certain image types


I am trying to run scripts that edit images automatically in a powerpoint presentation. There is no issue with the scripts themselves, they work great, but for some reason some of the images are unaffected by the script. I'll include the code to show how many object types I have tried to call. None of them work.

Sub ImageTablePosition()

Dim osld As Slide
Dim oshp As Shape
Dim x As Integer
Dim y As Integer

    With ActivePresentation.PageSetup
     x = .SlideWidth / 4
     y = .SlideHeight / 2
     Z = .SlideWidth - (0.25 * .SlideWidth)
    End With

    For Each osld In ActivePresentation.Slides
    For Each oshp In osld.Shapes

        If oshp.Type = msoPicture _
        Or oshp.Type = msoMedia _
        Or oshp.Type = msoGraphic _
        Or oshp.Type = msoLinkedGraphic _
        Or oshp.Type = msoEmbeddedOLEObject _
        Or oshp.Type = msoLinkedPicture Then
        
            oshp.Left = x - (oshp.Width / 2)
            oshp.Top = (y - (oshp.Height / 2)) + 36
        End If
        If oshp.Type = msoTable Then
            oshp.Left = Z - (oshp.Width / 2) - 36
            oshp.Top = (y - (oshp.Height / 2)) + 36
        End If

Next
Next

End Sub

The only thing that did work was by using msoPlaceholder, but that moves the text, too. At this point, I really could just change the ones remaining in maybe 20 minutes, but it's more about me being genuinely curious why this is the case. If it helps, some of the images were uploaded to a media upload box available in the Powerpoint template, while most were simply copy and pasted in. I was wondering if that was the difference, where the ones uploaded to that box are considered something else. Thank you.


Solution

  • An option is to check the placeholder types using PlaceholderFormat.Type. I suggest you encapsulate the checking in a predicate as follows (not tested):

    Sub ImageTablePosition()
    
      Dim osld As Slide
      Dim oshp As Shape
      Dim x As Long
      Dim y As Long
    
      With ActivePresentation.PageSetup
        x = .SlideWidth / 4
        y = .SlideHeight / 2
        Z = .SlideWidth - (0.25 * .SlideWidth)
      End With
    
      For Each osld In ActivePresentation.Slides
        For Each oshp In osld.Shapes
          If IsShapeWatched(oshp) Then
            oshp.Left = x - (oshp.Width / 2)
            oshp.Top = (y - (oshp.Height / 2)) + 36
          
          ElseIf oshp.Type = msoTable Then
            oshp.Left = Z - (oshp.Width / 2) - 36
            oshp.Top = (y - (oshp.Height / 2)) + 36
          End If
        Next oshp
      Next osld
    
    End Sub
    
    
    Function IsShapeWatched(shp As Shape) As Boolean
      Dim watchedShapeTypes As Variant
      Dim watchedPlaceholderTypes As Variant
      Dim v As Variant
      
      '* Edit these arrays as needed
      watchedShapeTypes = Array(msoPicture, msoMedia, msoGraphic, msoLinkedGraphic, msoEmbeddedOLEObject, msoLinkedPicture)
      watchedPlaceholderTypes = Array(ppPlaceholderBitmap, ppPlaceholderMediaClip, ppPlaceholderPicture)
      
      If shp.Type = msoPlaceholder Then
        For Each v In watchedPlaceholderTypes
          If shp.PlaceholderFormat.Type = v Then
            IsShapeWatched = True
            Exit Function
          End If
        Next v
      Else
        For Each v In watchedShapeTypes
          If shp.Type = v Then
            IsShapeWatched = True
            Exit Function
          End If
        Next v
      End If
      
      IsShapeWatched = False
    End Function
    

    Note: You can find placeholder types here