Loop

E

Elaine J.

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.
 
E

Elaine J.

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,
 
E

Elaine J.

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
 
G

Greg Maxey

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.
 
E

Elaine J.

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
 
G

Greg Maxey

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
 
E

Elaine J.

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
 
G

Greg Maxey

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
 
G

Greg Maxey

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.
 
G

Greg Maxey

I think your initial troubles were that you never reset the boolean values
electronic, expert, rep, or concurrent.
 

Ask a Question

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

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

Ask a Question

Top