【问题标题】:How to speed up VBA style replacement for multiple words within MS Word document? [duplicate]如何加快 MS Word 文档中多个单词的 VBA 样式替换? [复制]
【发布时间】:2020-01-10 18:08:02
【问题描述】:

几天前我一直在尝试使用以下脚本的一些变体来更改单词的样式 阵列内。该文档有大约 1200 页和 8MB 大小,但对于 MS Word 来说似乎更重。

它下面的脚本似乎比使用 Selection.Find 更快,但 40 分钟后我需要停止宏,因为 仅执行了 64 次迭代(共 182 次)。

还有其他方法可以提高这个宏的执行速度吗?我什至尝试使用嵌套循环查找每个段落的所有单词,但效果最差。

宏在文档中查找数组的每个单词并 如果单词是粗体而不是斜体,则适用 StyleA 如果单词不是粗体且不是斜体,则应用 StyleB 如果单词是斜体,则应用 StyleC

感谢您的帮助。

Sub ChangeStyles()
    Dim i As Long
    Dim Arr(1 To 182)
    Dim rng As Word.Range

Application.ScreenUpdating = False

Arr=Array("Word1","Word2",..,"Word182",)

For i = 0 To UBound(Arr)
    Set rng = ActiveDocument.Content

    With rng.Find
        .ClearFormatting
        .Replacement.ClearFormatting
        .Text = Arr(i)
        .Execute
        If rng.Characters(1).Font.Bold = True And rng.Characters(1).Font.Italic = False Then
        .Replacement.Style = ActiveDocument.Styles("StyleA")
        ElseIf rng.Characters(1).Font.Bold = False And rng.Characters(1).Font.Italic = False Then
            .Replacement.Style = ActiveDocument.Styles("StyleB")
        ElseIf rng.Characters(1).Font.Italic = True Then
            .Replacement.Style = ActiveDocument.Styles("StyleC")
        End If
        .Execute Replace:=wdReplaceAll
    End With
    Debug.Print "word: " & i
Next


Application.ScreenUpdating = True

End Sub

【问题讨论】:

  • 这里的逻辑是错误的——我想我之前已经讨论过同样的基本问题。您在循环中有两次Execute,第二次是ReplacAll。这根本没有意义。如果您打算走这条路线,而不是我建议的更快的路线,那么只需在If...Else 中执行rng.Style = ActiveDocument.Styles("NameOfStyle"),而不是设置Replacement.Style 并尝试再次执行Find。但我仍然说,为每个格式变体查找/替换会更有效......
  • 嗨辛迪。对不起打扰你了。我已经用你的建议进行了测试,它可以工作,但在实际文件中卡住了。我不确定为什么。我知道在“.Text(i)”之后为了找到这个词需要发送“.Execute”并且在找到它之后我插入了if条件来应用相应的样式。我知道此时只有一个单词匹配,为了将样式更改为所有实例,我添加了“ReplaceAll”。应该如何?我应该使用“rng.Style=...”而不是什么?再次感谢. 我继续测试的主要原因是性能缓慢。
  • @CindyMeister。感谢您到目前为止的帮助。换风格行得通,但是执行速度太慢了。

标签: vba performance ms-word


【解决方案1】:

您的代码中的逻辑是错误的。尽管您设置了替换样式,但您没有设置任何格式供Find 查找。因此,.Execute Replace:=wdReplaceAll 将找到 .Text = Arr(i) 的所有实例,并将样式替换为第一个结果中 If 语句中设置的样式。

正如 Cindy Meister 在她的评论中指出的那样,对每个单词使用多次查找和替换迭代可能会产生最快的结果。

我已经编辑了您的代码,以向您展示如何实现这一目标。

Sub ChangeStyles()
  Dim i As Long
  Dim Arr(1 To 182)

  Application.ScreenUpdating = False

  Arr=Array("Word1","Word2",..,"Word182",)

  For i = 0 To UBound(Arr)
    ReplaceStyle SearchText:=Arr(i), Bold:=True, Italic:=False, NewStyle:=ActiveDocument.Styles("StyleA")
    ReplaceStyle SearchText:=Arr(i), Bold:=False, Italic:=False, NewStyle:=ActiveDocument.Styles("StyleB")
    ReplaceStyle SearchText:=Arr(i), Bold:=False, Italic:=True, NewStyle:=ActiveDocument.Styles("StyleC")
  Next

  Application.ScreenUpdating = True

End Sub

Sub ReplaceStyle(SearchText As String, Bold As Boolean, Italic As Boolean, NewStyle As style)
  Dim rng As Range
  Set rng = ActiveDocument.Content
  With rng.Find
    .ClearFormatting
    .Text = SearchText
    With .Font
      .Bold = Bold
      .Italic = Italic
    End With
    .Replacement.ClearFormatting
    .Replacement.style = NewStyle
    .Execute Replace:=wdReplaceAll
  End With
End Sub

【讨论】:

  • 嗨蒂莫西。感谢您的回答。我用一页的测试文档测试了你的代码,替换了 9 个单词的样式,耗时 0.19 秒。然后,我用 8 MB 和 1200 页的实际文件测试了 10 多分钟,结果卡住了。我不知道是否正在替换样式,因为我需要停止宏并重新启动 MS Word。
  • 停下来想一想。您正在对一个非常大的文档执行 546 次查找和替换操作。这不会是一个快速的操作。为了进行比较,请使用标准 Word 界面对一个单词和格式组合进行查找和替换。
  • 谢谢。我就这样吧。
猜你喜欢
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-05
  • 2021-04-27
相关资源
最近更新 更多