Help With .Find Behaviour

G

Greg Maxey

Today I posted some code in the DocManagement group for deleteing duplicate
email entries from a document.

While working on this code I came across some behaviour with the .Find
method that I don't understand. Basically my approach was to search the
entire document for the first email address, set a variable to the end of
the first found item, look at the field code of each field in the document
and if it matched the first e-mail then delete the field, redefine the
search range to begin at the end of the first found e-mail and search for
the next e-mail address.

For some reason even though the search range didn't include the first e-mail
address it was still being found!!???


Here is the final code that worked. I marked where I had to add code to
overcome this behaviour. Any help in understanding this is appreciated.
Thanks.

Sub ScratchMacroII()
Dim pStr As String
Dim oRng As Range
Dim i As Long
Dim j As Long
Dim oFld As Field
Dim bLoop As Boolean
i = 1
bLoop = True
Do
Set oRng = ActiveDocument.Range
oRng.Start = i
With oRng.Find
.Text = "?{1,}\@?{1,}.?{3}"
.MatchWildcards = True
Do
.Execute
If Not .Found Then
bLoop = False
Exit Do
End If
If oRng.Start >= i Then 'Added this line to ignore a found item
preceeding the set search range
pStr = Trim(oRng.Text)
i = oRng.End
j = 0
For Each oFld In ActiveDocument.Fields
If InStr(oFld.Code, pStr) > 0 Then
j = j + 1
If j > 1 Then
oFld.Delete
End If
End If
Next oFld
Exit Do
Else ' Added this line
oRng.Collapse wdCollapseEnd 'Added this line
End If ' Added this line
Loop While .Found = True
End With
Loop While bLoop = True
End Sub
 
J

Jonathan West

Hi Greg,

In order to prevent the Find attempting to continue searching outside the
specified range, set the .Wrap property of the Find object to wdFindStop. I
suspect that not having this property correctly set is contributing to the
strange behaviour.
 
G

Greg Maxey

Jonathan,

Thanks for the reply. Actually I had tried that:
.....
With oRng.Find
.Text = "?{1,}\@?{1,}.?{3}"
.Wrap = wdFindStop
.MatchWildcards = True
.....

and it made no difference.

Here is a new twist. My earlier test document was just a collection of four
or five e-mail addresses with some of them repeated. When I added some
additional text before the first e-mail address the behaviour stops. Again
with or without .Wrap = wdFindStop

To see this for yourself enter a few repeating email addresses in a new
blank document. For example:

(e-mail address removed) (e-mail address removed) (e-mail address removed) (e-mail address removed)
(e-mail address removed) (e-mail address removed)

Then step through this code (if I run it, I get a continous loop):

Sub ScratchMacroII()
Dim pStr As String
Dim oRng As Range
Dim i As Long
Dim j As Long
Dim oFld As Field
Dim bLoop As Boolean
i = 1
bLoop = True
Do
Set oRng = ActiveDocument.Range
oRng.Start = i
With oRng.Find
.Text = "?{1,}\@?{1,}.?{3}"
'.Wrap = wdFindStop
.MatchWildcards = True
Do
.Execute
If Not .Found Then
bLoop = False
Exit Do
End If
'If oRng.Start >= i Then
pStr = Trim(oRng.Text)
i = oRng.End
j = 0
For Each oFld In ActiveDocument.Fields
If InStr(oFld.Code, pStr) > 0 Then
j = j + 1
If j > 1 Then
oFld.Delete
End If
End If
Next oFld
Exit Do
'Else
'oRng.Collapse wdCollapseEnd
'End If
Loop While .Found = True
End With
Loop While bLoop = True
End Sub

But if I simply add a single word or letter to the beginning of the document
the code runs fine:

A (e-mail address removed) (e-mail address removed) (e-mail address removed) (e-mail address removed)
(e-mail address removed) (e-mail address removed)
 
H

Helmut Weber

Hi Submariner,

to set a range's start to a position
within a field seems to be useless,
as it is automatically set to the fields start.
I wonder why.
Furthermore, some characters in the field
code seem to count more than others.

This is the text:

(e-mail address removed)¶
(e-mail address removed)¶
(e-mail address removed)¶
(e-mail address removed)¶


This is the code, watch it in single step mode:

Sub Test6001()
Dim lng As Long
Dim rng As Range
Set rng = ActiveDocument.Range
For lng = 52 To 59
rng.start = lng
rng.Select
Next
End Sub

So it seems you are always
processing the same first hyperlink.

With adding an extra character,
your variable i gets out of the critical
range of characters.
If I only knew why and how!

By the way, how about that:

Sub Test0083456()
Dim Linka As Hyperlink
Dim Linkb As Hyperlink
For Each Linka In ActiveDocument.Hyperlinks
For Each Linkb In ActiveDocument.Hyperlinks
If Linka.Address = Linkb.Address Then
If Linka.Range.start <> Linkb.Range.start Then
Linkb.Range.Delete
End If
End If
Next
Next
End Sub

--
Greetings from Bavaria, Germany

Helmut Weber, MVP WordVBA

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

Greg Maxey

Helmut,

Weird yes.

Your suggested method seems far better for this specific task ;-)

Cheers.
 
T

Tony Jollans

to set a range's start to a position
within a field seems to be useless,
as it is automatically set to the fields start.
I wonder why.

It depends on the .TextRetrievalMode setting. If the position you choose is,
effectively, excluded from the Range then an alternative position has to be
used - Word opts for the beginning of the field.
 

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