为什么我的 MergeField 名称是唯一通过 Excel 中的 MailMerge 提取到 PDF 的数据?
Why are my MergeField names the only data pulling through to a PDF via MailMerge in Excel?
我目前正在尝试使用 VBA 中的以下代码将 table 中的数据导入邮件合并 word 文档,然后将各个合并保存为 pdf。代码几乎做到了这一点,但是当我 运行 我的 excel sheet 上的宏时,pdf 的保存只带来来自 word 文档的合并域名称,而不是数据本身。
关于从这里我可以去哪里有什么想法吗?我目前使用的是 Office 2016。
Sub RunMailMerge()
Dim objWord
Dim objDoc
Dim StrFolder As String, StrName As String, i As Long, j As Long
Dim strWorkbookName As String: strWorkbookName = ThisWorkbook.FullName
Const StrNoChr As String = """*./\:?|": StrName = "Easy.docx"
StrFolder = ThisWorkbook.Path & Application.PathSeparator
If Dir(StrFolder & strDocNm) = "" Then Exit Sub
Set objWord = CreateObject("Word.Application")
Set objDoc = objWord.Documents.Add
With objWord
'Disable alerts to prevent an SQL prompt
.DisplayAlerts = wdAlertsNone
'Display Word - change this to False once the code is running correctly
.Visible = False
'Open the mailmerge main document - set Visible:=True for testing
Set objWord = .Documents.Open(Filename:=StrFolder & StrName, ReadOnly:=True,
AddToRecentFiles:=False, Visible:=False)
With objWord
With .MailMerge
'Define the mailmerge type
.MainDocumentType = wdFormLetters
'Define the output
.Destination = wdSendToNewDocument
.SuppressBlankLines = False
'Connect to the data source
.OpenDataSource Name:=strWorkbookName, _
ReadOnly:=True, _
LinkToSource:=False, _
AddToRecentFiles:=False, _
Format:=wdOpenFormatAuto, _
Connection:="User ID=Admin;DataSource=strWorkbookName;" & _
"Mode=Read;Extended Properties=""HDR=YES;IMEX=1"";", _
SQLStatement:="SELECT * FROM `Sheet1 SQLStatement:=", _
SubType:=wdMergeSubTypeAccess
'Process all eligible records
For i = 1 To .DataSource.RecordCount
With .DataSource
.FirstRecord = i
.LastRecord = i
.ActiveRecord = i
'Exit if the field to be used for the filename is empty
If Trim(.DataFields("Tenant")) = "" Then Exit For
'StrFolder = .DataFields("Folder") & Application.PathSeparator
StrName = .DataFields("Tenant")
End With
.Execute Pause:=True
'Clean up the filename
For j = 1 To Len(StrNoChr)
StrName = Replace(StrName, Mid(StrNoChr, j, 1), "_")
Next
StrName = "Letter - " & Trim(StrName)
'Save as a PDF
objWord.SaveAs Filename:=StrFolder & StrName & ".pdf", _
FileFormat:=wdFormatPDF, AddToRecentFiles:=False
Next i
'Disconnect from the data source
.MainDocumentType = wdNotAMergeDocument
End With
'Close the mailmerge main document
.Close False
End With
Call CloseAll
Set wdDoc = Nothing: Set wdApp = Nothing
End With
End Sub
Sub CloseAll()
Dim objWord
Dim objDoc
Set objWord = CreateObject("Word.Application")
Set objDoc = objWord.Documents.Add
objWord.ActiveDocument.Close SaveChanges:=wdDoNotSaveChanges
End Sub
您为什么要尝试通过 VBA 代码来推动邮件合并?您应该能够 A) 在 Excel 或 Access 中设置数据,B) 在 Word 中设置模板并将其连接到数据源,C) 运行 邮件合并。除非你做的事情真的非常非常花哨,否则应该不需要 VBA.
因为似乎是某个虐待狂强迫你以艰难的方式做事,看来你的错误很可能在这里:
Connection:="User ID=Admin;DataSource=strWorkbookName;" & _
"Mode=Read;Extended Properties=""HDR=YES;IMEX=1"";", _
SQLStatement:="SELECT * FROM `Sheet1
SQLStatement:=", _
SubType:=wdMergeSubTypeAccess
首先:
Connection:="User ID=Admin;DataSource=strWorkbookName;" & _
应该是
Connection:="User ID=Admin;DataSource=" & strWorkbookName & ";" & _
其次,您的 SQLStatement
参数未终止,我很确定 "Sheet1"
(不确定为什么在那里有额外的反引号)不是引用 "table"(即工作表)从 Excel 工作簿中选择时。 IIRC,应该是"WorkBook$WorkSheet"
,所以这个:
SQLStatement:="SELECT * FROM `Sheet1
应该是这样的:
SQLStatement:="SELECT * FROM " & strWorkbookName & "$Sheet1", _
该行后面是字符串的末尾
SQLStatement:=", _
其中 是发送到 Excel 中的数据库引擎的实际 SQL 字符串的 部分。那是行不通的。
按照我的理解,那一行应该是:
Connection:="User ID=Admin;DataSource=" & strWorkbookName & ";" & _
"Mode=Read;Extended Properties=""HDR=YES;IMEX=1"";", _
SQLStatement:="SELECT * FROM " & strWorkbookName & "$Sheet1", _
SubType:=wdMergeSubTypeAccess
您可能需要稍微调整一下,但我认为这会让您走上正轨。
该代码基本上是我在其他地方发布的代码的副本(例如 https://www.mrexcel.com/forum/general-excel-discussion-other-questions/713478-word-2007-2010-mail-merge-save-individual-pdf-files-post4796480.html#post4796480),但是为什么要添加对 CloseAll 的调用是个谜。
尽管如此,很明显您还部分修改了用于后期绑定的代码,方法是替换:
Dim wdApp As New Word.Application, wdDoc As Word.Document
与:
Dim objWord
Dim objDoc
...
Set objWord = CreateObject("Word.Application")
Set objDoc = objWord.Documents.Add
如果您自始至终都坚持使用早期绑定,代码就可以正常工作。不过现在,您修改后的代码混合使用了后期绑定和命名的 Word 常量,这实际上只适用于早期绑定。您需要使代码完全适应后期绑定或恢复为完全早期绑定的代码。
我目前正在尝试使用 VBA 中的以下代码将 table 中的数据导入邮件合并 word 文档,然后将各个合并保存为 pdf。代码几乎做到了这一点,但是当我 运行 我的 excel sheet 上的宏时,pdf 的保存只带来来自 word 文档的合并域名称,而不是数据本身。
关于从这里我可以去哪里有什么想法吗?我目前使用的是 Office 2016。
Sub RunMailMerge()
Dim objWord
Dim objDoc
Dim StrFolder As String, StrName As String, i As Long, j As Long
Dim strWorkbookName As String: strWorkbookName = ThisWorkbook.FullName
Const StrNoChr As String = """*./\:?|": StrName = "Easy.docx"
StrFolder = ThisWorkbook.Path & Application.PathSeparator
If Dir(StrFolder & strDocNm) = "" Then Exit Sub
Set objWord = CreateObject("Word.Application")
Set objDoc = objWord.Documents.Add
With objWord
'Disable alerts to prevent an SQL prompt
.DisplayAlerts = wdAlertsNone
'Display Word - change this to False once the code is running correctly
.Visible = False
'Open the mailmerge main document - set Visible:=True for testing
Set objWord = .Documents.Open(Filename:=StrFolder & StrName, ReadOnly:=True,
AddToRecentFiles:=False, Visible:=False)
With objWord
With .MailMerge
'Define the mailmerge type
.MainDocumentType = wdFormLetters
'Define the output
.Destination = wdSendToNewDocument
.SuppressBlankLines = False
'Connect to the data source
.OpenDataSource Name:=strWorkbookName, _
ReadOnly:=True, _
LinkToSource:=False, _
AddToRecentFiles:=False, _
Format:=wdOpenFormatAuto, _
Connection:="User ID=Admin;DataSource=strWorkbookName;" & _
"Mode=Read;Extended Properties=""HDR=YES;IMEX=1"";", _
SQLStatement:="SELECT * FROM `Sheet1 SQLStatement:=", _
SubType:=wdMergeSubTypeAccess
'Process all eligible records
For i = 1 To .DataSource.RecordCount
With .DataSource
.FirstRecord = i
.LastRecord = i
.ActiveRecord = i
'Exit if the field to be used for the filename is empty
If Trim(.DataFields("Tenant")) = "" Then Exit For
'StrFolder = .DataFields("Folder") & Application.PathSeparator
StrName = .DataFields("Tenant")
End With
.Execute Pause:=True
'Clean up the filename
For j = 1 To Len(StrNoChr)
StrName = Replace(StrName, Mid(StrNoChr, j, 1), "_")
Next
StrName = "Letter - " & Trim(StrName)
'Save as a PDF
objWord.SaveAs Filename:=StrFolder & StrName & ".pdf", _
FileFormat:=wdFormatPDF, AddToRecentFiles:=False
Next i
'Disconnect from the data source
.MainDocumentType = wdNotAMergeDocument
End With
'Close the mailmerge main document
.Close False
End With
Call CloseAll
Set wdDoc = Nothing: Set wdApp = Nothing
End With
End Sub
Sub CloseAll()
Dim objWord
Dim objDoc
Set objWord = CreateObject("Word.Application")
Set objDoc = objWord.Documents.Add
objWord.ActiveDocument.Close SaveChanges:=wdDoNotSaveChanges
End Sub
您为什么要尝试通过 VBA 代码来推动邮件合并?您应该能够 A) 在 Excel 或 Access 中设置数据,B) 在 Word 中设置模板并将其连接到数据源,C) 运行 邮件合并。除非你做的事情真的非常非常花哨,否则应该不需要 VBA.
因为似乎是某个虐待狂强迫你以艰难的方式做事,看来你的错误很可能在这里:
Connection:="User ID=Admin;DataSource=strWorkbookName;" & _
"Mode=Read;Extended Properties=""HDR=YES;IMEX=1"";", _
SQLStatement:="SELECT * FROM `Sheet1
SQLStatement:=", _
SubType:=wdMergeSubTypeAccess
首先:
Connection:="User ID=Admin;DataSource=strWorkbookName;" & _
应该是
Connection:="User ID=Admin;DataSource=" & strWorkbookName & ";" & _
其次,您的 SQLStatement
参数未终止,我很确定 "Sheet1"
(不确定为什么在那里有额外的反引号)不是引用 "table"(即工作表)从 Excel 工作簿中选择时。 IIRC,应该是"WorkBook$WorkSheet"
,所以这个:
SQLStatement:="SELECT * FROM `Sheet1
应该是这样的:
SQLStatement:="SELECT * FROM " & strWorkbookName & "$Sheet1", _
该行后面是字符串的末尾
SQLStatement:=", _
其中 是发送到 Excel 中的数据库引擎的实际 SQL 字符串的 部分。那是行不通的。
按照我的理解,那一行应该是:
Connection:="User ID=Admin;DataSource=" & strWorkbookName & ";" & _
"Mode=Read;Extended Properties=""HDR=YES;IMEX=1"";", _
SQLStatement:="SELECT * FROM " & strWorkbookName & "$Sheet1", _
SubType:=wdMergeSubTypeAccess
您可能需要稍微调整一下,但我认为这会让您走上正轨。
该代码基本上是我在其他地方发布的代码的副本(例如 https://www.mrexcel.com/forum/general-excel-discussion-other-questions/713478-word-2007-2010-mail-merge-save-individual-pdf-files-post4796480.html#post4796480),但是为什么要添加对 CloseAll 的调用是个谜。
尽管如此,很明显您还部分修改了用于后期绑定的代码,方法是替换:
Dim wdApp As New Word.Application, wdDoc As Word.Document
与:
Dim objWord
Dim objDoc
...
Set objWord = CreateObject("Word.Application")
Set objDoc = objWord.Documents.Add
如果您自始至终都坚持使用早期绑定,代码就可以正常工作。不过现在,您修改后的代码混合使用了后期绑定和命名的 Word 常量,这实际上只适用于早期绑定。您需要使代码完全适应后期绑定或恢复为完全早期绑定的代码。