【问题标题】:Search Outlook Emails from VBA从 VBA 搜索 Outlook 电子邮件
【发布时间】:2018-07-20 21:23:21
【问题描述】:

给定的代码成功运行。它在 Outlook 已发送邮件文件夹中搜索电子邮件主题。搜索基于特定时间段内的特定日期进行。例如,下面的代码查找 2018 年 7 月 20 日上午 12:00 到晚上 11:59 之间发送的电子邮件标题“周五发送的测试电子邮件”。

除了我现有的搜索条件外,我如何过滤发送给特定用户的电子邮件。我想检查 [To] 字段。如果 [To] 有收件人 x@email.com、y@email.com 或 z@email.com,则不要返回搜索结果。如果 [To] 部分没有以下任一电子邮件,则搜索应返回“Yes. Email found”:x@email.com、y@email.com 或 z@email.com。

 Public Function is_email_sent()
    Dim olApp As Object
    Dim olNs As Object
    Dim olFldr As Object
    Dim olItms As Object
    Dim objItem As Object

    On Error Resume Next
    Set olApp = CreateObject("Outlook.Application")

    Set olNs = olApp.GetNamespace("MAPI")
    Set olFldr = olNs.Folders("myemail@example.com").Folders("Sent Items")

    Set olItms = olFldr.Items
    Set objItem = olItms.Restrict("[Subject] = ""Test Email Sent on Friday"" And [SentOn] >= ""7/20/2018 12:00 AM"" AND [SentOn] <= ""7/20/2018 11:59 PM""")
    If objItem.Count = 0 Then
        MsgBox "No. Email not found"
    Else
        MsgBox "Yes. Email found"
    End If

    Set olApp = Nothing
    Set olNs = Nothing
    Set olFldr = Nothing
    Set olItms = Nothing
    Set objItem = Nothing
End Function

【问题讨论】:

标签: excel vba ms-access outlook


【解决方案1】:

这可能不是您所寻求的方法,但如果您将项目引用添加到 Outlook,您可以使用本机数据类型而不是将所有内容都视为对象,这样 Intellisense 就可以成为您最好的朋友。

优点是,您无需在Restrict 方法中猜测查询字符串是什么,而是可以简单地循环遍历所有邮件项目,然后使用本机属性来查找您要查找的邮件。这是您在上面确定的规格的示例。

 Public Function is_email_sent()
    Dim olApp As Outlook.Application
    Dim olNs As Outlook.Namespace
    Dim olFldr As Outlook.Folder
    Dim olItms As Outlook.Items
    Dim objItem As Outlook.MailItem
    Dim recipients() As String
    Dim found As Boolean

    found = False

    On Error Resume Next
    Set olApp = New Outlook.Application

    Set olNs = olApp.GetNamespace("MAPI")
    Set olFldr = olNs.Folders("myemail@example.com").Folders("Sent Items")

    For Each objItem In olFldr.Items
      If objItem.Subject = "Test Email Sent on Friday" And _
        objItem.SentOn >= DateSerial(2018, 7, 20) And _
        objItem.SentOn < DateSerial(2018, 7, 21) Then

          If InStr(objItem.To, "x@email.com") = 0 And _
            InStr(objItem.To, "y@email.com") = 0 And _
            InStr(objItem.To, "z@email.com") = 0 Then

              found = True
              Exit For

          End If

      End If
    Next objItem

当然,你可以去掉类引用,它仍然可以工作,但就像我说的,让 Intellisense 成为你的朋友。

有一些按顺序进行的微优化(即预先声明日期,而不是在每次循环迭代中运行 DateSerial),但这是为了证明我的观点的概念性想法。

【讨论】:

  • 太棒了。谢谢汉本。我将测试您的解决方案并及时更新。我对代码的唯一担心是我可能需要遍历 1000 封电子邮件才能找到我正在寻找的标题。由于我将搜索最近的电子邮件,因此我将按 SentOn 以降序对电子邮件进行排序,然后遍历项目。
  • 代码运行成功,但是由于发送的项目太多,速度太慢。我会想办法优化它。
  • 我敢打赌,如果您仍然使用 Restrict 方法将结果获取到子集,那么 for each 循环将从那里运行得非常快。如果您需要示例,请告诉我。
【解决方案2】:

您可以使用限制检查已找到的项目中的地址。

Public Function is_email_sent()

    Dim olApp As Object
    Dim olNs As Object

    Dim olFldr As Object
    Dim olFldrItms As Object    ' Outlook.Items

    Dim objResItems As Object   ' Outlook.Items
    Dim objResItem As Object

    'On Error Resume Next       ' Learn how to use this.

    Set olApp = CreateObject("Outlook.Application")

    Set olNs = olApp.GetNamespace("MAPI")
    Set olNs = GetNamespace("MAPI")

    Set olFldr = olNs.Folders("myemail@example.com").Folders("Sent Items")

    Set olFldrItms = olFldr.Items

    Set objResItems = olFldrItms.Restrict("[Subject] = ""Test Email Sent on Friday"" And [SentOn] >= ""7/20/2018 12:00 AM"" AND [SentOn] <= ""7/20/2018 11:59 PM""")

    If objResItems.count = 0 Then

        MsgBox "Email not found."

    Else

        For Each objResItem In objResItems

            Debug.Print objResItem.Subject
            Debug.Print objResItem.To

            If InStr(objResItem.To, "x@email.com") = 0 And _
              InStr(objResItem.To, "y@email.com") = 0 And _
              InStr(objResItem.To, "z@email.com") = 0 Then

                MsgBox "Email to " & objResItem.To & vbCr & vbCr & "No bad addresses."
                Exit For

            End If

            Debug.Print "At least one bad address in the mail."

        Next

    End If

    Set olApp = Nothing
    Set olNs = Nothing
    Set olFldr = Nothing

    Set olFldrItms = Nothing
    Set objResItems = Nothing

    Set objResItem = Nothing

End Function

【讨论】:

    【解决方案3】:

    解决办法

        Public Function is_email_sent()
            Dim olApp As Object
            Dim olNs As Object
            Dim olFldr As Object
            Dim olItms As Object
            Dim objItem As Object
    
            On Error Resume Next
            Set olApp = CreateObject("Outlook.Application")
    
            Set olNs = olApp.GetNamespace("MAPI")
            Set olFldr = olNs.Folders("myemail@example.com").Folders("Sent Items")
    
            Set olItms = olFldr.Items
            Set objItem = olItms.Restrict("[Subject] = ""Test Email Sent on Friday"" And [SentOn] >= ""7/20/2018 12:00 AM"" AND [SentOn] <= ""7/20/2018 11:59 PM""")
            If objItem.Count = 0 Then
                is_email_sent_out_to_business = False
            Else '*** Solution
                Dim o As Object
                For Each o In objItem
                    If Not (InStr(o.To, "x@email.com") > 0 Or InStr(o.To, "y@email.com") > 0) Then
                        MsgBox "Yes. Email found"
                        Exit For
                    Else
                        MsgBox "No. Email not found"
                    End If
                Next
            End If
    
            Set olApp = Nothing
            Set olNs = Nothing
            Set olFldr = Nothing
            Set olItms = Nothing
            Set objItem = Nothing
        End Function
    

    【讨论】:

    • On Error Resume Next 在这里没有任何好处。像这样的未来使用只会让你感到沮丧。您不会看到任何错误,这意味着您无法修复它们。 stackoverflow.com/a/31753321/1571407。如果要返回is_email_sent 中的值,则is_email_sent_out_to_business = False 应为is_email_sent = Falsestackoverflow.com/a/2781710/1571407 你也可能需要一个is_email_sent = True 在某个地方。
    猜你喜欢
    • 2016-06-24
    • 1970-01-01
    • 1970-01-01
    • 2015-10-02
    • 2022-01-01
    • 1970-01-01
    • 2022-11-09
    • 2018-03-25
    • 1970-01-01
    相关资源
    最近更新 更多