Re: How can I to repeat an action until the end of document in a macro
From: John McGhie [MVP - Word] (john_at_mcghie.name)
Date: 03/29/04
- Next message: John McGhie [MVP - Word]: "Re: Normal view displays incorrectly"
- Previous message: John McGhie [MVP - Word]: "Re: Style sheets and Column Breaks"
- In reply to: Olívio Pires: "How can I to repeat an action until the end of document in a macro"
- Messages sorted by: [ date ] [ thread ]
Date: Mon, 29 Mar 2004 19:05:15 +1000
Olivio:
OK, you cannot do this from a recorded macro. You need an "IF" statement.
1) Record your macro to do one set of the things you want.
2) Surround what you have just recorded with an IF statement.
Actually, I am going to use a 'For ... Next' statement and a 'While ...
End...' statement. Technically, these ARE 'IF' statements, but they are a
shortcut method provided in VBA where the compiler builds a pre-defined loop
for you automatically with all its control variables in place: it saves you
some code and a lot of thought. I am not sure I can even remember how to
code this up using raw "IF" statements any more!
There are two forms, depending on whether you are using the Selection or the
Find object to move through the document.
The easiest is a For... Each ... Next loop.
Sub Test()
'
' Test Macro
' Macro created 23/5/03 by John McGhie
'
For Each aPara In ActiveDocument.Paragraphs
aPara.Indent
Next aPara
End Sub
What happens here is that Word assigns a variable aPara to be "The number of
the current paragraph in the document". The Next aPara statement simply
increments this number by one on each travel through the loop until it has
done the last item in the document. It then does not try to do any more.
The above way is far, FAR easier than the next way, which you should use
only if you MUST use the Find method to find your object.
Sub Macro1()
'
' Macro1 Macro
' Macro recorded 29/3/04 by John McGhie
'
Dim IsFound As Boolean
IsFound = True
Selection.Find.ClearFormatting
With Selection.Find
.Text = "Word"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
While IsFound
Selection.Font.Bold = True
IsFound = Selection.Find.Execute
Wend
End Sub
This is a macro produced exactly the way I told you: I first recorded the
Find for the word "Word", then turned it bold. Then I wrapped the Find in a
Do ... While... Statement.
Notice that the first thing I did was to declare a Boolean variable
'IsFound' and then set it to True in the next line.
Now look down the code for the line ' While IsFound'... Anything that is
encased in the While ... Wend statement will happen ONLY if 'IsFound' has
the value 'True'. So on our first run through the code, we need to
explicitly set IsFound to True, otherwise our macro will simply exit without
doing anything.
The first statement inside the While statement is ' Selection.Font.Bold =
True'. This turns whatever was selected Bold.
That is bad programming, for which the purists will come looking for me.
It's a long swim to Sydney so I am fairly safe... The reason it is bad
programming is that the selection will ALWAYS be turned to True on the first
iteration, whether anything was found or not. But it's a lot easier: I will
show you how to get out of this in a minute...
The next statement is ' IsFound = Selection.Find.Execute'. This relies on
the fact that the 'Execute' method of the 'Find' object returns a result.
In this case, it returns 'True" if the Find found what it was looking for,
and False in all other circumstances.
The Next statement is the 'Wend' which stands for "While End". It simply
sends the program counter back to the start of the While loop. What happens
next is fascinating: Word tests the variable 'IsFound' to see if we found
anything in our most recent Find attempt. If we did, it loops through
again. If we did not, it simply calls through and out the bottom of the
macro without attempting anything else.
Now, while the purists are putting on their swimming trunks, let's handle
their pathetic objection! Recode the macro this way:
Sub Macro1()
'
' Macro1 Macro
' Macro recorded 29/3/04 by John McGhie
'
Dim IsFound As Boolean
Selection.Find.ClearFormatting
With Selection.Find
.Text = "Word"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
IsFound = Selection.Find.Execute
While IsFound
Selection.Font.Bold = False
IsFound = Selection.Find.Execute
Wend
End Sub
In this case, we do not set the variable true, we run the Find one time and
look to see if it was true!
This has its drawbacks: it relies on the fact that the Find parameters will
not be altered during the run of the macro (quite safe) but when you do it
with things other than the Find object, that's an unsafe assumption.
Keep these two samples around: you will use them over and over and over
again!
You will also notice that I trimmed out a whole lot of junk that the Macro
Recorder recorded. That's a habit, because I knew that I would not need it.
If you are on a decent machine, processing a document of less than 500
pages, don't even bother. You won't make your macro run noticeably faster,
and in the time it takes you to figure out what code you can throw out, you
will have long completed the task at hand. I coded a macro the other day
that took 66 hours to process all of the documents on a file server. I
guess I should have made that one more efficient, but hell, I just let it
run over the weekend. Machines and electricity are cheap: people and
thinking time are not :-)
There is a third way of accomplishing what you want, using the Range
objects. I won't even bother producing an example: it's very complex, and
it's technically difficult to produce a condition where you can be sure that
a Range test will come true under all circumstances when you get to the end
of the document!
Cheers
This responds to article <BC8A5999.DE5%ompires@knuut.de>, from "Olívio
Pires" <ompires@knuut.de> on 27/3/04 7:05 AM:
> Sometimes , when using a long document in Word X, I need to record a macro
> and repeat the action until the end of document, I have some trouble In
> knowing when I reach the end of document in order to stop?
>
> Thanks!
>
> OP
>
-- Please respond only to the newsgroup to preserve the thread. John McGhie, Consultant Technical Writer, McGhie Information Engineering Pty Ltd Sydney, Australia. GMT + 10 Hrs +61 4 1209 1410, mailto:john@mcghie.name
- Next message: John McGhie [MVP - Word]: "Re: Normal view displays incorrectly"
- Previous message: John McGhie [MVP - Word]: "Re: Style sheets and Column Breaks"
- In reply to: Olívio Pires: "How can I to repeat an action until the end of document in a macro"
- Messages sorted by: [ date ] [ thread ]