MS Office Forum / Word / Programming / September 2007
Loop
|
|
Thread rating:  |
Elaine J. - 14 Sep 2007 03:32 GMT I have a macro that I have been working on. It works exactly as I want to as long as I run it once.
Basically I have a document that contains many notices. Each notice is 3 to 5 sections long based on criteria that I can identify. The macro correctly identifies the number of sections for each notice, prints it and deletes it so that the second notice is now the first.
I can start the macro and print the first notice. Then start the macro again and print the second notice and so on until it reaches the end. So I know the macro is working. The problem is, I want to be able to run the macro with no user interaction. So a simple loop should work. But no matter how I try to make it loop, it does not run properly. (It prints part of them correctly, and part of them not correctly)
I have tried:
Start: (at the beginning of the macro) goto Start:
Doesn't work
I have tried
do while selection.find.execute ("refer to:") = true macro Loop
Doesn't work
I have tried
Do Macro Loop
Doesn't work
I have tried
do until selection.find.execute ("refer to:") = false macro loop
That doesn't work.
I have stepped through the macro repeatedly. Everytime I step through it, it works perfectly. Then I can add a loop to it and it does not work correctly.
Elaine J. - 14 Sep 2007 03:44 GMT Sorry, I was going to do some editing and somehow clicked something to make this post before I was done.
My question was going to be: what would make a macro work properly once, but not when it is looped?
Thanks,
> I have a macro that I have been working on. It works exactly as I want to as > long as I run it once. [quoted text clipped - 45 lines] > it works perfectly. Then I can add a loop to it and it does not work > correctly. Greg Maxey - 14 Sep 2007 04:00 GMT Without seeing your complete code it is impossible for me to even guess.
 Signature Greg Maxey/Word MVP See: http://gregmaxey.mvps.org/word_tips.htm For some helpful tips using Word.
> Sorry, I was going to do some editing and somehow clicked something to > make [quoted text clipped - 62 lines] >> it works perfectly. Then I can add a loop to it and it does not work >> correctly. Elaine J. - 14 Sep 2007 17:30 GMT Sorry, Greg, It's a little long, but hopefully you can tell what is going on. I do document mine with plenty of notes. Basically this is what is happening: We use a document generation program in Word that create a single document that contains notices that we sent to customers. Each notice is 3 to 5 sections long. First I have to determine whether the notice is 3, 4, or 5 sections based on information that is unique to each section. After I determine how many sections a notice is, it is printed. Then the macro calls another macro that prints some forms. Then the notice is deleted. It then goes through the same steps with the second notice (that is now the first notice).
The problem that I am having, is the macro works -- once (i.e. I can run it for the first notice, then run it again for the second notice and keep clicking run until I am done. It also works if I step through it. But if I try to add any kind of loop to it, it kind of scrambles the notices. I have wondered if it is going too fast (is that possible?). I wondered if maybe I need to somehow pause it between each notice?
If you need the macro that is called, I can send that too.
Thanks for any help you can give me.
Sub altNewPrintNOH()
'Print the Notice of Hearing. 'Requires the forms "hrformsrep.doc and hrformsnorep to be in the user's K:\ 'Updated 9/10/07 to accomodate EF procedures.
Application.ScreenUpdating = true
Dim notice As Range Dim printnotice As Range
Dim notice3 As Range Dim printnotice3 As Range
Dim notice4 As Range Dim printnotice4 As Range
Dim notice5 As Range Dim printnotice5 As Range
Dim acknotice As Range Dim blankpage As Range
Dim electronic As Boolean Dim rep As Boolean Dim expert As Boolean Dim concurrent As Boolean
Selection.EndKey Unit:=wdStory
Selection.InsertBreak Type:=wdSectionBreakNextPage Selection.InsertBreak Type:=wdSectionBreakNextPage Selection.InsertBreak Type:=wdSectionBreakNextPage
Selection.HomeKey Unit:=wdStory With Selection.Find .ClearFormatting .Text = "Refer to:" .Forward = True .Wrap = wdFindStop End With If Selection.Find.Execute = False Then End End If 'this checks for occasional blank pages left behind.
Set blankpage = ActiveDocument.Range(start:=ActiveDocument.Sections(1).Range.start, End:=ActiveDocument.Sections(1).Range.End)
With blankpage.Find .ClearFormatting .Text = "Refer To:" .Forward = True .Wrap = wdFindStop End With
If blankpage.Find.Execute = False Then Set blankpage = ActiveDocument.Range(start:=ActiveDocument.Sections(1).Range.start, End:=ActiveDocument.Sections(1).Range.End) blankpage.Delete
End If
Selection.HomeKey Unit:=wdStory
'*************VARIABLES*************** 'Check for Electronic
Set notice5 = ActiveDocument.Range(start:=ActiveDocument.Sections(1).Range.start, End:=ActiveDocument.Sections(5).Range.End)
With notice5.Find .ClearFormatting .Text = "Electronic" .Forward = True .Wrap = wdFindStop End With
'Electronic If If notice5.Find.Execute("Electronic") = True Then electronic = True End If 'Check for Rep Set notice = ActiveDocument.Range(start:=ActiveDocument.Sections(1).Range.start, End:=ActiveDocument.Sections(1).Range.End) With notice.Find .ClearFormatting .Text = "cc:" .Replacement.Text = "" .Forward = True .Wrap = wdFindStop End With ' Rep IF
If notice.Find.Execute("cc:") = True Then rep = True End If 'Check for Expert Set notice4 = ActiveDocument.Range(start:=ActiveDocument.Sections(4).Range.start, End:=ActiveDocument.Sections(4).Range.End) With notice4.Find .ClearFormatting .Text = "in accordance with your contract" .Replacement.Text = "" .Forward = True .Wrap = wdFindStop End With
'Expert if
If notice4.Find.Execute = True Then expert = True End If 'Check for concurrent
Set notice = ActiveDocument.Range(start:=ActiveDocument.Sections(1).Range.start, End:=ActiveDocument.Sections(1).Range.End)
With notice.Find .ClearFormatting .Text = "The hearing also concerns" .Replacement.Text = "" .Forward = True .Wrap = wdFindStop End With 'Concurrent If
If notice.Find.Execute("The hearing also concerns") = True Then concurrent = True End If '************THIS STARTS THE PRINT PORTION OF THE MACRO********
Set notice = ActiveDocument.Range(start:=ActiveDocument.Sections(1).Range.start, End:=ActiveDocument.Sections(2).Range.End) Set printnotice = ActiveDocument.Range(start:=ActiveDocument.Sections(1).Range.start, End:=ActiveDocument.Sections(2).Range.End - 1) Set notice3 = ActiveDocument.Range(start:=ActiveDocument.Sections(1).Range.start, End:=ActiveDocument.Sections(3).Range.End) Set printnotice3 = ActiveDocument.Range(start:=ActiveDocument.Sections(1).Range.start, End:=ActiveDocument.Sections(3).Range.End - 1) Set notice4 = ActiveDocument.Range(start:=ActiveDocument.Sections(1).Range.start, End:=ActiveDocument.Sections(4).Range.End) Set printnotice4 = ActiveDocument.Range(start:=ActiveDocument.Sections(1).Range.start, End:=ActiveDocument.Sections(4).Range.End - 1) Set notice5 = ActiveDocument.Range(start:=ActiveDocument.Sections(1).Range.start, End:=ActiveDocument.Sections(5).Range.End) Set printnotice5 = ActiveDocument.Range(start:=ActiveDocument.Sections(1).Range.start, End:=ActiveDocument.Sections(5).Range.End - 1) Set acknotice = ActiveDocument.Range(start:=ActiveDocument.Sections(3).Range.start, End:=ActiveDocument.Sections(3).Range.End)
'******ELECTRONIC CASES**********
'Electronic Cases with rep and expert (5 sections)
If electronic = True Then If rep = True Then If expert = True Then
'print the notice printnotice5.Select ActiveDocument.PrintOut Range:=wdPrintSelection, Copies:=1, PageType:=wdPrintAllPages, Collate:=True, Background:=False, PrintToFile:=False 'print the forms
Call PrintHRFormsRep
'delete the notice notice5.Delete End If End If End If
'Electronic with rep but no Expert (4 sections) If electronic = True Then If rep = True Then If expert = False Then 'Print the notice
printnotice4.Select ActiveDocument.PrintOut Range:=wdPrintSelection, Copies:=1, PageType:=wdPrintAllPages, Collate:=True, Background:=False, PrintToFile:=False ' print the forms Call PrintHRFormsRep 'delete the notice
notice4.Delete End If End If End If
'Electronic with no rep with an expert (5 sections)
If electronic = True Then If rep = False Then If expert = True Then ' Just print the forms
Call PrintHRFormsNoRep 'delete the notice notice5.Delete End If End If End If
'Electronic with no rep AND NO expert (4 sections)
If electronic = True Then If rep = False Then If expert = False Then 'Just print the forms Call PrintHRFormsNoRep 'Delete the notice notice4.Delete End If End If End If '**********PAPER CASES*************** 'Paper case with rep and expert (4 sections)
If electronic = False Then If rep = True Then If expert = True Then 'Print 1 copy for rep printnotice4.Select ActiveDocument.PrintOut Range:=wdPrintSelection, Copies:=1, PageType:=wdPrintAllPages, Collate:=True, Background:=False, PrintToFile:=False 'Concurrent = print 2 copies for the file If concurrent = True Then 'delete the acknowledgement notice With acknotice .Select .Delete End With 'print the notice printnotice4.Select ActiveDocument.PrintOut Range:=wdPrintSelection, Copies:=2, PageType:=wdPrintAllPages, Collate:=True, Background:=False, PrintToFile:=False End If 'Not concurrent = print 1 copy for the file If concurrent = False Then 'delete the acknowledgement notice With acknotice .Select .Delete End With 'print the notice printnotice4.Select ActiveDocument.PrintOut Range:=wdPrintSelection, Copies:=1, PageType:=wdPrintAllPages, Collate:=True, Background:=False, PrintToFile:=False End If ' CONCURRENT If 'print the forms Call PrintHRFormsRep 'Delete the notice notice4.Delete End If End If End If
'Paper case with rep and no expert (3 sections)
If electronic = False Then If rep = True Then If expert = False Then 'Print 1 copy for rep printnotice3.Select ActiveDocument.PrintOut Range:=wdPrintSelection, Copies:=1, PageType:=wdPrintAllPages, Collate:=True, Background:=False, PrintToFile:=False 'Concurrent = print 2 copies (first delete the acknowledgement notice) ' If concurrent = True Then With acknotice .Select .Delete End With printnotice3.Select ActiveDocument.PrintOut Range:=wdPrintSelection, Copies:=2, PageType:=wdPrintAllPages, Collate:=True, Background:=False, PrintToFile:=False End If 'Not concurrent = print 1 copy (first delete the acknowldgement notice)
If concurrent = False Then With acknotice .Select .Delete End With printnotice3.Select ActiveDocument.PrintOut Range:=wdPrintSelection, Copies:=1, PageType:=wdPrintAllPages, Collate:=True, Background:=False, PrintToFile:=False End If ' concurrent 'print the forms
Call PrintHRFormsRep 'Delete the notice notice3.Delete End If End If End If
'Paper case with no rep and an expert (4 sections)
If electronic = False Then If rep = False Then If expert = True Then If concurrent = True Then 'Print 2 copies for the file (first delete the acknowledgment notice)
With acknotice .Select .Delete End With printnotice4.Select ActiveDocument.PrintOut Range:=wdPrintSelection, Copies:=2, PageType:=wdPrintAllPages, Collate:=True, Background:=False, PrintToFile:=False End If 'Print 1 copy for the file
If concurrent = False Then With acknotice .Select .Delete End With printnotice4.Select ActiveDocument.PrintOut Range:=wdPrintSelection, Copies:=1, PageType:=wdPrintAllPages, Collate:=True, Background:=False, PrintToFile:=False End If 'print the forms Call PrintHRFormsNoRep
'Delete the notice notice4.Delete
End If End If End If
'Paper case with no rep and no expert (3 sections)
If electronic = False Then If rep = False Then If expert = False Then If concurrent = True Then 'Print 2 copies for the file (first delete the acknowledgement notice)
With acknotice .Select .Delete End With printnotice3.Select ActiveDocument.PrintOut Range:=wdPrintSelection, Copies:=2, PageType:=wdPrintAllPages, Collate:=True, Background:=False, PrintToFile:=False End If 'Print 1 copy for the file If concurrent = False Then With acknotice .Select .Delete End With printnotice3.Select ActiveDocument.PrintOut Range:=wdPrintSelection, Copies:=1, PageType:=wdPrintAllPages, Collate:=True, Background:=False, PrintToFile:=False End If 'print the forms Call PrintHRFormsNoRep 'Delete the notice notice3.Delete End If End If End If Selection.HomeKey Unit:=wdStory
'Closes the notices document ' ' With ActiveDocument ' .Saved = True ' .Close ' End With
End Sub
> Without seeing your complete code it is impossible for me to even guess. > [quoted text clipped - 64 lines] > >> it works perfectly. Then I can add a loop to it and it does not work > >> correctly. Greg Maxey - 14 Sep 2007 22:55 GMT Elaine,
No I really can't make much sense of it.
What exactly are your trying to loop? Do you want to add 3 new sections to the document with each loop? How many sections does the document have to begin with?
Just a stab,
If "Refer to:" is the key identifier of many notices then putting most of your code in a
While .Execute
Wend
Statement, may be the place to start.
 Signature Greg Maxey/Word MVP See: http://gregmaxey.mvps.org/word_tips.htm For some helpful tips using Word.
> Sorry, Greg, It's a little long, but hopefully you can tell what is going > on. [quoted text clipped - 607 lines] >> >> it works perfectly. Then I can add a loop to it and it does not work >> >> correctly. Elaine J. - 15 Sep 2007 05:22 GMT Greg, yes the "refer to" statement is where I want the loop to start. (the section breaks at the very beginning only need to be added once. The document as created does not have a section break at the end. When I first wrote the macro, it kept giving me an error at the end because it could not set 5 sections. After much thought, I decided the easist solution was to manually create a section break at the end. I added three because there was the possibility that my last notice could only have three sections in it. There is probably a more professional way to do this, but it solved the problem that I was having at the time.)
The document could have many sections (10 - 30 notices with 3 to 5 sections each). The macro only evaulates the first five sections. I search for the variables that tell me what type of case I have. Then based on the variables, it decides if I need to print 3, 4 or 5 sections. It then deletes it and evaluates the next five sections (which are now the first 5 sections of the document).
So basically I want it to loop from the end back up to the "Refer to" statement. I am pretty sure I know how to write a loop and I have tried several variations (see my first post). The problem is it just doesn't work -- even though it works if I step through it (even with a loop) or if I just run it once - repeatedly.
Thanks,
Elaine
> Elaine, > [quoted text clipped - 270 lines] > > > > ' print the forms Greg Maxey - 15 Sep 2007 13:15 GMT Elaine,
Yes I sort of got the gist of it after getting past the adding three sections each time. It is also a bit tough working out the problem without having a document to work with.
You could try pausing the macro at the end of each loop like this:
Paste this line at the top of the project modle:
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Copy this procedure into the project module:
Sub Doze(ByVal lngPeriod As Long) DoEvents Sleep lngPeriod ' Call it in desired location to sleep for 1 second like this Doze 1000 End Sub
Just before the end of the loop add
Doze 1000
I still think the if all the code past the first .Execute was in a While Wend statemenet that is should work: Selection.HomeKey Unit:=wdStory
With Selection.Find .ClearFormatting .Text = "Refer to:" .Forward = True .Wrap = wdFindStop While .Execute 'Do the deeds 'Code to reset the search range to the entire document Wend End With
 Signature Greg Maxey/Word MVP See: http://gregmaxey.mvps.org/word_tips.htm For some helpful tips using Word.
> Greg, yes the "refer to" statement is where I want the loop to start. > (the section breaks at the very beginning only need to be added once. [quoted text clipped - 304 lines] >>> >>> ' print the forms Elaine J. - 15 Sep 2007 14:44 GMT Greg, thank you so much for your help. I will try your two suggestions on Monday. Can I ask one more question? In looking at this macro (after the line that says "THIS STARTS THE PRINT PORTION OF THE MACRO" where the If statements start: Each of those are a different scenario and only of them will be true each time the macro is run. Is there a more efficient way to write that? I.e. even after it finds a true scenario, it still goes through the rest of them. If this is too many questions for the same macro, then that is OK. It doesn't stop anything from working, I'd just like it to be as clean as possible.
Thank you so much for your help.
Elaine
> Elaine, > [quoted text clipped - 271 lines] > >>> Then concurrent = True > >>> End If Greg Maxey - 15 Sep 2007 21:20 GMT Elaine,
Yes all those If statements seems clunky. You could try use Select Case statements instead. Also, when I do something repetive, I try to create and call smaller procedures to do those tasks. For example, your code is peppered with Printout Methods where all you do is print 1 or 2 copies. Instead of repeating that code in your main macro you could have a procedure to Printout and pass the number of copies to it. Here is a example:
Sub ScratchMacro() Dim A As Boolean Dim B As Boolean Dim C As Boolean Dim D As Boolean A = True B = True C = True D = True Select Case A Case True Select Case B Case True Select Case C Case True Select Case D Case True PrinttheSelection 1 Case Else PrinttheSelection 2 End Select Case Else
End Select Case Else
End Select Case Else Select Case B Case True Select Case C Case True Select Case D Case True MsgBox "Do whatever" Case Else MsgBox "Do something else" End Select Case Else
End Select Case Else
End Select
End Select
End Sub Sub PrinttheSelection(ByRef Count) ActiveDocument.PrintOut Range:=wdPrintSelection, Copies:=Count, _ PageType:=wdPrintAllPages, Collate:=True, Background:=False, _ PrintToFile:=False
End Sub
 Signature Greg Maxey/Word MVP See: http://gregmaxey.mvps.org/word_tips.htm For some helpful tips using Word.
> Greg, thank you so much for your help. I will try your two suggestions on > Monday. Can I ask one more question? In looking at this macro (after the [quoted text clipped - 288 lines] >> >>> Then concurrent = True >> >>> End If Greg Maxey - 15 Sep 2007 23:19 GMT Elaine,
Use the feedback link on my website to send you e-mail addres. I will send you a document with some revisions to your code.
 Signature Greg Maxey/Word MVP See: http://gregmaxey.mvps.org/word_tips.htm For some helpful tips using Word.
> Greg, thank you so much for your help. I will try your two > suggestions on Monday. Can I ask one more question? In looking at [quoted text clipped - 293 lines] >>>>> Then concurrent = True >>>>> End If Greg Maxey - 16 Sep 2007 15:24 GMT I think your initial troubles were that you never reset the boolean values electronic, expert, rep, or concurrent.
 Signature Greg Maxey/Word MVP See: http://gregmaxey.mvps.org/word_tips.htm For some helpful tips using Word.
> I have a macro that I have been working on. It works exactly as I > want to as long as I run it once. [quoted text clipped - 46 lines] > through it, it works perfectly. Then I can add a loop to it and it > does not work correctly.
|
|
|