無法獲得遞歸Range.Find在Word VBA中工作

我一直在爲此喋喋不休,似乎無法想出一個解決方案.我必須通過通配符搜索自定義標記從頭到尾搜索文檔.爲了這個問題,我們會說{something}當我找到一個特定的匹配時,它會被另一個字符串的內容替換,該字符串也可能包含標記.標記必須按照它在最終文檔中出現的順序進行替換.我必須知道每次替換所做的遞歸級別.

這基本上就是我提出的.請注意,ProcessReplacement函數是爲示例設計的 – 文本被外部程序替換:

 

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

有人看到我遺失的任何東西嗎?

最佳答案 Word的查找行爲非常奇怪.

除了其他特性之外,如果您的搜索文本與Range的文本完全匹配,則忽略Wrap選項,並根據此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.

這就是{fizzbuzz}(帶尾隨空格)的原因 – 它不是完全匹配的原因.

您需要調整代碼來處理:

> Range.Text是通配符搜索的完全匹配,和/或:
>調用Execute後,檢查Range的開始是否在預期結束之前.

通過在每個Execute調用之前和之後以及每個Text分配之前和之後添加Range.Select語句,可以看到Range更改的操作

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章