Unable to get recursive Range.Find in Word VBA to work

I was a little worried about this and could not come up with a solution. I have to search the document from start to finish using a wildcard search for a custom add-in. For the sake of the question, we will say {something}When I find a specific match, it is replaced by the contents of another line, which may also contain markup. The inscription should be replaced in the order in which it will be displayed in the final document AND . I need to know the level of recursion at which each replacement was made.

This is basically what I came up with. Please note that for example, a function ProcessReplacementis implemented - the text is 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

, , .Find.Execute . ( {fizzbuzz} - ):

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

{fizzbuzz}, , , , . :

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

( ):

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

- -, ?

+4
1

Word Find .

, Range, Wrap , :

Find object.Execute , , . ( target storyRange). .

{fizzbuzz} ( ) - .

:

  • Range.Text - /:
  • Execute , Range .

Range , Range.Select Execute Text

+2

Source: https://habr.com/ru/post/1584399/


All Articles