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
替换为 wdFindAsk
或 wdFindStop
.
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
简而言之,你是靠自己的。
您有两个选择:恢复到以前保存的版本;或者,编写一个模仿撤消的宏,并确保此宏是 运行,然后再开始与撤消列表混淆的宏
在 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
替换为 wdFindAsk
或 wdFindStop
.
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
简而言之,你是靠自己的。
您有两个选择:恢复到以前保存的版本;或者,编写一个模仿撤消的宏,并确保此宏是 运行,然后再开始与撤消列表混淆的宏