MS Word VBA 样式和分页清理

问题描述

我公司的工作流程目前包括一个流程,我们从存储库导出文档,对其进行一些清理,然后将其发送到生产线以供审核/批准。 “稍微清理一下”涉及运行一个宏,该宏除其他外,执行查找/替换样式以将它们从存储库中的内容更改为我们的文档模板指定的内容。因此,例如,存储库为我们提供了“p_body”的样式,我们需要将其设为“body”。这个宏运行得很好,除了一些我想看看我们是否可以改进的东西。

一个问题是,当涉及到它提供的样式时,存储库的行为往往有些不可预测。使用上面的示例,不是以该样式标记所有“p_body”文本,而是返回“p_body”、“p_body_1”、“p_body_1_1”等。目前,宏中的样式切换都是硬编码的,所以为了让宏修复某些东西,它必须知道它存在。因此,如果存储库输出宏中尚未包含的样式,则无法修复。我知道如果我正在处理 HTML 文档,我可以使用正则表达式来查找“p_body”样式的所有版本,并将它们替换为“body”。有没有办法使用这种更智能的查找/替换版本,而不是对每个需要替换的样式进行硬编码?

第二个问题需要一个单独的问题来解决,所以现在被删掉了。

为了后代,这里是宏查找/替换块之一的样子:

Selection.Find.ClearFormatting
Selection.Find.Style = ActiveDocument.Styles("p_body")
Selection.Find.Replacement.ClearFormatting
Selection.Find.Replacement.Style = ActiveDocument.Styles("body")
With Selection.Find
    .Text = ""
    .Replacement.Text = ""
    .Forward = True
    .Wrap = wdFindask
    .Format = True
    .MatchCase = False
    .MatchWholeWord = False
    .MatchWildcards = False
    .MatchSoundsLike = False
    .MatchAllWordForms = False
End With
Selection.Find.Execute Replace:=wdReplaceAll

解决方法

为了处理 p_body 和其他人的样式名称变化,试试这个。您用要查找的名称填充 StyName1 数组,并在 StyName2 数组中放置替换名称。必须是一对一的对决。

这只是众多编码方式中的一种。

Sub StyleNames()
    Dim StyName1 As Variant,StyName2 As Variant
    StyName1 = Array("p_body","p_bold")
    StyName2 = Array("body","bold")
    
    Dim i As Long
    Dim findStyName As String,replaceName As String
    
    For i = LBound(StyName1) To UBound(StyName1)
        findStyName = StyName1(i)
        replaceName = StyName2(i)
        FindAndReplaceStyles findStyName,replaceName
    Next
    
End Sub

Private Function FindAndReplaceStyles(ByRef findStyName As String,ByRef replaceName As String)
    Dim sty As Word.Style,aStory As Word.Range
    For Each sty In ActiveDocument.Styles
        If InStr(1,sty.NameLocal,findStyName) Then
            For Each aStory In ActiveDocument.StoryRanges
                With aStory.Find
                    .ClearFormatting
                    .Format = True
                    .Forward = True
                    .MatchWildcards = False
                    .Style = sty.NameLocal
                    .Text = ""
                    .Wrap = wdFindStop
                    .Replacement.ClearFormatting
                    .Replacement.Style = replaceName
                    .Replacement.Text = ""
                    .Execute Replace:=Word.wdReplaceAll
                End With
            Next
            Exit For
        End If
    Next
End Function