VBA-Word 错误:如果在撤消列表中有 "Apply Quick Style" 时使用 UndoRecord 记录 "Replace All",则撤消列表会出错。如何避免?

VBA-Word bug: Undo list get error if use UndoRecord to record "Replace All" while there is a "Apply Quick Style" in the undo list. How to avoid?

在 Word window 上,执行诸如键入、格式化字体、段落等操作以确保撤消列表不为空,然后通过单击功能区上的任意样式更改某些文本的样式。名为 "Apply Quick Style" 的条目出现在撤消列表中。然后 运行 宏如:

Sub SampleMacro()
Dim myUndoRecord As UndoRecord

Set myUndoRecord = Application.UndoRecord
myUndoRecord.StartCustomRecord ("VBA - Format Text")
'I do a lot of step here, but for this example, just simple like below
Selection.Characters(1).Bold = True     'just for example
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
    .Text = "Find Text"
    .Replacement.Text = "Replace Text"
    .Forward = True
    .Wrap = wdFindContinue
    .Format = False
    .MatchCase = False
    .MatchWholeWord = False
    .MatchWildcards = False
    .MatchSoundsLike = False
    .MatchAllWordForms = False
End With
'Word undo list get error after below step
Selection.Find.Execute Replace:=wdReplaceAll
'no crash, no error message, but the entry "Apply Quick Style" 
'become to "Replace All", and Word can't go back before that entry
myUndoRecord.EndCustomRecord
End Sub

在这行代码之后:

Selection.Find.Execute Replace:=wdReplaceAll

撤消列表中名为 "Apply Quick Style" 的条目将变为 "Replace All",我无法撤消(按 Ctrl-Z,或单击快速访问工具栏上的箭头按钮)返回该条目之前的任何步骤 "Replace All"。它总是出现在撤消列表中,Word 将不再返回。 如何避免这个错误? 我使用的是 Word 2016 专业版 64 位

附加信息:通过按 Ctrl+C、Ctrl+V(从其他文档到当前文档)而不是 "Apply Quick Style" 使用复制粘贴也会出错,撤消列表中的条目 "Paste" 也会出错重命名为 "Replace all"。不同的人仍然能够回到那个条目之前。可能有另一种方式使用UndoRecord记录"Replace all".

会报错

更新 10/01

解决方法

此问题特定于 wdReplaceAll。如果该特定的 wdConstant 被省略或替换,那么 "Apply Quick Style" 将不会被重命名并且撤消堆栈仍然可以访问。

我们很幸运,Find.Execute returns 一个布尔值(True 表示成功)。这意味着,我们可以用 wdFindOne 循环替换所有匹配项,并使用 .Execute = False 作为退出条件。

With 块上方添加单词 Do 并将该行替换为 .Execute

Do
    With Selection.Find
         [....]
    End With
Loop While Selection.Find.Execute(Replace:=wdReplaceOne)

提醒一句:某些情况下会产生无限循环(例如将"A"替换为"A").因此,您应该考虑使用第二个退出条件或将 wdFindContinue 替换为 wdFindAskwdFindStop.


9 月 30 日更新

(编辑 10/01)糟糕!! Apply Quick Style 条目未重命名(好),但我错误地假设存在相同限制时可以达到撤消堆栈(坏)。另外,今天测试,我了解到 还有第三个条件:.Execute 不能找到任何匹配项 (更糟)。可以这么说,这是一个如何不测试解决方案的示例性演示,我希望每个人都吸取教训!

当我创建一个新文档并按照您的步骤操作时,我可以始终如一地重现您描述的问题。谢谢你让这一切变得简单!

尽管我能够重现该问题,但我也能够通过满足两个条件来避免它。

  • 确保 Replace All 列在 Apply Quick Style 上方的 Undo Stack 中。

  • Replace All 应用于整个文档(如果 Replace All 应用于文档中的 Selection,问题仍然存在)

无论是使用 'Ctrl + H' 手动完成还是作为宏的一部分,此方法都有效。用相同的字符替换一个字符就足够了。


显示问题行之后的执行点的屏幕截图:


Undo Stack 包含一个有意放置的 Replace All 以保留 Apply Quick Style。 本文适用于 Excel,但与 Word 相关。

https://excel.tips.net/T002060_Preserving_the_Undo_List.html

简而言之,你是靠自己的。

您有两个选择:恢复到以前保存的版本;或者,编写一个模仿撤消的宏,并确保此宏是 运行,然后再开始与撤消列表混淆的宏