Ключ к этому, кажется, заключается в том, что когда вы перебираете Range, глядя на каждую «позицию» в диапазоне, например, через что-то вроде
With ActiveDocument.Range
For i = 0 to .End - 1
Debug.Print i,Ascw(.Range(i,i+1).Text)
Next
End With
Range действительно содержит все символы в коде поля, такого как поле ГИПЕРССЫЛКА, и все символы в его результате (который может быть отображен или может быть скрытым текстом). Но в некоторых случаях Range может содержать дополнительные символы, которые никогда не отображаются. Например, если у вас есть код поля, такой как {SET x 123}, тогда диапазон содержит то, что фактически является скобками поля и кодом «SET X 123», но перед конечной скобкой поля он также содержит маркер, за которым следует значение «123». Но поле SET не отображает его результат.
Это затрудняет построение строки "find" той же длины, что и Range.
Но Range.Text - это тот же текст, что и конкатенация всех символы в Range.Characters, и каждый символ в этой коллекции - это диапазон, который содержит позицию .Start
. Это позволяет нам получить .Start и .End, как показано в следующем примере.
Предполагается, что вы работаете с ActiveDocument в Word и имеете некоторый текст, поле ГИПЕРССЫЛКИ (скажем) и, возможно, другие поля с текстом «test1» в разных местах.
Я не проводил большого количества тестов, так что, возможно, его еще нужно настроить.
Sub HighlightFinds()
Dim match As VBScript_RegExp_55.match
Dim matches As VBScript_RegExp_55.MatchCollection
Dim rng1 As Word.Range
Dim rng2 As Word.Range
Set rng1 = ActiveDocument.Content
Set rng2 = ActiveDocument.Content ' or rng1.Duplicate
' When you do this, rng1.Text returns the text of the field *codes* but
' not the field *results*, and so does rng1.Characters
'rng1.TextRetrievalMode.IncludeFieldCodes = True
' when you do this, it returns the *results* but not the *codes*
rng1.TextRetrievalMode.IncludeFieldCodes = False
' You could do both, one after the other, to try to get all the matches
' You might also need to set .TextRetrievalMode.IncludeHiddenText
With New VBScript_RegExp_55.RegExp
.Pattern = "test1"
.Global = True
Set matches = .Execute(rng1.Text)
End With
For Each match In matches
rng2.SetRange rng1.Characters(match.FirstIndex + 1).Start, rng1.Characters(match.FirstIndex + 1 + match.Length).End
rng2.HighlightColorIndex = wdYellow
Next
Set matches = Nothing
Set rng2 = Nothing
Set rng1 = Nothing
End Sub