сокращенного поискRange.Find - проблема с .Found в wdInFieldResult
Когда findRng.Find успешно обнаруживает поисковый текст в поле результата (например, оглавление) начинается следующий .Execute в начале ТОС а не в исходной позиции, которая была указана ниже документа из предыдущего findRng.Find. Это можно визуально показать, выбрав findRng.select. В свойствах Start и End findRng выбор не должен включать начало TOC, но он делает И это похоже на то, что использует метод .Find, потому что он становится адресом Apple Corporate Headquarters; т. е. один бесконечный контур. ;)
Вы можете посмотреть значения findRng.Start и .End, которые ожидаются до утверждения .Execute в нижней части подпрограммы.
Если кто-либо не может исправить проблему сброса диапазона, я был бы счастлив, просто найдя способ быстро определить местоположение .End поля, которое запускает wdInFieldResult, давая True и продолжая жизнь.
Sub findAcronyms()
Dim findRng As Range, tempRng As Range
Dim oFld As Field
Dim findStr As String, acroStr As String
Dim acroTbl As Table
'################# test code
Dim testMode As Boolean
Dim testIdx As Long, testSize As Long, i As Long
testMode = True
testIdx = 0
testSize = 25
If testMode Then
ThisDocument.ShowRevisions = True
ThisDocument.TrackRevisions = True
End If
Quiet (Not testMode)
'#################
'set acroTbl to ThisDocument's Acronym table
Set findRng = ThisDocument.Content
findStr = "ACRONYMS"
With findRng.Find
.ClearFormatting
.Style = WdBuiltinStyle.wdStyleHeading1
.Text = findStr
.Forward = False
.Wrap = wdFindStop
.Format = False
.Execute
If Not .Found Then
MsgBox findStr & ": not found!", vbExclamation
Stop
Debug.Print "Debug the issue..."
Else
findRng.MoveStart wdTable
findRng.Expand wdTable
Set acroTbl = findRng.Tables(1)
End If
End With
'find occurrences of "(" and if closing parens "(" is within 7 characters then add to end of Acronym table
Set findRng = ThisDocument.Content
findStr = "("
With findRng.Find
.ClearFormatting
.Text = findStr
.Forward = True
.Wrap = wdFindStop
.Format = False
.Execute
Do While .Found 'until Find finds other than itself or EOD
'################# test code
If testMode Then
findRng.Select
Debug.Print findRng.Start
testIdx = testIdx + 1
If testIdx > testSize Then
Stop 'and Debug if necessary
Exit Sub
End If
End If
'################
i = findRng.MoveEndUntil(")", 7)
If i > 2 And Not findRng.Text Like Left(findStr & "#######", _
Len(findRng.Text)) Then
'check for pre-existence of acronym before adding to table
Set tempRng = ThisDocument.Range(acroTbl.Columns(1).Cells(2).Range.Start, _
acroTbl.Columns(1).Cells(acroTbl.Columns(1).Cells.Count).Range.End)
tempRng.Find.ClearFormatting
With tempRng.Find
.Text = Mid(findRng.Text, 2, i)
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = True
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute
If Not .Found Then 'proceed with adding new acronym to table
With acroTbl.Rows
.Add
With .Last
.Cells(1).Range.Text = Mid(findRng.Text, 2, i)
i = findRng.Start
findRng.Collapse wdCollapseStart
findRng.MoveStart wdCharacter, -1
findRng.MoveStart wdWord, _
-.Cells(1).Range.Characters.Count
.Cells(2).Range.Text = Trim(findRng.Text)
findRng.Start = i + 1
Debug.Print .Cells(1).Range.Text, .Cells(2).Range.Text
End With
End With
End If
End With
Else: findRng.MoveStart wdWord 'skip over 2 letter acronyms
End If
If findRng.Information(wdInFieldResult) Then
findRng.MoveStart wdParagraph 'in lieu of a better solution I need to determine how to get out of the field result
ElseIf findRng.Information(wdWithInTable) Then
If findRng.InRange(findRng.Tables(1).Range.Cells(findRng.Tables(1).Range.Cells.Count).Range) Then 'test if in last cell
findRng.Expand wdTable
findRng.Collapse wdCollapseEnd
Else
findRng.MoveStart wdCell
End If
Else
findRng.MoveStart wdWord
End If
'################# test code
If testMode Then findRng.Select
'################
findRng.Collapse wdCollapseEnd
findRng.End = ThisDocument.Content.End
.Execute
Loop
End With
Stop
End Sub
Последующее исследование с использованием процедуры рекурсии, в которой только часть поля. Результат возвращается в Sub, также приводит к такому же поведению. То есть, вся Field.Result перерабатывается с самого начала при выполнении инструкции .Execute. По моему мнению, включение информации о результатах поля приводит к нарушению функции .Find. – IronX