我已经暂时搁浅了一段时间,似乎无法想出一个解决方案。我必须通过通配符搜索自定义标记从头到尾搜索文档。为了问题,我们会说{something}
当我找到特定匹配时,它会被另一个字符串的内容替换,该字符串可以也包含标记。标记必须按照它在最终文档中出现的顺序进行替换 AND 我必须知道每次替换的递归级别。
这基本上就是我提出来的。请注意,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
有人看到我失踪的任何东西吗?
答案 0 :(得分:2)
Word的Find
行为非常奇怪。
在其他特性中,如果您的搜索文本与Range
文本的完全匹配匹配,则忽略Wrap选项,并根据此{重新定义搜索范围} {3}}:
当Find对象.Execute方法确定要查找的内容与搜索范围完全匹配时,将动态重新定义搜索范围。新搜索范围从旧搜索范围的末尾开始,到文档末尾(或目标storyRange)结束。处理在重新定义的范围内继续。
这就是为什么{fizzbuzz}
(带尾随空格)有效 - 它不完全匹配。
您需要调整代码才能处理:
Range.Text
与通配符搜索完全匹配,和/或:Execute
后,检查Range
的开头是,然后预期结束。您可以通过在每次Range
来电之前和之后以及每次Range.Select
作业之前和之后添加Execute
声明来查看Text
更改操作