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. |
|
|
Thread Tools | Display Modes |
#1
|
|||
|
|||
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
|
|||
|
|||
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
|
|||
|
|||
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
|
|||
|
|||
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
|
|||
|
|||
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
|
|||
|
|||
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
|
|||
|
|||
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 | |
|
|