Simple delete shapes with vba, but not working

B

brett

I thought this would be easy, but it's giving me fits. I want my macro to
run on a single slide while in the edit mode of PPT 2002, and delete certain
slide items that have specific names. But it always misses one. One. Always.

For example on a title/text slide layout, I have 4 objects in the slide. The
first two (placeholders) have default names and the second two (rectangles)
have been assigned custom names via VBA:

Shapes:
Placeholder(1) with name "rectangle 2"
Placeholder(2) with name "rectangle 4"
Rectangle with name: "tempOrangeBox"
Rectangle with name: "tempBlueBox"

So, I use the following code to delete any objects with a name beginning
with "temp", and it consistantly misses one "temp" object, no matter how
many there are. If I have two, it finds only one, if I have three it finds
only two. The shape it misses has the "temp" name and it can be verified in
the multiple object tool as well through VBA.

BTW, I have the same problem when I run it on shapes with default names. For
example, with three ovals in a slide, I change the code to delete anything
starting with "oval" and it deletes only two of the three ovals. So, I'm not
sure my issue has to do with custom names. Here's what I use:

Sub DelTempShapes()
Dim oShape As Shape
For Each oShape In ActiveWindow.Selection.SlideRange.Shapes
With oShape
If Left(.Name, 4) = "temp" Then .Delete
End With
Next oShape
End Sub

I'm sure I'm just missing something. Probebly something dumb. But, I would
sure love someone to point it out or show me a better way to do this.

Thank you for your time,
Brett
 
G

Glen Millar

Hi,

Well, I can't answer your question, but on another tack. I saw some
modelling code today that was written in natural language something like:
"please compare product x to product y as a percent". Natural language in
vba would be wonderful. And if it was in Australian, we would all be better
off! Like:

Please dot get-rid-of dot mongrel dot temp-thingy

Anyway, one of our vba persons who speak vba-lish (US version) will know.

--
Regards,

Glen Millar
Microsoft PPT MVP
www.powerpointworkbench.com

Australia

Please tell us your PowerPoint version,
whether you are using vba,
whether your dog has fleas, or
anything else relevant.
 
S

Steve Rindsberg

Hi Brett,

When you're iterating a collection and deleting stuff, the pointers get off.

Ex: in your case:

First time through the loop, pointer is at 1 so you're looking at the first
object. You delete it.

Second time through the loop, pointer is at two so you're looking at the second
object, but it doesn't exist, because you've just deleted one of the two
objects; pointer's at 2 but total number of objects is 1. oops.

Instead, do it backwards:

For X = .Shapes.Count to 1 Step -1
' test, delete if need be
Next
 
B

brett

Steve, you saved my sanity! I'm glad I wrote the question in, because I
wouldn't have ever thought of stepping backwards through the iteration.
That's wild... and it worked great.

Here's my finished code:

Sub DelTempShapes()
Dim oSlide As SlideRange
Set oSlide = ActiveWindow.Selection.SlideRange
With oSlide
For x = .Shapes.Count To 1 Step -1
With .Shapes(x)
If Left(.Name, 4) = "temp" Then .Delete
End With
Next x
End With
End Sub
 
S

Steve Rindsberg

Steve, you saved my sanity! I'm glad I wrote the question in, because I
wouldn't have ever thought of stepping backwards through the iteration.
That's wild... and it worked great.

Here's my finished code:

Looks good, but if this is for use by others, watch out for a couple things:

If the user's in Slide Sorter view, .SlideRange can contain more than one
slide. In that case, you can either work on .SlideRange(1) or do something
like this if you want to process all of the slides in the range:

Dim oSl as Slide
For Each oSl in oSlide ' your sliderange
' do yer stuff
Next

Also, add a little error trapping in case the active window can't have a slide
range as a selection.
 
B

brett

Steve Rindsberg said:
If the user's in Slide Sorter view, .SlideRange can contain more than one
slide.

I gotcha. The code is inside a larger loop iterating through each slide in
the selection. Thanks for the heads-up.
Also, add a little error trapping in case the active window can't have a
slide
range as a selection.

Ouch. I see what you mean. Ok, early on, I'd like to ensure the user is in a
window that can reference a slide range AND where the code can edit slide
objects. I'm thinking that would be normal or slide view, right? Is that
what you are warning about?

What about this...?

If Application.Version > 8 Then 'v2000+ (v97 lacked normal view)
If ActiveWindow.ViewType <> ppViewNormal Then
ActiveWindow.ViewType = ppViewNormal
End If
Else 'v97
If ActiveWindow.ViewType <> ppViewSlide Then
ActiveWindow.ViewType = ppViewSlide
End If
End If

Of course with that action, they loose their multiple slide selections if
they were, say, in Slide Sorter. It'd be nice to bring that selection
array-reference over and continue the routine. Otherwise, I'll have to stop
and ask them to reselect once in the correct view. Any suggestions before I
wonder aimlessly through the vba jungle?
 
S

Steve Rindsberg

Steve Rindsberg said:
I gotcha. The code is inside a larger loop iterating through each slide in
the selection. Thanks for the heads-up.


Ouch. I see what you mean. Ok, early on, I'd like to ensure the user is in a
window that can reference a slide range AND where the code can edit slide
objects. I'm thinking that would be normal or slide view, right? Is that
what you are warning about?

What about this...?

Have a look at Selection.Type instead.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top