Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problem with Find and automatic range expanding

Status
Not open for further replies.

costincca

Programmer
Jan 16, 2008
5
RO
Hi,

I am trying to loop through a document to find all occurences of a text.

For example, I want to find "link". The sentence in the document is "The links are broken."

Using the code below, I find the first occurence. After that, is set myRange to be from after the occurence to the end. And it does so. Now the myRange becomes "s are broken". When looping, however, Find.Execute finds again "link", going back and expanding the range by itself, even if myRange is "s are broken" and does not contain "link" anymore.

Why instead of looking in myRange, at the second call, Find looks in the whole file again? Of course, stopping on the same occurence as before and looping and looping....

What can I do? What I did wrong?

Thanks a lot. The code is below...
Costin



Set myRange = Doc.Content

ToFind = "link"
WildCards = False
MatchCase = False
MatchWildCards = False
WholeWord = False

Found = False
Do
myRange.Find.ClearFormatting

Found = myRange.Find.Execute(FindText:=ToFind, MatchWildcards:=WildCards, MatchCase:=MatchCase, MatchWholeWord:=WholeWord, Wrap:=wdFindStop, MatchSoundsLike:=False, MatchAllWordForms:=False, Format:=False, Forward:=True)

If Found Then
'Here I fill a list with the positions where I find
myControl.AddItem myRange.Start & " - " & myRange.End & " = " & """" & myRange.Text & """"
End If

myRange.SetRange myRange.End + 1, Doc.Range.End
Loop Until Not Found
 
Hmmm. I am not quite following what you are saying, or doing. Could you explain what is happening with myControl.AddItem? What, precisely, are you trying to do? You seem, at least in your post, to be resizing the range to the end of the paragraph - if it is indeed a paragraph.

"The links are broken."

So you search for "links", then you want "s are broken."???? Why?

So, again, I am not quite following what you are actually trying to do. The myControl seems to be adding the Found range start, yet it also has the .Text...yet you say that you are moving the range to "s are broken." Where? I do not see this. Not following.

In any case, when you use the .Find method of a Range, the Range is automatically resized to the range of each .Found.

It then proceeds to the next search string.
Code:
Dim r As range
Set r = ActiveDocument.Range
  With r.Find
    Do While .Execute(FindText:="link", _
          Forward:=True) = True
      ' do whatever it is you are doing
    Loop
  End With

Now, and this is important, if you are moving the existing Range of a .Found - and of course you can - then you must collapse the Range object afterwards, in order to continue from THAT point.

So, for example, if you have the text:

The links are broken.
The links are broken really badly.
The whole links are shattered.

And you ran:
Code:
Sub GetStuff()
Dim r As Range
Dim lngStart As Long
Set r = ActiveDocument.Range
With r.Find
  Do While .Execute(FindText:="link", _
        Forward:=True) = True
    lngStart = r.Start
    With r
      .Collapse Direction:=wdCollapseEnd
      .MoveEndUntil Cset:=Chr(13)
      MsgBox lngStart & "  " & r.Text
      .Collapse wdCollapseEnd
    End With
  Loop
End With
End Sub

You would get messages:

4 s are broken.
26 s are broken really badly.
67 s are shattered.

The number is the Start of the .Found range, ie. the Long position of the "l" in "link". The text is the text from the end of that Range, to the first paragraph mark - Chr(13). So from just past "k", to the first paragraph mark.

Also, what is myControl? Are you running this from a userform?

faq219-2884

Gerry
My paintings and sculpture
 
Hi,

Thanks a lot for the answer. I am sorry for using "moving" and "resizing" words inadequately and this caused confusion.

Let me explain in more detail.

Suppose I have the sentence: "The links are blue now, yesterday the links were black.". I need to extract the start and end positions were "link" appears and write these positions in a list. Well, myControl is a list on a custom toolbar in Word. That is why when I find an occurence of "link" in the sentence, I write in myControl (using AddItem) the start and end positions of the Range found.

So, we have "The links are blue now, yesterday the links were black.". We want to find "link".

I have a Range, myRange.
Initially, the myRange contains the whole document: "The links are blue now, yesterday the links were black."
I execute a Find. Now the myRange becomes "link" (Start = 5, End = 8). I write in the myControl list: "5 - 8 - link".
I resize myRange in such way to continue searching till the end of the document: myRange.SetRange myRange.End, Doc.Word.Range
Now myRange contains: "s are blue now, yesterday the links were black.", because I exclude the first part of the text which was already processed.

I execute Find again. myRange should become "link" (Start = 39, End = 42)! However, myRange becomes again "link" (Start = 5, End = 8), like it started again from the beginning, not from where it left.

And it loops and it loops.



I tried using Collapse instead of SetRange, but it seems to be the same result. SetRange works, because, after this, the Range extends from immediately after first occurence until the end of the document, which is correct.

The error comes in Find.Execute, when the text is searched again in the whole document, positioning me on the very same first occurence as before, instead of searching in the new Range.

Please help, the code is the one from above, I did not change it.
Thank you,
Costin
 
Please read my post again. If you read it carefully it explains.

"I resize myRange in such way to continue searching till the end of the document: myRange.SetRange myRange.End, Doc.Word.Range Now myRange contains: "s are blue now, yesterday the links were black.", because I exclude the first part of the text which was already processed."

You do not need to do this at all.

Just for example sake, say the document in its entirety is:

"The links are blue now, yesterday the links were black."

Now if I understand correctly, what you want has nothing to do with the text following. In other words: getting "s are blue now, yesterday the links were black." after the first found "link" is completely irrelevant.

I will repeat. Using a Range will proceed to the first found, then the next, then the next.... The range itself is resized, and therefore each Found does have its own start and end.
Code:
Sub GetStuff()
Dim r As Range
Set r = ActiveDocument.Range
With r.Find
  Do While .Execute(FindText:="link", _
        Forward:=True) = True
     myControl.AddItem r.Start & " - " & r.End & " = " _
        r.Text
  Loop
End With
End Sub
will do exactly as you are asking, if I understand correctly. You may want to be carefully with how ranges deal with themselves.

"The links..." Using "link" as the findtext, the found range Start = 4, not 5.

faq219-2884

Gerry
My paintings and sculpture
 
Hi,

Thank a lot for the answer. I will use this approach tonight to see how it behaves. I used the first method I described because I felt like having more control.

Thank you again for your quick answer.
Costin
 
I used the first method I described because I felt like having more control."

What makes you think you have more control?

More curiously...what do you think you have control of?

faq219-2884

Gerry
My paintings and sculpture
 
Hi,

It is one thing when I can define myself the start and end of a Range, than let Word choose. I thought I can control better, by specifying exact positions.

I will try today the method proposed by you.

Thanks,
Costin
PS: What if not?
 
I thought I can control better, by specifying exact positions."

Huh?????? Again, control WHAT exactly? The range is resized automatically, and you can get the Start and End values each time...just like in my code. You take those values, as text, and pass them, as text, to your control.AddItem.

"It is one thing when I can define myself the start and end of a Range, than let Word choose. "

Except for one thing...you did it wrong. And got yourself into the looping situation you had. If you had let Word do it...that would not have happened. So, IMO, you lost control, you did not get control.

There is simply no need for you to do this. Word does it very very well, thank you very much. I suggest you let it.

faq219-2884

Gerry
My paintings and sculpture
 
Hi,

Indeed it worked. I was a bit skeptical because my initial version worked for some test files. I only noticed the looping when putting on a live file (not test).

Thanks so much.

Costin
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top