I've been flailing at this for a while and can't seem to come up with a solution. I have to search through a document from start to finish with a wildcard search for custom mark-up. For the sake of the question, we'll say {something}
When I find a specific match, it gets replaced with the contents of another string which can also contain mark-up. The mark-up has to be replaced in the order it will appear in the final document AND I have to know the recursion level that each replacement was made at.
This is basically what I came up with. Note that the ProcessReplacement
function is contrived for the example - the text gets replaced by an external program:
Option Explicit
Private replaced As Integer
Public Sub Demo()
Dim pos As Range
Set pos = ActiveDocument.Content
replaced = 0
pos.Text = "{fizz}{fizz}{more}{buzz}{buzz}"
Expand pos
End Sub
Private Sub Expand(incoming As Range, Optional depth = 1)
Dim sub_range As Range
Dim end_pos As Long
end_pos = incoming.End
With incoming.Find
.ClearFormatting
.MatchWildcards = True
.Forward = True
.Wrap = wdFindStop
End With
Do While incoming.Find.Execute("\{*\}")
If incoming.Start < incoming.End Then
Debug.Print "Replaced " & incoming.Text & " at " & depth
end_pos = end_pos + ProcessReplacement(incoming)
Set sub_range = incoming.Duplicate
Expand sub_range, depth + 1
incoming.End = end_pos
incoming.Start = sub_range.End - 1
End If
Loop
End Sub
Private Function ProcessReplacement(replacing As Range) As Long
Dim len_cache As Long
len_cache = Len(replacing.Text)
If replacing.Text = "{more}" Then
replacing.Text = "{foo}{evenmore}{bar}"
ElseIf replacing.Text = "{evenmore}" Then
'This kind of works.
replacing.Text = "{fizzbuzz} "
'This doesn't work at all.
' replacing.Text = "{fizzbuzz}"
Else
replaced = replaced + 1
replacing.Text = "<" & replaced & ">"
End If
ProcessReplacement = Len(replacing.Text) - len_cache
End Function
The first issue is that I can't figure how to keep the .Find.Execute confined to the correct Range. This is what the document and output look like (with the space after {fizzbuzz}- more on that later):
Document text: <1><2><3><4> <5><6><7>
Output:
Replaced {fizz} at 1
Replaced {fizz} at 1
Replaced {more} at 1
Replaced {foo} at 2
Replaced {evenmore} at 2
Replaced {fizzbuzz} at 3
Replaced {bar} at 2
Replaced {buzz} at 2 <---This was outside of the range at that depth.
Replaced {buzz} at 1
If I take the space out after {fizzbuzz}, it doesn't even get matched, even though I confirmed in the watch window that it is basically the contents of the range when the function recurses after its replacement. Output without the space:
Document text: <1><2><3>{fizzbuzz}<4><5><6>
Output:
Replaced {fizz} at 1
Replaced {fizz} at 1
Replaced {more} at 1
Replaced {foo} at 2
Replaced {evenmore} at 2
Replaced {bar} at 3 <---No clue how this happens - wdFindStop is ignored.
Replaced {buzz} at 3
Replaced {buzz} at 3
Expected output (with or without spaces):
Document text: <1><2><3><4><5><6><7>
Output:
Replaced {fizz} at 1
Replaced {fizz} at 1
Replaced {more} at 1
Replaced {foo} at 2
Replaced {evenmore} at 2
Replaced {fizzbuzz} at 3
Replaced {bar} at 2
Replaced {buzz} at 1
Replaced {buzz} at 1
Anybody see anything that I'm missing?
Word's Find
behavior is very odd.
Among other peculiarities, if your search text is an exact match for the Range
's text, then the Wrap option is ignored, and the search range is redefined as per this article :
When the Find object .Execute method determines that the thing to find exactly matches the search range, the search range is dynamically redefined. The new search range starts at the end of the old search range and ends at the end of the document (or targeted storyRange). Processing continues in the redefined range.
That's why the {fizzbuzz}
(with the trailing space) works - it's not an exact match.
You'll need to adapt your code to handle:
Range.Text
is an exact match for the wildcard search, and/or: Execute
, check that the Range
's start is before the expected end. You can see the Range
changes in action by adding a Range.Select
statement before and after every Execute
call and before and after every Text
assignment
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.