I need to write a program that can walk through a presentation and change all the instances of a text string to a different one. So, for example, where ever the text string "Old Company Name" appears, it replaces it with "New Company Name".

I get the general idea of how to automate Powerpoint, the challenge is that it is hard to walk the shapes object, and I don't see obvious properties where this data is stored (like, for example, a "Text" property.)

Can someone point me in the right direction?

Also, is there a tool that makes it easier to dig in to the object model of Office products, that is to say walk the instance object tree of a particular document? Normally I'd do this with the Visual Studio debugger, but because it is a thin layer on top of COM, you can't readily walk the object instance tree in the watch window as I would do in other circumstances. Is there a good tool to help with this?

PPT 2010 if it matters.


Powerpoint is one of the more tricky Office applications to automate (using VBA) simply because you cannot record macros like you can with Word and Excel. I've found the best way of learning the object model is a combination of web searches and the Object Browser with the VBIDE (just press F2).

As for the text replacement, it's a case of easy once you know. You can loop through all the shapes in a particular slide and then check the text for that shape. (note this code actually comes from an Excel workbook so it has the Powerpoint references which wouldn't be necessary from within Powerpoint:

Edit: Steve makes a very good point about the original edit only search text boxes, depending on your presentation setup you'd have to individually sort through every type of object and implement a custom replace on each type. Not particularly difficult just a pain in the rear.

Also note, that depending on the size of the presentation, it could take a while to cycle through all the shapes. I've also used a combination of .HasTextFrame/.HasTable with .Type so you can see both types.

Sub ReplaceTextShape(sFindText As String, sNewText As String, ppOnSlide As PowerPoint.Slide)
    Dim ppCurShape As PowerPoint.Shape

    For Each ppCurShape In ppOnSlide.Shapes
        If ppCurShape.HasTextFrame Then
            ppCurShape.TextFrame.TextRange.Text = VBA.Replace(ppCurShape.TextFrame.TextRange.Text, sFindText, sNewText)
        ElseIf ppCurShape.HasTable Then
            Call FindTextinPPTables(ppCurShape.Table, sFindText, sNewText)
        ElseIf ppCurShape.Type = msoGroup Then
            Call FindTextinPPShapeGroup(ppCurShape, sFindText, sNewText)
            ''Note you'll have to implement this function, it is an example only
        ElseIf ppCurShape.Type = msoSmartArt Then
            Call FindTextinPPSmartArt(ppCurShape, sFindText, sNewText)
        ElseIf ppCurShape.Type = msoCallout Then
        ElseIf ppCurShape.Type = msoComment Then
            'etc etc
        End If
    Next ppCurShape

    Set ppCurShape = Nothing
End Sub

Then to replace all the text in an entire presentation:

Sub ReplaceAllText(ppPres As PowerPoint.Presentation)
    Dim ppSlide As PowerPoint.Slide

    For Each ppSlide In ppPres.Slides
        Call ReplaceTextShape("Hello", "Goodbye", ppSlide)
    Next ppSlide

    Set ppSlide = Nothing
End Sub

And the example code to replace text in a table:

Sub FindTextinPPTables(ppTable As PowerPoint.Table, sFindText As String, sReplaceText As String)
    Dim iRows As Integer, iCols As Integer

    With ppTable
        iRows = .Rows.Count
        iCols = .Columns.Count

        For ii = 1 To iRows
            For jj = 1 To iCols
                .Cell(ii, jj).Shape.TextFrame.TextRange.Text = VBA.Replace(.Cell(ii, jj).Shape.TextFrame.TextRange.Text, sFindText, sReplaceText)
            Next jj
        Next ii
    End With

End Sub
  • Just a caution: This won't really replace all the text in a presentation. It will miss text on shapes that are grouped, text in tables, text in charts, text in smartshapes and, I'm sure, a couple of other bits I'm not thinking of offhand. Ah. And shapes on masters & layouts & notes pages. – Steve Rindsberg Jan 21 '14 at 16:50
  • @SteveRindsberg Fair call, I've made an edit. – CuberChase Jan 21 '14 at 23:23
  • nicely done. If I were doing this, I'd write the sub so that I could call it once per shape, passing the shape to it as a param. That way you could pass each shape within a group to the function recursively which'd then deal with groups within groups (within groups within....) – Steve Rindsberg Jan 22 '14 at 5:07

Your Answer

