自动化邮件合并

Automating Mail Merge

我需要使用来自 Access 数据库的文本动态生成 word 文档 table。这里需要注意的是,一些来自数据库的文本需要修改为 MergeFields。我目前正在使用 Interop.Word(VBA 宏)和 VB.NET 来生成文档。

到目前为止我的步骤是这样的:

  1. 拉取标准 .docx 模板
  2. 使用来自 table
  3. 的预定义填充文本填充模板
  4. 通过用实际合并字段替换部分填充文本来添加 MergeFields
  5. 附加数据源并执行邮件合并

经过测试,我注意到我不能简单地将 MergeFields 作为字符串存储到访问数据库中,它们不会反馈到实际文档中。我当时在想的是创建一个 table 的已知字符串,应该通过编码将其替换为 MergeFields。

例如:

第 2 步将插入 "After @INACTIVE_DATE@ your account will no longer be active.",这将在数据库文本中。

第 3 步将 find/replace@INACTIVE_DATE@ 与 MergeField «INACTIVE_DATE»。我正在使用 Word Interop 来执行此操作,因此理论上我可以循环浏览文档。

我无法执行从文本到 MergeField 的 "Find And Replace",那么我应该如何实施呢?

另外标记 VBA,因为我正在寻找 "VBA" 风格的答案(Word Interop)。

你遗漏了很多细节,所以我会用一些笼统的术语来回答这个问题。

你想做的事绝对可以实现。立即想到两个可能的解决方案:

  1. 使用 Find
  2. 替换范围
  3. 使用 TypeText
  4. 插入标记

使用 Find

替换范围

假设文本已经插入,您可以在文档中搜索给定的模式并将其替换为合并字段。例如:

Sub FindInsertMerge()
    Dim rng As Range
    Set rng = ActiveDocument.Range

    With rng.Find
        .Text = "(\@*\@)"
        .MatchWildcards = True
        .Execute

        If .Found Then
            ActiveDocument.MailMerge.Fields.Add rng, Mid(rng.Text, 2, Len(rng.Text) - 2)
        End If
    End With
End Sub

将查找第一次出现的以 @ 开头的文本,匹配任何字符串并以 @ 结尾。找到的范围的内容随后将被合并字段替换。上面的代码可以很容易地扩展为对所有字段进行循环。

使用 TypeText

插入标记

虽然我通常建议不要使用 Selection 插入数据,但此解决方案使事情变得简单。假设您有一个目标范围,rng,您将要插入的数据库文本标记化,select 范围,开始键入,每当找到指定的邮件合并字段时,插入一个字段而不是文本。

例如:

Private Sub InsertMergeText(rng As Range, txt As String)
    Dim i As Integer
    Dim t As String
    Dim tokens() As String

    tokens = Split(txt, " ")
    rng.Select

    For i = 0 To UBound(tokens)
        t = tokens(i)

        If Left(t, 1) = "@" And Right(t, 1) = "@" Then
            'Insert field if it's a mail merge label.
            ActiveDocument.MailMerge.Fields.Add Selection.Range, Mid(t, 2, Len(t) - 2)
        Else
            'Simply insert text.
            Selection.TypeText t
        End If

        'Insert the whitespace we replaced earlier.
        If i < UBound(tokens) Then Selection.TypeText " "
    Next
End Sub

调用示例:

InsertMergeText Selection.Range, "After @INACTIVE_DATE@ your account will no longer be active which will be in the database text."