【问题标题】:Mail merge started by VBA in Access let Word open Database againAccess中VBA启动的邮件合并让Word再次打开数据库
【发布时间】:2010-10-11 11:00:47
【问题描述】:

我正在开发一个 Access 数据库,该数据库会生成一些邮件,这些邮件是从 Access 数据库中的 VBA 代码调用的邮件合并。问题是,如果我打开一个新的 Word 文档并启动邮件合并 (VBA),Word 会打开同一个 Access 数据库(已经打开)来获取数据。有什么办法可以防止这种情况发生吗?以便使用已经打开的数据库实例?

经过一些测试,我得到一个奇怪的行为:如果我打开 Access 数据库持有 SHIFT 键邮件合并不会打开同一数据库的其他 Access 实例。如果我在不持有密钥的情况下打开 Access 数据库,则会得到所描述的行为。

我的邮件合并 VBA 代码:

On Error GoTo ErrorHandler

    Dim word As word.Application
    Dim Form As word.Document

    Set word = CreateObject("Word.Application")
    Set Form = word.Documents.Open("tpl.doc")

    With word
        word.Visible = True

        With .ActiveDocument.MailMerge
            .MainDocumentType = wdMailingLabels
            .OpenDataSource Name:= CurrentProject.FullName, ConfirmConversions:=False, _
                ReadOnly:=False, LinkToSource:=False, AddToRecentFiles:=False, _
                PasswordDocument:="", PasswordTemplate:="", WritePasswordDocument:="", _
                WritePasswordTemplate:="", Revert:=False, Format:=wdOpenFormatAuto, _
                SQLStatement:="[MY QUERY]", _
                SQLStatement1:="", _
                SubType:=wdMergeSubTypeWord2000, OpenExclusive:=False
            .Destination = wdSendToNewDocument
            .Execute
            .MainDocumentType = wdNotAMergeDocument
        End With
    End With

    Form.Close False
    Set Form = Nothing

    Set word = Nothing

Exit_Error:
    Exit Sub
ErrorHandler:
    word.Quit (False)
    Set word = Nothing
    ' ...
End Sub

整个事情都是用 Access / Word 2003 完成的。

更新 #1 如果有人能告诉我使用或不使用 SHIFT 键打开 Access 之间的确切区别,这也会有所帮助。如果可以编写一些 VBA 代码来启用“功能”,那么如果在没有 SHIFT 键的情况下打开数据库,它至少会“模拟”它。

干杯, 格雷戈尔

【问题讨论】:

  • 在按住 Shift 键的同时打开 Access 可防止自动执行宏和其他自动启动的事情发生。请注意,您可以禁用这种可能性。谷歌“AllowBypassKey”。
  • 我不想禁用它,我更喜欢需要它...这真的很奇怪:按住 Shift 键,一切正常。不持有它,Word 将在每次新的 Access 实例时打开,并从那里打开 Access 数据库...
  • 您有一个 .OpenDataSource 命令但没有 .Close,可以吗? (我对vba这个词不熟悉)。否则,我认为db再打开一次也没问题,只要你事后关掉就行了。
  • 看起来没问题。没有任何 Close 方法。向 Word 模板添加一些代码的问题是,它还可能关闭用户自己打开的 Access 实例。因此,据我所知,无法确定何时关闭/不关闭数据源。此外,我没有看到任何事件可以在 Word 中挂钩这样的关闭方法
  • 这就是为什么输出文本文件并将其用于 Access 邮件合并通常更容易的原因。我经常使用简化版:tek-tips.com/faqs.cfm?fid=5088

标签: ms-access vba mailmerge


【解决方案1】:

当我进行邮件合并时,我通常会从 Access 导出一个 .txt 文件,然后将邮件合并数据源设置为该文件。这样Access只涉及导出查询,然后告诉Word文档通过自动化完成工作,大致如下:

    Public Function MailMergeLetters() 
           Dim pathMergeTemplate As String
            Dim sql As String
            Dim sqlWhere As String
            Dim sqlOrderBy As String


'Get the word template from the Letters folder  

            pathMergeTemplate = "C:\MyApp\Resources\Letters\"

'This is a sort of "base" query that holds all the mailmerge fields
'Ie, it defines what fields will be merged.

            sql = "SELECT * FROM MailMergeExportQry" 

            With Forms("MyContactsForm")

' Filter and order the records you want
'Very much to do for you

            sqlWhere = GetWhereClause()
            sqlOrderBy = GetOrderByClause()

            End With

' Build the sql string you will use with this mail merge

            sql = sql & sqlWhere & sqlOrderBy & ";"

'Create a temporary QueryDef to hold the query

                Dim qd As DAO.QueryDef
                Set qd = New DAO.QueryDef
                    qd.sql = sql
                    qd.Name = "mmexport"

                    CurrentDb.QueryDefs.Append qd

' Export the data using TransferText

                        DoCmd.TransferText _
                            acExportDelim, , _
                            "mmexport", _
                            pathMergeTemplate & "qryMailMerge.txt", _
                            True
' Clear up
                    CurrentDb.QueryDefs.Delete "mmexport"

                    qd.Close
                Set qd = Nothing

'------------------------------------------------------------------------------
'End Code Block:
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
'Start Code Block:
'OK. Access has built the .txt file.
'Now the Mail merge doc gets opened...
'------------------------------------------------------------------------------

                Dim appWord As Object
                Dim docWord As Object

                Set appWord = CreateObject("Word.Application")

                    appWord.Application.Visible = True

' Open the template in the Resources\Letters folder:

                    Set docWord = appWord.Documents.Add(Template:=pathMergeTemplate & "MergeLetters.dot")

'Now I can mail merge without involving currentproject of my Access app

                        docWord.MailMerge.OpenDataSource Name:=pathMergeTemplate & "qryMailMerge.txt", LinkToSource:=False

                    Set docWord = Nothing

                Set appWord = Nothing

'------------------------------------------------------------------------------
'End Code Block:
'------------------------------------------------------------------------------

        Finally:
            Exit Function

        Hell:
            MsgBox Err.Description & " " & Err.Number, vbExclamation, APPHELP

        On Error Resume Next
            CurrentDb.QueryDefs.Delete "mmexport"

            qd.Close
            Set qd = Nothing

            Set docWord = Nothing
            Set appWord = Nothing

            Resume Finally

        End Function

要使用它,您需要设置 Resources\Letters 子文件夹并将您的 mailmerge 模板 word 文件放在那里。您还需要使用 Access 应用程序中的字段定义进行“基本”查询(在示例中,它称为 MailMergeExportQry。但您可以将其命名为任何名称。

您还需要弄清楚您将执行哪些过滤和排序。在示例中,这表示为

sqlWhere = GetWhereClause()
sqlOrderBy = GetOrderByClause

一旦你了解了这些东西,这就是高度可重用的。

【讨论】:

  • 这就像 Remou 的评论,它完成了工作。谢谢你。因为你不是第一个有这个想法的人,所以我只是赞成它。谢谢!
  • 另一方面,它是其他人可以使用的有效解决方案(在 SO 中需要大量格式化......)。通过接受它,您可以使 Stackoverflow 变得更好。即,您可以轻松找到问题答案的地方。 5 点既不是这里也不是那里,但使 stackoverflow 更好不是。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多