为什么我的 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 常量,这实际上只适用于早期绑定。您需要使代码完全适应后期绑定或恢复为完全早期绑定的代码。