A Microsoft Office (Excel, Word) forum. OfficeFrustration

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

Go Back   Home » OfficeFrustration forum » Microsoft Powerpoint, Publisher and Visio » Powerpoint
Site Map Home Register Authors List Search Today's Posts Mark Forums Read  

Why need to run macro twice?



 
 
Thread Tools Display Modes
  #1  
Old March 12th, 2007, 04:00 PM posted to microsoft.public.powerpoint
lisa
external usenet poster
 
Posts: 1,001
Default Why need to run macro twice?

I wrote a macro to delete the slide (title) placeholder from the currently
viewed Notes page, then change the position of the body placeholder on that
page. With my first attempt at the code, I needed to run the macro twice. The
first run deleted the slide placeholder; the second run repositioned the body
placeholder.

I rewrote the code so I need to run the macro only once, but I'm still
stumped as to why I needed to run the old version twice. (I'm still pretty
much in the dark about VBA in general and VBA for ppt in particular.)

I'd really appreciate it if you could shed some light on this. (And if you
see anything silly in the code below, please feel free to call it to my
attention, even if it has nothing to do with the question at hand.)

Thanks much!

HERE'S THE CODE IN QUESTION
Dim myShape As Shape
Dim mySlide As Slide
Dim myCheckBody, myCheckSlide As Boolean
Dim nn As Integer

Sub Fmt_Notes_FullTxt_OLD()
'Deletes the slide placeholder and puts body placeholder at top of current
Notes page
'Run while appropriate Notes pg is active window
'Must run twice to get BodyPlaceholder positioned properly
Call Name_Placehldrs_CurSlide
On Error Resume Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "SlidePlaceholder" Then
myShape.Delete
ElseIf myShape.Name = "BodyPlaceholder" Then
With myShape
.Left = 40
.Top = 50
End With
Else ' leave it alone
End If
Next
End Sub

Sub Fmt_Notes_FullTxt_NEW()
'Deletes the slide placeholder and puts body placeholder at top of current
Notes pg
'Run while appropriate Notes pg is active window
'Need to run once only
Call Name_Placehldrs_CurSlide
On Error Resume Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "SlidePlaceholder" Then myShape.Delete
Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "BodyPlaceholder" Then
With myShape
.Left = 40
.Top = 50
End With
End If
Next
End Sub

Sub Name_Placehldrs_CurSlide()
'Names the body and slide (title) placeholders on each Notes pg
'Run from any view
myCheckBody = False
myCheckSlide = False
On Error Resume Next

nn = ActiveWindow.Selection.SlideRange.SlideIndex
Set mySlide = ActivePresentation.Slides(nn)
With ActivePresentation.Slides(nn).NotesPage.Shapes
For Each myShape In mySlide.NotesPage.Shapes
If myShape.PlaceholderFormat.Type = ppPlaceholderBody Then
myShape.Name = "BodyPlaceholder"
myCheckBody = True
ElseIf myShape.PlaceholderFormat.Type = ppPlaceholderTitle Then
myShape.Name = "SlidePlaceholder"
myCheckSlide = True
Else 'leave it alone
End If
Next myShape
If myCheckBody = False Then
.AddPlaceholder(ppPlaceholderBody).Name = "BodyPlaceholder"
End If
If myCheckSlide = False Then
.AddPlaceholder(ppPlaceholderTitle).Name = "SlidePlaceholder"
End If
End With
End Sub

  #2  
Old March 12th, 2007, 04:28 PM posted to microsoft.public.powerpoint
John Wilson
external usenet poster
 
Posts: 6,023
Default Why need to run macro twice?

One quick thing Lisa

Dim myCheckBody, myCheckSlide As Boolean - doesn't do what I guess you
imagine it does. myCheckbody would be declared as a variant and only
myCheckslide as Boolean. It's a good idea to keep the Dim statements on their
own line to avoid this easy slip.

Dim myCheckBody As Boolean
Dim myCheckSlide As Boolean
--
Amazing PPT Hints, Tips and Tutorials-http://www.PPTAlchemy.co.uk
http://www.technologytrish.co.uk/ppttipshome.html
email john AT technologytrish.co.uk


"Lisa" wrote:

I wrote a macro to delete the slide (title) placeholder from the currently
viewed Notes page, then change the position of the body placeholder on that
page. With my first attempt at the code, I needed to run the macro twice. The
first run deleted the slide placeholder; the second run repositioned the body
placeholder.

I rewrote the code so I need to run the macro only once, but I'm still
stumped as to why I needed to run the old version twice. (I'm still pretty
much in the dark about VBA in general and VBA for ppt in particular.)

I'd really appreciate it if you could shed some light on this. (And if you
see anything silly in the code below, please feel free to call it to my
attention, even if it has nothing to do with the question at hand.)

Thanks much!

HERE'S THE CODE IN QUESTION
Dim myShape As Shape
Dim mySlide As Slide
Dim myCheckBody, myCheckSlide As Boolean
Dim nn As Integer

Sub Fmt_Notes_FullTxt_OLD()
'Deletes the slide placeholder and puts body placeholder at top of current
Notes page
'Run while appropriate Notes pg is active window
'Must run twice to get BodyPlaceholder positioned properly
Call Name_Placehldrs_CurSlide
On Error Resume Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "SlidePlaceholder" Then
myShape.Delete
ElseIf myShape.Name = "BodyPlaceholder" Then
With myShape
.Left = 40
.Top = 50
End With
Else ' leave it alone
End If
Next
End Sub

Sub Fmt_Notes_FullTxt_NEW()
'Deletes the slide placeholder and puts body placeholder at top of current
Notes pg
'Run while appropriate Notes pg is active window
'Need to run once only
Call Name_Placehldrs_CurSlide
On Error Resume Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "SlidePlaceholder" Then myShape.Delete
Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "BodyPlaceholder" Then
With myShape
.Left = 40
.Top = 50
End With
End If
Next
End Sub

Sub Name_Placehldrs_CurSlide()
'Names the body and slide (title) placeholders on each Notes pg
'Run from any view
myCheckBody = False
myCheckSlide = False
On Error Resume Next

nn = ActiveWindow.Selection.SlideRange.SlideIndex
Set mySlide = ActivePresentation.Slides(nn)
With ActivePresentation.Slides(nn).NotesPage.Shapes
For Each myShape In mySlide.NotesPage.Shapes
If myShape.PlaceholderFormat.Type = ppPlaceholderBody Then
myShape.Name = "BodyPlaceholder"
myCheckBody = True
ElseIf myShape.PlaceholderFormat.Type = ppPlaceholderTitle Then
myShape.Name = "SlidePlaceholder"
myCheckSlide = True
Else 'leave it alone
End If
Next myShape
If myCheckBody = False Then
.AddPlaceholder(ppPlaceholderBody).Name = "BodyPlaceholder"
End If
If myCheckSlide = False Then
.AddPlaceholder(ppPlaceholderTitle).Name = "SlidePlaceholder"
End If
End With
End Sub

  #3  
Old March 12th, 2007, 04:53 PM posted to microsoft.public.powerpoint
lisa
external usenet poster
 
Posts: 1,001
Default Why need to run macro twice?

You're right John, my dim wasn't doing what I thought it was (and of course I
couldn't tell since "variant" worked okay). I thought I was being efficient,
rather than the reverse g

Thank you so much for pointing this out to me... (I have a feeling I'm doing
a lot of stuff I don't intend to, since my approach to date for learning VBA
is to look at recorded macros and others' code, try to adapt it to what I
want to do, check out help files, and spend hours on end trying out a series
of best, but feeble, guesses... Not the most efficient way, I've heard told
;-)

Again, thanks for the guidance!


"John Wilson" wrote:

One quick thing Lisa

Dim myCheckBody, myCheckSlide As Boolean - doesn't do what I guess you
imagine it does. myCheckbody would be declared as a variant and only
myCheckslide as Boolean. It's a good idea to keep the Dim statements on their
own line to avoid this easy slip.

Dim myCheckBody As Boolean
Dim myCheckSlide As Boolean
--
Amazing PPT Hints, Tips and Tutorials-http://www.PPTAlchemy.co.uk
http://www.technologytrish.co.uk/ppttipshome.html
email john AT technologytrish.co.uk


"Lisa" wrote:

I wrote a macro to delete the slide (title) placeholder from the currently
viewed Notes page, then change the position of the body placeholder on that
page. With my first attempt at the code, I needed to run the macro twice. The
first run deleted the slide placeholder; the second run repositioned the body
placeholder.

I rewrote the code so I need to run the macro only once, but I'm still
stumped as to why I needed to run the old version twice. (I'm still pretty
much in the dark about VBA in general and VBA for ppt in particular.)

I'd really appreciate it if you could shed some light on this. (And if you
see anything silly in the code below, please feel free to call it to my
attention, even if it has nothing to do with the question at hand.)

Thanks much!

HERE'S THE CODE IN QUESTION
Dim myShape As Shape
Dim mySlide As Slide
Dim myCheckBody, myCheckSlide As Boolean
Dim nn As Integer

Sub Fmt_Notes_FullTxt_OLD()
'Deletes the slide placeholder and puts body placeholder at top of current
Notes page
'Run while appropriate Notes pg is active window
'Must run twice to get BodyPlaceholder positioned properly
Call Name_Placehldrs_CurSlide
On Error Resume Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "SlidePlaceholder" Then
myShape.Delete
ElseIf myShape.Name = "BodyPlaceholder" Then
With myShape
.Left = 40
.Top = 50
End With
Else ' leave it alone
End If
Next
End Sub

Sub Fmt_Notes_FullTxt_NEW()
'Deletes the slide placeholder and puts body placeholder at top of current
Notes pg
'Run while appropriate Notes pg is active window
'Need to run once only
Call Name_Placehldrs_CurSlide
On Error Resume Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "SlidePlaceholder" Then myShape.Delete
Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "BodyPlaceholder" Then
With myShape
.Left = 40
.Top = 50
End With
End If
Next
End Sub

Sub Name_Placehldrs_CurSlide()
'Names the body and slide (title) placeholders on each Notes pg
'Run from any view
myCheckBody = False
myCheckSlide = False
On Error Resume Next

nn = ActiveWindow.Selection.SlideRange.SlideIndex
Set mySlide = ActivePresentation.Slides(nn)
With ActivePresentation.Slides(nn).NotesPage.Shapes
For Each myShape In mySlide.NotesPage.Shapes
If myShape.PlaceholderFormat.Type = ppPlaceholderBody Then
myShape.Name = "BodyPlaceholder"
myCheckBody = True
ElseIf myShape.PlaceholderFormat.Type = ppPlaceholderTitle Then
myShape.Name = "SlidePlaceholder"
myCheckSlide = True
Else 'leave it alone
End If
Next myShape
If myCheckBody = False Then
.AddPlaceholder(ppPlaceholderBody).Name = "BodyPlaceholder"
End If
If myCheckSlide = False Then
.AddPlaceholder(ppPlaceholderTitle).Name = "SlidePlaceholder"
End If
End With
End Sub

  #4  
Old March 13th, 2007, 11:57 AM posted to microsoft.public.powerpoint
Bill Dilworth
external usenet poster
 
Posts: 1,455
Default Why need to run macro twice?

In addition to John's point on Dimming as Boolean, whenever deleting shapes,
slides, or objects it is a very good idea to work backwards.

Instead of using For Each statements, try using For X = Item.Count to 1
Step -1 style statements. The reason is clear when you stand back and look
at the problem.

Here I have two code examples to delete the 2nd slide.

-----
Example 1:
Sub WrongWay()

Dim oSld As Slide

For Each oSld In ActivePresentation.Slides
If oSld.SlideIndex = 2 Then oSld.Delete
Next

End Sub
-----
This method will delete all the slides from 2 thru the end of the
presentation because as slide 2 gets deleted, the next slide (3) becomes
slide 2 and gets deleted also. This isn't intuitive on first glance and can
be a bit disastrous.

-----
Example 2:
Sub RightWay()

Dim oSld As Slide, x As Integer

With ActivePresentation
For x = .Slides.Count To 1 Step -1
Set oSld = .Slides(x)
If oSld.SlideIndex = 2 Then oSld.Delete
Next x
End With

End Sub
-----

This time, the deletion of slide 2 does not shift the slides you are looking
at next, only the ones you have already checked. It is a little more code,
but not that complicated.

The same principles apply to shapes within a slide or within any collection
of objects.


Soooooo.... after that long introduction, I would suspect that the deletion
of the first placeholder, shifted the objects so that the next one was not
found, therefore the double run requirement. Of course this is just my
quick guess.



--
Bill Dilworth
A proud member of the Microsoft PPT MVP Team
Users helping fellow users.
http://billdilworth.mvps.org
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
vestprog2@ Please read the PowerPoint FAQ pages.
yahoo. They answer most of our questions.
com www.pptfaq.com
..


"John Wilson" john AT technologytrish.co DOT uk wrote in message
...
One quick thing Lisa

Dim myCheckBody, myCheckSlide As Boolean - doesn't do what I guess you
imagine it does. myCheckbody would be declared as a variant and only
myCheckslide as Boolean. It's a good idea to keep the Dim statements on
their
own line to avoid this easy slip.

Dim myCheckBody As Boolean
Dim myCheckSlide As Boolean
--
Amazing PPT Hints, Tips and Tutorials-http://www.PPTAlchemy.co.uk
http://www.technologytrish.co.uk/ppttipshome.html
email john AT technologytrish.co.uk


"Lisa" wrote:

I wrote a macro to delete the slide (title) placeholder from the
currently
viewed Notes page, then change the position of the body placeholder on
that
page. With my first attempt at the code, I needed to run the macro twice.
The
first run deleted the slide placeholder; the second run repositioned the
body
placeholder.

I rewrote the code so I need to run the macro only once, but I'm still
stumped as to why I needed to run the old version twice. (I'm still
pretty
much in the dark about VBA in general and VBA for ppt in particular.)

I'd really appreciate it if you could shed some light on this. (And if
you
see anything silly in the code below, please feel free to call it to my
attention, even if it has nothing to do with the question at hand.)

Thanks much!

HERE'S THE CODE IN QUESTION
Dim myShape As Shape
Dim mySlide As Slide
Dim myCheckBody, myCheckSlide As Boolean
Dim nn As Integer

Sub Fmt_Notes_FullTxt_OLD()
'Deletes the slide placeholder and puts body placeholder at top of
current
Notes page
'Run while appropriate Notes pg is active window
'Must run twice to get BodyPlaceholder positioned properly
Call Name_Placehldrs_CurSlide
On Error Resume Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "SlidePlaceholder" Then
myShape.Delete
ElseIf myShape.Name = "BodyPlaceholder" Then
With myShape
.Left = 40
.Top = 50
End With
Else ' leave it alone
End If
Next
End Sub

Sub Fmt_Notes_FullTxt_NEW()
'Deletes the slide placeholder and puts body placeholder at top of
current
Notes pg
'Run while appropriate Notes pg is active window
'Need to run once only
Call Name_Placehldrs_CurSlide
On Error Resume Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "SlidePlaceholder" Then myShape.Delete
Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "BodyPlaceholder" Then
With myShape
.Left = 40
.Top = 50
End With
End If
Next
End Sub

Sub Name_Placehldrs_CurSlide()
'Names the body and slide (title) placeholders on each Notes pg
'Run from any view
myCheckBody = False
myCheckSlide = False
On Error Resume Next

nn = ActiveWindow.Selection.SlideRange.SlideIndex
Set mySlide = ActivePresentation.Slides(nn)
With ActivePresentation.Slides(nn).NotesPage.Shapes
For Each myShape In mySlide.NotesPage.Shapes
If myShape.PlaceholderFormat.Type = ppPlaceholderBody Then
myShape.Name = "BodyPlaceholder"
myCheckBody = True
ElseIf myShape.PlaceholderFormat.Type = ppPlaceholderTitle
Then
myShape.Name = "SlidePlaceholder"
myCheckSlide = True
Else 'leave it alone
End If
Next myShape
If myCheckBody = False Then
.AddPlaceholder(ppPlaceholderBody).Name = "BodyPlaceholder"
End If
If myCheckSlide = False Then
.AddPlaceholder(ppPlaceholderTitle).Name = "SlidePlaceholder"
End If
End With
End Sub



  #5  
Old March 13th, 2007, 03:43 PM posted to microsoft.public.powerpoint
lisa
external usenet poster
 
Posts: 1,001
Default Why need to run macro twice?

Very good tip, Bill. Thank you!

I had no idea that you could "count backwards" as shown in your "RightWay"
example. I'm sure that will be very helpful as I continue trying to learn and
use VBA. (I'm definitely saving it as one of my "study and remember this"
examples.)

Don't think it's the problem in the code I'm asking about, however, since I
name the shapes on the Notes pg, then refer to the shapes by name as I
manipulate them.(For example: If myShape.Name = "SlidePlaceholder" Then
myShape.Delete). And I'm pretty sure the names aren't changing as I run the
sub, since on the second run (If myShape.Name = "BodyPlaceholder" Then...)
does move the ppPlaceholderBody shape...

Anyhooo, thanks for the coding tip and the example of how to count backwards
to avoid problems. Really appreciate it.

"Bill Dilworth" wrote:

In addition to John's point on Dimming as Boolean, whenever deleting shapes,
slides, or objects it is a very good idea to work backwards.

Instead of using For Each statements, try using For X = Item.Count to 1
Step -1 style statements. The reason is clear when you stand back and look
at the problem.

Here I have two code examples to delete the 2nd slide.

-----
Example 1:
Sub WrongWay()

Dim oSld As Slide

For Each oSld In ActivePresentation.Slides
If oSld.SlideIndex = 2 Then oSld.Delete
Next

End Sub
-----
This method will delete all the slides from 2 thru the end of the
presentation because as slide 2 gets deleted, the next slide (3) becomes
slide 2 and gets deleted also. This isn't intuitive on first glance and can
be a bit disastrous.

-----
Example 2:
Sub RightWay()

Dim oSld As Slide, x As Integer

With ActivePresentation
For x = .Slides.Count To 1 Step -1
Set oSld = .Slides(x)
If oSld.SlideIndex = 2 Then oSld.Delete
Next x
End With

End Sub
-----

This time, the deletion of slide 2 does not shift the slides you are looking
at next, only the ones you have already checked. It is a little more code,
but not that complicated.

The same principles apply to shapes within a slide or within any collection
of objects.


Soooooo.... after that long introduction, I would suspect that the deletion
of the first placeholder, shifted the objects so that the next one was not
found, therefore the double run requirement. Of course this is just my
quick guess.



--
Bill Dilworth
A proud member of the Microsoft PPT MVP Team
Users helping fellow users.
http://billdilworth.mvps.org
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
vestprog2@ Please read the PowerPoint FAQ pages.
yahoo. They answer most of our questions.
com www.pptfaq.com
..


"John Wilson" john AT technologytrish.co DOT uk wrote in message
...
One quick thing Lisa

Dim myCheckBody, myCheckSlide As Boolean - doesn't do what I guess you
imagine it does. myCheckbody would be declared as a variant and only
myCheckslide as Boolean. It's a good idea to keep the Dim statements on
their
own line to avoid this easy slip.

Dim myCheckBody As Boolean
Dim myCheckSlide As Boolean
--
Amazing PPT Hints, Tips and Tutorials-http://www.PPTAlchemy.co.uk
http://www.technologytrish.co.uk/ppttipshome.html
email john AT technologytrish.co.uk


"Lisa" wrote:

I wrote a macro to delete the slide (title) placeholder from the
currently
viewed Notes page, then change the position of the body placeholder on
that
page. With my first attempt at the code, I needed to run the macro twice.
The
first run deleted the slide placeholder; the second run repositioned the
body
placeholder.

I rewrote the code so I need to run the macro only once, but I'm still
stumped as to why I needed to run the old version twice. (I'm still
pretty
much in the dark about VBA in general and VBA for ppt in particular.)

I'd really appreciate it if you could shed some light on this. (And if
you
see anything silly in the code below, please feel free to call it to my
attention, even if it has nothing to do with the question at hand.)

Thanks much!

HERE'S THE CODE IN QUESTION
Dim myShape As Shape
Dim mySlide As Slide
Dim myCheckBody, myCheckSlide As Boolean
Dim nn As Integer

Sub Fmt_Notes_FullTxt_OLD()
'Deletes the slide placeholder and puts body placeholder at top of
current
Notes page
'Run while appropriate Notes pg is active window
'Must run twice to get BodyPlaceholder positioned properly
Call Name_Placehldrs_CurSlide
On Error Resume Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "SlidePlaceholder" Then
myShape.Delete
ElseIf myShape.Name = "BodyPlaceholder" Then
With myShape
.Left = 40
.Top = 50
End With
Else ' leave it alone
End If
Next
End Sub

Sub Fmt_Notes_FullTxt_NEW()
'Deletes the slide placeholder and puts body placeholder at top of
current
Notes pg
'Run while appropriate Notes pg is active window
'Need to run once only
Call Name_Placehldrs_CurSlide
On Error Resume Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "SlidePlaceholder" Then myShape.Delete
Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "BodyPlaceholder" Then
With myShape
.Left = 40
.Top = 50
End With
End If
Next
End Sub

Sub Name_Placehldrs_CurSlide()
'Names the body and slide (title) placeholders on each Notes pg
'Run from any view
myCheckBody = False
myCheckSlide = False
On Error Resume Next

nn = ActiveWindow.Selection.SlideRange.SlideIndex
Set mySlide = ActivePresentation.Slides(nn)
With ActivePresentation.Slides(nn).NotesPage.Shapes
For Each myShape In mySlide.NotesPage.Shapes
If myShape.PlaceholderFormat.Type = ppPlaceholderBody Then
myShape.Name = "BodyPlaceholder"
myCheckBody = True
ElseIf myShape.PlaceholderFormat.Type = ppPlaceholderTitle
Then
myShape.Name = "SlidePlaceholder"
myCheckSlide = True
Else 'leave it alone
End If
Next myShape
If myCheckBody = False Then
.AddPlaceholder(ppPlaceholderBody).Name = "BodyPlaceholder"
End If
If myCheckSlide = False Then
.AddPlaceholder(ppPlaceholderTitle).Name = "SlidePlaceholder"
End If
End With
End Sub




  #6  
Old March 13th, 2007, 04:25 PM posted to microsoft.public.powerpoint
David M. Marcovitz
external usenet poster
 
Posts: 1,267
Default Why need to run macro twice?

Actually, Bill's backward trick is very likely the solution to your
problem. As you go through with For Each and delete shapes, it never
checks some of the shapes on the first pass. Bill's example was more
extreme than yours (deleting all shapes while just trying to delete one),
but the same principle applies. I believe that For Each is just a
shorthand for For i=1 to .Shapes.Count, so it is really going through
shape by shape and when you delete one, all the shapes shift down one.
For example, you delete shape 6, and on the next pass, you want to know
if you should delete shape 7. However, once shape 6 is gone, shape 7 is
now shape 6, so on the next pass, you are looking at what used to be
shape 8, and you have skipped what used to be shape 7. You never delete
the wrong shape because you test whether or not to delete a shape by
looking at the name, but you aren't even testing some of the shapes on
each pass.
--David

--
David M. Marcovitz
Microsoft PowerPoint MVP
Director of Graduate Programs in Educational Technology
Loyola College in Maryland
Author of _Powerful PowerPoint for Educators_
http://www.PowerfulPowerPoint.com/

=?Utf-8?B?TGlzYQ==?= wrote in
:

Very good tip, Bill. Thank you!

I had no idea that you could "count backwards" as shown in your
"RightWay" example. I'm sure that will be very helpful as I continue
trying to learn and use VBA. (I'm definitely saving it as one of my
"study and remember this" examples.)

Don't think it's the problem in the code I'm asking about, however,
since I name the shapes on the Notes pg, then refer to the shapes by
name as I manipulate them.(For example: If myShape.Name =
"SlidePlaceholder" Then myShape.Delete). And I'm pretty sure the names
aren't changing as I run the sub, since on the second run (If
myShape.Name = "BodyPlaceholder" Then...) does move the
ppPlaceholderBody shape...

Anyhooo, thanks for the coding tip and the example of how to count
backwards to avoid problems. Really appreciate it.

"Bill Dilworth" wrote:

In addition to John's point on Dimming as Boolean, whenever deleting
shapes, slides, or objects it is a very good idea to work backwards.

Instead of using For Each statements, try using For X = Item.Count to
1 Step -1 style statements. The reason is clear when you stand back
and look at the problem.

Here I have two code examples to delete the 2nd slide.

-----
Example 1:
Sub WrongWay()

Dim oSld As Slide

For Each oSld In ActivePresentation.Slides
If oSld.SlideIndex = 2 Then oSld.Delete
Next

End Sub
-----
This method will delete all the slides from 2 thru the end of the
presentation because as slide 2 gets deleted, the next slide (3)
becomes slide 2 and gets deleted also. This isn't intuitive on first
glance and can be a bit disastrous.

-----
Example 2:
Sub RightWay()

Dim oSld As Slide, x As Integer

With ActivePresentation
For x = .Slides.Count To 1 Step -1
Set oSld = .Slides(x)
If oSld.SlideIndex = 2 Then oSld.Delete
Next x
End With

End Sub
-----

This time, the deletion of slide 2 does not shift the slides you are
looking at next, only the ones you have already checked. It is a
little more code, but not that complicated.

The same principles apply to shapes within a slide or within any
collection of objects.


Soooooo.... after that long introduction, I would suspect that the
deletion of the first placeholder, shifted the objects so that the
next one was not found, therefore the double run requirement. Of
course this is just my quick guess.



--
Bill Dilworth
A proud member of the Microsoft PPT MVP Team
Users helping fellow users.
http://billdilworth.mvps.org
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
vestprog2@ Please read the PowerPoint FAQ pages.
yahoo. They answer most of our questions.
com www.pptfaq.com
..


"John Wilson" john AT technologytrish.co DOT uk wrote in message
...
One quick thing Lisa

Dim myCheckBody, myCheckSlide As Boolean - doesn't do what I guess
you imagine it does. myCheckbody would be declared as a variant and
only myCheckslide as Boolean. It's a good idea to keep the Dim
statements on their
own line to avoid this easy slip.

Dim myCheckBody As Boolean
Dim myCheckSlide As Boolean
--
Amazing PPT Hints, Tips and Tutorials-http://www.PPTAlchemy.co.uk
http://www.technologytrish.co.uk/ppttipshome.html
email john AT technologytrish.co.uk


"Lisa" wrote:

I wrote a macro to delete the slide (title) placeholder from the
currently
viewed Notes page, then change the position of the body
placeholder on that
page. With my first attempt at the code, I needed to run the macro
twice. The
first run deleted the slide placeholder; the second run
repositioned the body
placeholder.

I rewrote the code so I need to run the macro only once, but I'm
still stumped as to why I needed to run the old version twice.
(I'm still pretty
much in the dark about VBA in general and VBA for ppt in
particular.)

I'd really appreciate it if you could shed some light on this.
(And if you
see anything silly in the code below, please feel free to call it
to my attention, even if it has nothing to do with the question at
hand.)

Thanks much!

HERE'S THE CODE IN QUESTION
Dim myShape As Shape
Dim mySlide As Slide
Dim myCheckBody, myCheckSlide As Boolean
Dim nn As Integer

Sub Fmt_Notes_FullTxt_OLD()
'Deletes the slide placeholder and puts body placeholder at top of
current
Notes page
'Run while appropriate Notes pg is active window
'Must run twice to get BodyPlaceholder positioned properly
Call Name_Placehldrs_CurSlide
On Error Resume Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "SlidePlaceholder" Then
myShape.Delete
ElseIf myShape.Name = "BodyPlaceholder" Then
With myShape
.Left = 40
.Top = 50
End With
Else ' leave it alone
End If
Next
End Sub

Sub Fmt_Notes_FullTxt_NEW()
'Deletes the slide placeholder and puts body placeholder at top of
current
Notes pg
'Run while appropriate Notes pg is active window
'Need to run once only
Call Name_Placehldrs_CurSlide
On Error Resume Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "SlidePlaceholder" Then myShape.Delete
Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "BodyPlaceholder" Then
With myShape
.Left = 40
.Top = 50
End With
End If
Next
End Sub

Sub Name_Placehldrs_CurSlide()
'Names the body and slide (title) placeholders on each Notes pg
'Run from any view
myCheckBody = False
myCheckSlide = False
On Error Resume Next

nn = ActiveWindow.Selection.SlideRange.SlideIndex
Set mySlide = ActivePresentation.Slides(nn)
With ActivePresentation.Slides(nn).NotesPage.Shapes
For Each myShape In mySlide.NotesPage.Shapes
If myShape.PlaceholderFormat.Type = ppPlaceholderBody
Then
myShape.Name = "BodyPlaceholder"
myCheckBody = True
ElseIf myShape.PlaceholderFormat.Type =
ppPlaceholderTitle
Then
myShape.Name = "SlidePlaceholder"
myCheckSlide = True
Else 'leave it alone
End If
Next myShape
If myCheckBody = False Then
.AddPlaceholder(ppPlaceholderBody).Name =
"BodyPlaceholder"
End If
If myCheckSlide = False Then
.AddPlaceholder(ppPlaceholderTitle).Name =
"SlidePlaceholder"
End If
End With
End Sub






  #7  
Old March 13th, 2007, 10:09 PM posted to microsoft.public.powerpoint
lisa
external usenet poster
 
Posts: 1,001
Default Why need to run macro twice?

Right you are, David. I didn't realize Bill's solution applied to my
situation, as the example id'd slides by number, and I was id'ing shapes by
name. I hadn't an inkling that "For each shape" translates to "For i=1 to
..Shapes.Count".

Live and - with the patience and kindess of folks in this forum - learn.

FWIW, the revised code, which incorporates feedback from John, Bill, and
David, is below. Thanks so much, all of you!

Dim myShape As Shape
Dim mySlide As Slide
Dim myCheckBody As Boolean
DimmyCheckSlide As Boolean
Dim nn As Integer

Sub Fmt_Notes_NEW2()

Call Name_Placehldrs_CurSlide

With ActiveWindow.Selection.SlideRange
For nn = .Shapes.Count To 1 Step -1
Set myShape = .Shapes(nn)
If myShape.name = "SlidePlaceholder" Then
myShape.Delete
ElseIf myShape.name = "BodyPlaceholder" Then
With myShape
.Left = 40
.Top = 50
End With
Else ' leave it alone
End If
Next
End With
End Sub


"David M. Marcovitz" wrote:

Actually, Bill's backward trick is very likely the solution to your
problem. As you go through with For Each and delete shapes, it never
checks some of the shapes on the first pass. Bill's example was more
extreme than yours (deleting all shapes while just trying to delete one),
but the same principle applies. I believe that For Each is just a
shorthand for For i=1 to .Shapes.Count, so it is really going through
shape by shape and when you delete one, all the shapes shift down one.
For example, you delete shape 6, and on the next pass, you want to know
if you should delete shape 7. However, once shape 6 is gone, shape 7 is
now shape 6, so on the next pass, you are looking at what used to be
shape 8, and you have skipped what used to be shape 7. You never delete
the wrong shape because you test whether or not to delete a shape by
looking at the name, but you aren't even testing some of the shapes on
each pass.
--David

--
David M. Marcovitz
Microsoft PowerPoint MVP
Director of Graduate Programs in Educational Technology
Loyola College in Maryland
Author of _Powerful PowerPoint for Educators_
http://www.PowerfulPowerPoint.com/

=?Utf-8?B?TGlzYQ==?= wrote in
:

Very good tip, Bill. Thank you!

I had no idea that you could "count backwards" as shown in your
"RightWay" example. I'm sure that will be very helpful as I continue
trying to learn and use VBA. (I'm definitely saving it as one of my
"study and remember this" examples.)

Don't think it's the problem in the code I'm asking about, however,
since I name the shapes on the Notes pg, then refer to the shapes by
name as I manipulate them.(For example: If myShape.Name =
"SlidePlaceholder" Then myShape.Delete). And I'm pretty sure the names
aren't changing as I run the sub, since on the second run (If
myShape.Name = "BodyPlaceholder" Then...) does move the
ppPlaceholderBody shape...

Anyhooo, thanks for the coding tip and the example of how to count
backwards to avoid problems. Really appreciate it.

"Bill Dilworth" wrote:

In addition to John's point on Dimming as Boolean, whenever deleting
shapes, slides, or objects it is a very good idea to work backwards.

Instead of using For Each statements, try using For X = Item.Count to
1 Step -1 style statements. The reason is clear when you stand back
and look at the problem.

Here I have two code examples to delete the 2nd slide.

-----
Example 1:
Sub WrongWay()

Dim oSld As Slide

For Each oSld In ActivePresentation.Slides
If oSld.SlideIndex = 2 Then oSld.Delete
Next

End Sub
-----
This method will delete all the slides from 2 thru the end of the
presentation because as slide 2 gets deleted, the next slide (3)
becomes slide 2 and gets deleted also. This isn't intuitive on first
glance and can be a bit disastrous.

-----
Example 2:
Sub RightWay()

Dim oSld As Slide, x As Integer

With ActivePresentation
For x = .Slides.Count To 1 Step -1
Set oSld = .Slides(x)
If oSld.SlideIndex = 2 Then oSld.Delete
Next x
End With

End Sub
-----

This time, the deletion of slide 2 does not shift the slides you are
looking at next, only the ones you have already checked. It is a
little more code, but not that complicated.

The same principles apply to shapes within a slide or within any
collection of objects.


Soooooo.... after that long introduction, I would suspect that the
deletion of the first placeholder, shifted the objects so that the
next one was not found, therefore the double run requirement. Of
course this is just my quick guess.



--
Bill Dilworth
A proud member of the Microsoft PPT MVP Team
Users helping fellow users.
http://billdilworth.mvps.org
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
vestprog2@ Please read the PowerPoint FAQ pages.
yahoo. They answer most of our questions.
com www.pptfaq.com
..


"John Wilson" john AT technologytrish.co DOT uk wrote in message
...
One quick thing Lisa

Dim myCheckBody, myCheckSlide As Boolean - doesn't do what I guess
you imagine it does. myCheckbody would be declared as a variant and
only myCheckslide as Boolean. It's a good idea to keep the Dim
statements on their
own line to avoid this easy slip.

Dim myCheckBody As Boolean
Dim myCheckSlide As Boolean
--
Amazing PPT Hints, Tips and Tutorials-http://www.PPTAlchemy.co.uk
http://www.technologytrish.co.uk/ppttipshome.html
email john AT technologytrish.co.uk


"Lisa" wrote:

I wrote a macro to delete the slide (title) placeholder from the
currently
viewed Notes page, then change the position of the body
placeholder on that
page. With my first attempt at the code, I needed to run the macro
twice. The
first run deleted the slide placeholder; the second run
repositioned the body
placeholder.

I rewrote the code so I need to run the macro only once, but I'm
still stumped as to why I needed to run the old version twice.
(I'm still pretty
much in the dark about VBA in general and VBA for ppt in
particular.)

I'd really appreciate it if you could shed some light on this.
(And if you
see anything silly in the code below, please feel free to call it
to my attention, even if it has nothing to do with the question at
hand.)

Thanks much!

HERE'S THE CODE IN QUESTION
Dim myShape As Shape
Dim mySlide As Slide
Dim myCheckBody, myCheckSlide As Boolean
Dim nn As Integer

Sub Fmt_Notes_FullTxt_OLD()
'Deletes the slide placeholder and puts body placeholder at top of
current
Notes page
'Run while appropriate Notes pg is active window
'Must run twice to get BodyPlaceholder positioned properly
Call Name_Placehldrs_CurSlide
On Error Resume Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "SlidePlaceholder" Then
myShape.Delete
ElseIf myShape.Name = "BodyPlaceholder" Then
With myShape
.Left = 40
.Top = 50
End With
Else ' leave it alone
End If
Next
End Sub

Sub Fmt_Notes_FullTxt_NEW()
'Deletes the slide placeholder and puts body placeholder at top of
current
Notes pg
'Run while appropriate Notes pg is active window
'Need to run once only
Call Name_Placehldrs_CurSlide
On Error Resume Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "SlidePlaceholder" Then myShape.Delete
Next
For Each myShape In ActiveWindow.Selection.SlideRange.Shapes
If myShape.Name = "BodyPlaceholder" Then
With myShape
.Left = 40
.Top = 50
End With
End If
Next
End Sub

Sub Name_Placehldrs_CurSlide()
'Names the body and slide (title) placeholders on each Notes pg
'Run from any view
myCheckBody = False
myCheckSlide = False
On Error Resume Next

nn = ActiveWindow.Selection.SlideRange.SlideIndex
Set mySlide = ActivePresentation.Slides(nn)
With ActivePresentation.Slides(nn).NotesPage.Shapes
For Each myShape In mySlide.NotesPage.Shapes
If myShape.PlaceholderFormat.Type = ppPlaceholderBody
Then
myShape.Name = "BodyPlaceholder"
myCheckBody = True
ElseIf myShape.PlaceholderFormat.Type =
ppPlaceholderTitle
Then
myShape.Name = "SlidePlaceholder"
myCheckSlide = True
Else 'leave it alone
End If
Next myShape
If myCheckBody = False Then
.AddPlaceholder(ppPlaceholderBody).Name =
"BodyPlaceholder"
End If
If myCheckSlide = False Then
.AddPlaceholder(ppPlaceholderTitle).Name =
"SlidePlaceholder"
End If
End With
End Sub







 




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Forum Jump


All times are GMT +1. The time now is 09:09 PM.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Copyright ©2004-2024 OfficeFrustration.
The comments are property of their posters.