【问题标题】:How to Send an Email with a PDF attached with Outlook using MS Access VBA?如何使用 MS Access VBA 发送带有 Outlook 附件的 PDF 的电子邮件?
【发布时间】:2019-08-25 06:35:59
【问题描述】:

我正在使用 Access 2016 中的 Access 应用程序。该应用程序通过 DoCmd.OutputTo 方法输出到 PDF 文件。

我想将此 PDF 附件发送到我用代码构建的电子邮件中,或者打开带有附件的新 Outlook 电子邮件。

当我单击表单中触发包含我的子(位于单独的模块中)的代码的按钮时,电子邮件窗口永远不会显示,也不会发送电子邮件(取决于@987654324 的使用@ 与 .Send)。我也没有收到任何错误。

我认为还值得注意的是,调用创建 PDF 的模块内部的 sub 按预期工作。

我在 Windows 7 64 位计算机上运行 Access 2016 和 Outlook 2016,作为 Office 2016 Pro Plus 的一部分安装。 Office 套件是 32 位的。

模块和子 (电子邮件地址已编辑

Dim objEmail As Outlook.MailItem
Dim objApp As Outlook.Application

Set objApp = CreateObject("Outlook.Application")

Set objEmail = oApp.CreateItem(olMailItem)
With objEmail
    .Recipients.Add "email@domain.com"
    .Subject = "Invoice"
    .Body = "See Attached"
    .Attachments.Add DestFile
    .Display        
End With

子调用

MsgBox "Now saving the Invoice as a PDF"
strInvoiceNbr = Int(InvoiceNbr)
strWhere = "[InvoiceNbr]=" & Me!InvoiceNbr
strDocName = "Invoice Print One"
ScrFile = "Invoice Print One"
DestFile = "Inv" + strInvoiceNbr + " - " + Me.GetLastname + " - " + GetLocation
MsgBox DestFile, vbOKOnly

DoCmd.OpenForm strDocName, , , strWhere
Call ExportToPDF(SrcFile, DestFile, "INV")
Call EmailInvoice(DestFile)

基于 PDF 在模块文件的子文件中输出的事实,我应该在创建 PDF 的子文件中创建电子邮件(或调用子文件)吗?

注意:我在 Stack Overflow 上查看了 this accepted answer 以及许多其他网站。我的问题有所不同,因为我问的是为什么没有显示或发送消息,而不是如何像其他人一样构建和发送消息。

编辑: 如果 Outlook 已打开,则 Outlook 不会打开并且不会发生任何事情。

最后说明: 要添加已接受的答案,在 Access 的 VBA 编辑器中,您可能必须转到 Tools > References 并根据您的 Office/Outlook 版本启用 Microsoft Outlook 16.0 Object Library 或类似内容。

【问题讨论】:

  • Outlook 是否打开,运行时是否可见?
  • 未按预期工作时的基本规则:单步。你试过吗?您还需要消除所有不相关的代码:stackoverflow.com/help/mcve
  • 您的代码中是否有On Error Resume Next 可能会掩盖错误?
  • 看起来 DestFile 不包含完整的文件路径。如果文件路径无效且找不到文件,代码将出错。您必须有一个错误处理程序来捕获错误。分步调试。调试时禁用错误处理程序。
  • DestFile文件名的完整路径吗?

标签: vba ms-access outlook


【解决方案1】:

要传递完整路径,请尝试使用Function EmailInvoice

例子

Option Explicit
#Const LateBind = True
Const olFolderInbox As Long = 6

Public Sub ExportToPDF( _
           ByVal strSrcFileName As String, _
           ByVal strNewFileName As String, _
           ByVal strReportType As String _
                )

    Dim PathFile As String

    Dim strEstFolder As String
        strEstFolder = "c:\OneDrive\Estimates\"
    Dim strInvFolder As String
        strInvFolder = "c:\OneDrive\Invoices\"

    ' Export to Estimates or Invoices Folder based on passed parameter
    If strReportType = "EST" Then
        DoCmd.OutputTo acOutputForm, strSrcFileName, acFormatPDF, _
                       strEstFolder & strNewFileName & ".pdf", False, ""


        PathFile = strEstFolder & strNewFileName & ".pdf"


    ElseIf strReportType = "INV" Then
        DoCmd.OutputTo acOutputForm, strSrcFileName, acFormatPDF, _
                       strInvFolder & strNewFileName & ".pdf", False, ""


        PathFile = strEstFolder & strNewFileName & ".pdf"


    End If

    EmailInvoice PathFile ' call function

End Sub

Public Function EmailInvoice(FldrFilePath As String)

    Dim objApp As Object
    Set objApp = CreateObject("Outlook.Application")

    Dim objNS As Object
    Set objNS = olApp.GetNamespace("MAPI")

    Dim olFolder As Object
    Set olFolder = objNS.GetDefaultFolder(olFolderInbox)
        'Open inbox to prevent errors with security prompts
        olFolder.Display

    Dim objEmail As Outlook.MailItem
    Set objEmail = oApp.CreateItem(olMailItem)

    With objEmail
        .Recipients.Add "email@domain.com"
        .Subject = "Invoice"
        .Body = "See Attached"
        .Attachments.Add FldrFilePath
        .Display
    End With

End Function

【讨论】:

  • 是的,添加 PathFile = strEstFolder & strNewFileName & ".pdf" 可以解决我的文件路径问题。起初我传递的是文件名,然后我传递的是没有附加.pdf 的路径。
【解决方案2】:

您的问题可能与 Outlook 安全性有关。通常,Outlook 会显示一个弹出窗口,说明第 3 方应用程序正在尝试通过它发送电子邮件。你想允许还是不允许。但是,由于您以编程方式执行此操作,因此弹出窗口永远不会出现。以前有办法绕过这个。

在用户登录并打开 Outlook 时测试您的程序。看看行为上会不会有什么不同。如果确实出现了该弹出窗口,请在谷歌上搜索确切的消息,您可能会找到绕过它的方法。

【讨论】:

  • 虽然这值得赞赏,但这似乎不是问题。我尝试使用 Outlook 打开并加载配置文件和电子邮件,但没有任何反应。我没有收到任何类型的电子邮件窗口或错误。
  • 无论如何都要调查一下。他们可能已经完成了警告,但没有完成安全策略。我知道我过去花了很多时间想知道为什么我的电子邮件发送静默失败,直到我偶然发现一篇关于 Outlook 如何需要特殊权限才能以编程方式发送电子邮件的文章。
  • 在解决了文件路径的一些问题后,我现在已经加载了它,我看到了你所说的消息/警告。但是,我将研究这个主题来抑制这个警告,因为它会让用户感到沮丧。 support.office.com/en-us/article/… 提供了不错的信息。您还提到让 OL 打开..这是它现在工作的唯一方式。
  • 我让它在 Active Directory 环境中的客户站点上工作,并且可以访问组策略。否则,它可能是每个工作站和/或每个用户的一次性设置。
【解决方案3】:

您不使用 sendOject 的任何原因?

sendobject 的优点是您不受 Outlook 的限制,任何电子邮件客户端都可以使用。

所以,可以使用这段代码:

  Dim strTo   As String
  Dim strMessage    As String
  Dim strSubject    As String

  strTo = "abc@abc.com;def@def.com"

  strSubject = "Your invoice"
  strMessage = "Please find the invoice attached"

  DoCmd.SendObject acSendReport, "rptInvoice", acFormatPDF, _
        strTo, , , strSubject, strMessage

请注意,如果您需要过滤报告,请在运行发送对象之前先将其打开。当然,您在之后关闭报告(仅当您必须过滤并在之前打开报告时才需要 - 如果不提​​供过滤器,那么上面的代码就足够了,而不必先打开报告)。

不需要单独写出pdf文件,也不需要编写代码来附加生成的pdf。以上是一步完成,实际上是一行代码。

【讨论】:

  • 老实说,我根本没有使用sendObject,因为我没有完全意识到它,而且我对按照我在帖子中的方式构建电子邮件有点熟悉。至于我的方法仅限于 Outlook,这不是问题,因为用户在 Outlook 和 MS 生态系统中根深蒂固。至于单独写出,那是因为我需要将 PDF 也保存在目录中,而不仅仅是通过电子邮件发送出去。该目录是一个同步的 One Drive 文件夹。不过,我可能误解了你所说的。
  • 没问题。这只是一个可能的建议。它只让你“一次”,因此仅限于一个附件。这也是一个很好的方式来启动一个带有发送到电子邮件的空白电子邮件 - 其余的参数可以留空,所以它可以节省一些编码(一个很好的快速方式来启动一个准备好让用户填写的电子邮件)。但是,我承认我有一个很好的例程,我需要大多数电子邮件,因此我也创建了一个 Outlook 实例。因此,只需将此选项保留在您的技巧包中 - 它仍然很有用。
猜你喜欢
  • 1970-01-01
  • 2020-05-16
  • 2011-09-28
  • 1970-01-01
  • 2021-05-11
  • 2021-11-21
  • 2018-05-24
  • 2016-02-28
相关资源
最近更新 更多