自动化邮件合并
Automating Mail Merge
我需要使用来自 Access 数据库的文本动态生成 word 文档 table。这里需要注意的是,一些来自数据库的文本需要修改为 MergeFields。我目前正在使用 Interop.Word(VBA 宏)和 VB.NET 来生成文档。
到目前为止我的步骤是这样的:
- 拉取标准 .docx 模板
- 使用来自 table
的预定义填充文本填充模板
- 通过用实际合并字段替换部分填充文本来添加 MergeFields
- 附加数据源并执行邮件合并
经过测试,我注意到我不能简单地将 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)。
你遗漏了很多细节,所以我会用一些笼统的术语来回答这个问题。
你想做的事绝对可以实现。立即想到两个可能的解决方案:
- 使用
Find
替换范围
- 使用
TypeText
插入标记
使用 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."
我需要使用来自 Access 数据库的文本动态生成 word 文档 table。这里需要注意的是,一些来自数据库的文本需要修改为 MergeFields。我目前正在使用 Interop.Word(VBA 宏)和 VB.NET 来生成文档。
到目前为止我的步骤是这样的:
- 拉取标准 .docx 模板
- 使用来自 table 的预定义填充文本填充模板
- 通过用实际合并字段替换部分填充文本来添加 MergeFields
- 附加数据源并执行邮件合并
经过测试,我注意到我不能简单地将 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)。
你遗漏了很多细节,所以我会用一些笼统的术语来回答这个问题。
你想做的事绝对可以实现。立即想到两个可能的解决方案:
- 使用
Find
替换范围
- 使用
TypeText
插入标记
使用 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."