使用VBA for Word查找和替换会覆盖以前的样式

我正在编写VBA脚本,以从已定义的模板生成Word文档。在其中,我需要能够为每个标题写一个标题以及一个正文。举一个小例子,我有一个Word文档,仅包含<PLACEHOLDER>。对于我需要编写的每个标题和正文,我使用VBA中的“查找和替换”功能来找到<PLACEHOLDER>,并将其替换为标题名称,换行符,然后再次使用<PLACEHOLDER>。重复此操作,直到写入每个标题名称和正文,然后将最后的<PLACEHOLDER>换行。

文本替换工作正常,但是我指定的样式被替换的 next 调用所覆盖。这导致我刚刚替换的所有东西都具有我对替换函数的 last 调用的样式。

VBA代码(运行main

Option Explicit

Sub replace_stuff(search_string As String,replace_string As String,style As Integer)
    With activeDocument.Range.Find
        .Text = search_string
        .Replacement.Text = replace_string
        .Replacement.style = style
        .Forward = True
        .Wrap = wdFindContinue
        .Format = True
        .MatchWholeWord = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
        .Execute Replace:=wdReplaceAll
    End With
End Sub

Sub main()
    Dim section_names(2) As String
    section_names(0) = "Introduction"
    section_names(1) = "Background"
    section_names(2) = "Conclusion"

    Dim section_bodies(2) As String
    section_bodies(0) = "This is the body text for the introduction! Fetched from some file."
    section_bodies(1) = "And Background... I have no issue fetching data from the files."
    section_bodies(2) = "And for the conclusion... But I want the styles to 'stick'!"

    Dim i As Integer
    For i = 0 To 2
        ' Writes each section name as wsStyleHeading2,and then the section body as wdStyleNormal
        Call replace_stuff("<PLACEHOLDER>",section_names(i) & Chr(11) & "<PLACEHOLDER>",wdStyleHeading2)
        Call replace_stuff("<PLACEHOLDER>",section_bodies(i) & Chr(11) & "<PLACEHOLDER>",wdStyleNormal)
    Next i
    Call replace_stuff("<PLACEHOLDER>",Chr(11),wdStyleNormal)

End Sub

输入文档:仅包含<PLACEHOLDER>的Word文档。

<PLACEHOLDER>

预期输出: 我希望每个标题都将以我指定的样式显示,并且可以从导航窗格中进行如下查看:

使用VBA for Word查找和替换会覆盖以前的样式

实际输出:但是,我实际上得到的是像这样的wdStyleNormal样式的所有东西:

使用VBA for Word查找和替换会覆盖以前的样式

我认为可以通过在每个样式转换之间插入一个换行符来解决问题,但是当我尝试使用vbCrLFChr(10) & Chr(13)vbNewLine时,可以解决此问题我现在使用的chr(11)中的每一行中,每一行都以这样的框状问号开头:

使用VBA for Word查找和替换会覆盖以前的样式

huomiao1122 回答:使用VBA for Word查找和替换会覆盖以前的样式

在对另一个答案的评论中,

更新。下面描述的问题适用于Word 2016及更早版本。从 Office 365 (可能还有Word 2019)开始,from collections import defaultdict from typing import Dict vars: Dict[str,int] = defaultdict(int) while True: try: var,inc = input("Gimme a variable and an increment: ").split() vars[var] += int(inc) except: break print(dict(vars)) 的行为已更改为将ANSI 13转换为“真实” “段落标记,因此问题不会出现。

答案

出现奇数格式行为的原因是使用Replace,它会插入新行(Shift + Enter)而不是新段落。因此,应用于此文本任何部分的段落样式都会用相同的样式格式化整个文本。

在这种特殊情况下(使用Chr(11)),Replace或等效的vbCr也无效,因为它们不是Word的本机段落。段落不仅仅是ANSI代码13,它还包含段落格式信息。因此,在代码运行时,Word并未真正将它们识别为真正的段落标记,并且段落样式分配已应用于“所有内容”。

有效的方法是使用字符串Chr(13),它在Word的“查找/替换”中是完整段落标记的“别名”。因此,例如:

^p

但是,比为每个新项目插入一个占位符并使用“查找/替换”将占位符替换为文档内容,这是一种更有效的构建文档的方法。较传统的方法是使用replace_stuff "<PLACEHOLDER>",section_names(i) & "^p" & "<PLACEHOLDER>",wdStyleHeading2 replace_stuff "<PLACEHOLDER>",section_bodies(i) & "^p" & "<PLACEHOLDER>",wdStyleNormal 对象(将其视为不可见的选择)...

将内容分配给Range,对其进行格式化,折叠(如按右箭头进行选择)并重复。这是一个示例,该示例返回与问题中的(更正)代码相同的结果:

Range
,

此问题是由您使用Chr(11)(这是手动换行符)引起的。这导致所有文本都在一个段落中。应用段落样式时,它将应用于整个段落。

Chr(11)替换为vbCr,以确保每段文字都位于单独的段落中。

本文链接:https://www.f2er.com/3150515.html

大家都在问