Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
DiscussionsAccessExcelInfoPathOutlookPowerPointPublisherWord
DirectoryUser Groups
Related Topics
Outlook ExpressInternet ExplorerWindowsMS Server ProductsMore Topics ...

MS Office Forum / Word / Programming / December 2006

Tip: Looking for answers? Try searching our database.

How do I write a loop statement to that will stop at the end of the doc?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jeff Mitteer - 11 Dec 2006 20:25 GMT
I am doing a search on a document and need to perform some actions when the
search criteria is met.  I am having a problem getting the loop to stop at
the end of the document.  It just keeps looping.  I am very new to Word VBA
and would appreciate any help.

Jeff
Jay Freedman - 11 Dec 2006 20:55 GMT
The usual construction is to start with a Range object that covers the
entire document body:

  Dim myRange As Range
  Set myRange = ActiveDocument.Range

Set the properties of the myRange.Find object (the .Text, .Replacement,
.MatchWildcards, and so forth). It's important to set myRange.Find.Wrap =
wdFindStop so the search stops at each occurrence of the target.  Then write
the loop like this:

  Do While myRange.Find.Execute
      ' do your work on myRange here
      MyRange.Collapse wdCollapseEnd
  Loop

The .Execute method returns True if it found the search target or False if
it didn't find it. That makes the loop stop when there are no more
occurrences between the current position of myRange and the end of the
document (you don't actually have to know whether you've "reached the end").

The .Collapse ensures that, if the target still exists within myRange after
you've worked on it, the next iteration won't find the same occurrence
again.

Signature

Regards,
Jay Freedman
Microsoft Word MVP        FAQ: http://word.mvps.org
Email cannot be acknowledged; please post all follow-ups to the newsgroup so
all may benefit.

> I am doing a search on a document and need to perform some actions
> when the search criteria is met.  I am having a problem getting the
> loop to stop at the end of the document.  It just keeps looping.  I
> am very new to Word VBA and would appreciate any help.
>
> Jeff
Jeff Mitteer - 12 Dec 2006 05:50 GMT
> The usual construction is to start with a Range object that covers the
> entire document body:
[quoted text clipped - 20 lines]
> you've worked on it, the next iteration won't find the same occurrence
> again.

Thanks.  I think that will work.

Jeff
Greg Maxey - 12 Dec 2006 14:16 GMT
Jay,

I have used a construction similiar to yours many times.  That is one
reason I mentioned that the OP should provide his code.

In a new document I type the words "Your text"

and run this code:

Sub Scratchmacro()
Dim oRng As Word.Range
Set oRng = ActiveDocument.Range
With oRng.Find
 .Text = "Your text"
 .Wrap = wdFindStop
 While .Execute
   oRng.Font.Color = wdColorBlue
 Wend
End With
End Sub

In this simple test, it appears that .Wrap = wdFindStop is sufficient
to avoid that dreadful loop that often requires:

oRng.Collapse wdCollapseEnd  ;-)

> The usual construction is to start with a Range object that covers the
> entire document body:
[quoted text clipped - 34 lines]
> >
> > Jeff
Jay Freedman - 12 Dec 2006 15:13 GMT
Hi Greg,

Of course, you're correct. I know I've been in situations where the
.Collapse was necessary, but I don't have an example handy. If I come across
one, I'll let you know what's different about it.

Signature

Regards,
Jay Freedman
Microsoft Word MVP        FAQ: http://word.mvps.org
Email cannot be acknowledged; please post all follow-ups to the newsgroup so
all may benefit.

> Jay,
>
[quoted text clipped - 61 lines]
>>>
>>> Jeff
Helmut Weber - 12 Dec 2006 18:36 GMT
Hi Jay,

IMHO,
formatting does no harm,
however, replacing text seems to require
additional measures to control the range.

Signature

Greetings from Bavaria, Germany

Helmut Weber, MVP WordVBA

Win XP, Office 2003
"red.sys" & Chr$(64) & "t-online.de"

Greg Maxey - 12 Dec 2006 20:17 GMT
Jay/Helmut,

It seems that I have been tripped up before as well with a continous
loop without the .Collapse wdCollapseEnd statement, but despite trying
for the last hour, I had to resort to some non-standard code to produce
the situation.  It will occur whenever you expand the found range
within the execute statement while leaving the find.text intact.  In
this rather poor example, I am adding quotes to underlined text within
a document.  With the .Collapse wdCollapseEnd statement a continous
loop occurs:

Sub ScratchMacro1()
'Adds quotes to underlined text
Dim oRng As Range
Set oRng = ActiveDocument.Content
With oRng.Find
 .ClearFormatting
 .Text = "<*>"
 .Font.Underline = True
 .Forward = True
 .Wrap = wdFindStop
 .MatchWildcards = True
 Do While .Execute
   With oRng
     .InsertBefore Chr(34)
     .InsertAfter Chr(34)
     .Characters.Last.Font.Underline = False
     .Collapse wdCollapseEnd
   End With
 Loop
End With
End Sub

For me a more common problem is the job won't complete without that
statement.  Take this example where I want to underline text in quotes:

Sub ScratchMacro2()
'Underlines text exclusive of the quotes marks
Dim oRng As Range
Set oRng = ActiveDocument.Content
With oRng.Find
 .ClearFormatting
 .Text = """<*>"""
 .Forward = True
 .Wrap = wdFindStop
 .MatchWildcards = True
 Do While .Execute
   With oRng
     .MoveEnd Unit:=wdCharacter, Count:=-1
     .MoveStart Unit:=wdCharacter, Count:=1
     .Font.Underline = True
     .Collapse wdCollapseEnd
   End With
 Loop
End With
End Sub

Without the collapse statement the code only formats the first found
instance.

I think I have read here somewhere before that the .execute won't find
.find.text that exactly matches the find.range.

So in a new document with Test text Test text

The following code:

Sub ScratchMacro3()
Dim oRng As Word.Range
Set oRng = ActiveDocument.Range
With oRng.Find
 .Text = "Test text"
 .Wrap = wdFindStop
 While .Execute
   oRng.Text = "Test text"
 Wend
End With
MsgBox oRn.Text
End Sub

Finds the first instances, the next .Execute collapses the range and
extends the range forward to the end of the document and finds the next
instance, at this point the oRng.Text and .Find.Text are identical and
.Execute terminates.

Here is another way of attempting to illustrate what I think happes.
You can't find the text of a document in the range of a document:

Sub ScratchMacro4()
Dim oRng As Word.Range
Set oRng = ActiveDocument.Range
With oRng.Find
 .Text = ActiveDocument.Range.Text
 .Execute
   If .Found Then
     MsgBox "Found"
   Else
     MsgBox "Not found"
   End If
End With
If oRng.Text = ActiveDocument.Range.Text Then
 MsgBox "Doesn't is seem odd that Word doesnt' find the" _
        & " ActiveDocument.Range.Text in the ActiveDocument.Range?"
End If
End Sub
Tony Jollans - 12 Dec 2006 23:28 GMT
I have just posted (in word.vba.customization) where a collapse was
necessary.

Each Find operation (each execution of the .Execute) is a stand-alone Find
and follows the same set of rules: if the range exactly satisfies the Find
criteria it is presumed to have been the result of a previous Find for the
same thing and searching starts after the range (the range is effectively
automatically collapsed); otherwise the Range is searched and if that
results in a not found condition, further searching depends on the Wrap
value.

If, after a find, you mess with the range - change its size - or its
contents or formatting - you will affect how the next iteration works. If
you have Wrap=Continue you can end up with an infinite loop in cases where
you don't change every found instance.

Signature

Enjoy,
Tony

> Jay/Helmut,
>
[quoted text clipped - 101 lines]
> End If
> End Sub
Greg Maxey - 13 Dec 2006 13:21 GMT
Tony,

Concur with your explanation in the Customization group message.  That
is why I said:

"For me a more common problem is the job won't complete without that
statement."

This is a good explanation of what happens with .Execute:

> Each Find operation (each execution of the .Execute) is a stand-alone Find
> and follows the same set of rules: if the range exactly satisfies the Find
[quoted text clipped - 3 lines]
> results in a not found condition, further searching depends on the Wrap
> value.

This might give anyone following this string a good example of how the
collapse statement ensures the code procedes when the range is reduced
and ensures it doesn't get in a continous loop if the range is expanded
in the .Execute portion of the code:

Sub Test1()
Dim oRng As Word.Range
Set oRng = ActiveDocument.Range
With oRng.Find
 .Text = "<*>"
 .MatchWildcards = True
 While .Execute
   MsgBox oRng.Text
   oRng.MoveEnd wdCharacter, -1
   oRng.MoveStart wdCharacter, 1
   MsgBox oRng.Text
   oRng.Collapse wdCollapseEnd
 Wend
End With
Set oRng = ActiveDocument.Range
With oRng.Find
 .Text = "<*>"
 .MatchWildcards = True
While .Execute
   MsgBox oRng.Text
   oRng.MoveEnd wdCharacter, 1
   oRng.MoveStart wdCharacter, -1
   oRng.Collapse wdCollapseEnd
 MsgBox oRng.Text
 Wend
End With
End Sub

> > Jay/Helmut,
> >
[quoted text clipped - 101 lines]
> > End If
> > End Sub
Greg Maxey - 11 Dec 2006 20:58 GMT
Jeff,

I helps to provide your code.

Try something like:

Sub Scratchmacro()
Dim oRng As Word.Range
Set oRng = ActiveDocument.Range
With oRng.Find
 .Text = "Your text"
 .Wrap = wdFindStop
 While .Execute
   oRng.Font.Color = wdColorBlue
 Wend
End With
End Sub

> I am doing a search on a document and need to perform some actions when the
> search criteria is met.  I am having a problem getting the loop to stop at
> the end of the document.  It just keeps looping.  I am very new to Word VBA
> and would appreciate any help.
>
> Jeff
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.