0
votes

I have this PPT vba script to delete all shapes in a region at the bottom left corner of each slide. It works but sometimes it leaves one shape in the area. If I run it again it will get rid of it, but I don't want to have to run it twice! How can I fix this?

Sub GoAwayDumbText()
 Dim oPres As Presentation
 Dim oSlides As Slides
 Dim oSld As Slide
 Dim oShp As Shape
 Dim PathSep As String
 Dim sTempString As String

#If Mac Then
PathSep = ":"
#Else
PathSep = "\"
#End If

Set oPres = ActivePresentation
Set oSlides = oPres.Slides

For Each oSld In oSlides
For Each oShp In oSld.Shapes
    If oShp.Left <= 135 And oShp.Top >= 260 Then
    oShp.Delete
    Else
    End If
Next oShp

Next oSld

End Sub
1
Have you checked the actual positions of each shape to be sure they meet the criteria for deletion? Does seem a bit weird that you have to run twice. Wondering if one of the shapes somehow has its relative position set against something else in the first run... - QHarr
One possibility is that you are deleting a shape which is a placeholder shape with content. Any time you delete such a shape an empty placeholder is added in its place. You would have to delete that empty placeholder as well. - Shyam Pillai
In addition to Shyam's suggestion, you need to use a For x = osld.Shapes.Count to 1 Step -1 loop rather than For Each oShp. - Steve Rindsberg
@SteveRindsberg: You have hit the nail on the head. Should post that as the answer. - AJD
Thankyou @SteveRindsberg You did indeed solve it! - quickreactor

1 Answers

0
votes

When you're iterating through a collection (shapes, slides, whatever) and deleting items along the way, For/Each loops won't behave as expected.

Instead, use (in this case)

For x = oSld.Shapes.Count to 1 Step -1

Delete from the end of the collection to the beginning rather than from the beginning to the end.

Why?

Suppose you have three items in the collection:

VBA starts with its internal For/Each counter set to 1 First item meets your criteria, you delete it VBA increments its internal For/Each counter to 2 Since you deleted one item, there are only two items left in the collection, so VBA looks at the second item (which USED TO BE the third item) and deletes it. VBA increments its internal counter to 3, but you've deleted the first two of three original items, so there's only 1 item in the collection; there's no item three so what used to be item 3 never gets looked at.

[If anyone can offer a better/clearer explanation of this, PLEASE have at it.]