【发布时间】:2021-10-22 05:13:20
【问题描述】:
我正在尝试制作一个 excel 宏来将我的 Outlook 文件夹中的电子邮件导入到指定日期范围内的 excel 文件中(对于收到的电子邮件)。这个过程必须定期进行。因此,我需要继续在 Excel 工作表中的现有电子邮件下方添加电子邮件。
我得到了它的工作,但是,我的日期范围似乎不起作用。如果我只添加“发件人日期”,它会起作用并从指定的“发件人日期”导入所有电子邮件,直到最后收到的电子邮件。但是如果我指定一个日期范围,那么宏就根本不起作用,尽管它没有显示任何错误/调试。它只是告诉我导入已完成。在我的工作表中,单元格 L1 包含“起始日期”,单元格 L2 包含“截止日期”。
我该如何纠正这个问题?
Sub Download_Emails()
Application.ScreenUpdating = False
Dim OutlookApp As Outlook.Application
Dim OutlookNamespace As Namespace
Dim Folder As MAPIFolder
Dim OutlookMail As Variant
Dim objOwner As Outlook.Recipient
Dim i As Integer
Dim olItems As Object
Dim olItem As Object
Dim LastRow As Long
LastRow = Cells(Rows.Count, "A").End(xlUp).Row
Set OutlookApp = New Outlook.Application
Set OutlookNamespace = OutlookApp.GetNamespace("MAPI")
Set objOwner = OutlookNamespace.CreateRecipient("xxxxx.com")
objOwner.Resolve
'Allows the user to select the desired folder from which the emails are to be imported
If objOwner.Resolved Then
Set Folder = GetObject("", "Outlook.Application").GetNamespace("MAPI").PickFolder
End If
i = LastRow
LastRow = LastRow + 1
For Each OutlookMail In Folder.Items
If TypeName(OutlookMail) = "MailItem" Then
'Sets the date from which the user wants to import the emails from
If CDate(OutlookMail.ReceivedTime) >= Range("L1").Value And CDate(OutlookMail.ReceivedTime) <= Range("L2").Value Then
'Imports email subject, received date and time, sender's name, and the email body into the excel file
Range("A1").Offset(i, 0) = OutlookMail.Subject
Range("B1").Offset(i, 0) = OutlookMail.ReceivedTime
Range("C1").Offset(i, 0) = OutlookMail.SenderName
'Range("D1").Offset(i, 0) = OutlookMail.Body
i = i + 1
'If the email date set is crossed, then to to line number 3
Else: GoTo 3
End If
End If
Next OutlookMail
Set Folder = Nothing
Set OutlookNamespace = Nothing
Set OutlookApp = Nothing
'Do not wrap text of the imported emails
3 Sheet1.Cells.WrapText = False
Application.ScreenUpdating = True
'Pop up saying the import is complete
MsgBox "Email importing is done!", vbOKOnly + vbInformation
End Sub
根据建议,我使用以下代码进行了修改和测试。单元格 L1 的日期为 12/08/2021,单元格 L2 的日期为 16/08/2021。现在,代码会选择忽略晚于 2021 年 8 月 16 日的电子邮件的日期范围,但是,它不会获取 2021 年 8 月 16 日的电子邮件。它仅在 2021 年 8 月 15 日之前获取电子邮件。收件箱按“最新优先”排序,有日期为 12/08/2021 和 16/08/2021 的电子邮件。
Sub Download_Emails()
Application.ScreenUpdating = False
Dim OutlookApp As Outlook.Application
Dim OutlookNamespace As Namespace
Dim Folder As MAPIFolder
Dim OutlookMail As Variant
Dim objOwner As Outlook.Recipient
Dim i As Integer
Dim olItems As Object
Dim olItem As Object
Dim LastRow As Long
LastRow = Cells(Rows.Count, "A").End(xlUp).Row
Set OutlookApp = New Outlook.Application
Set OutlookNamespace = OutlookApp.GetNamespace("MAPI")
Set objOwner = OutlookNamespace.CreateRecipient("xxxxxx.com") 'Set the Outlook mailbox name
objOwner.Resolve
'Allows the user to select the desired folder from which the emails are to be imported
If objOwner.Resolved Then
Set Folder = GetObject("", "Outlook.Application").GetNamespace("MAPI").PickFolder
End If
i = LastRow
LastRow = LastRow + 1
For Each OutlookMail In Folder.Items
If TypeName(OutlookMail) = "MailItem" Then
'Sets the date from which the user wants to import the emails from
If CDate(OutlookMail.ReceivedTime) > Range("L2").Value Then
'Do nothing
ElseIf CDate(OutlookMail.ReceivedTime) >= Range("L1").Value Then ‘L1 has date 12/08/2021 and L2 has date 16/08/2021
'Imports email subject, received date and time, sender's name, and the email body into the excel file
Range("A1").Offset(i, 0) = OutlookMail.Subject
Range("B1").Offset(i, 0) = OutlookMail.ReceivedTime
Range("C1").Offset(i, 0) = OutlookMail.SenderName
'Range("D1").Offset(i, 0) = OutlookMail.Body
i = i + 1
'If the email date range is crossed, then exit For loop
Else: Exit For
End If
End If
Next OutlookMail
Set Folder = Nothing
Set OutlookNamespace = Nothing
Set OutlookApp = Nothing
'Do not wrap text of the imported emails
Sheet1.Cells.WrapText = False
Application.ScreenUpdating = True
'Pop up saying the import is complete
MsgBox "Email importing is done!", vbOKOnly + vbInformation
End Sub
由于我发现从最旧到最新获取电子邮件最适合我,因此我尝试更改代码。但是,它退出循环而不做任何事情。 我的邮箱从最旧到最新排序。我有 2019 年至今的电子邮件。我想获取以下给定范围内的电子邮件。 单元格 L1 的起始日期为 (28/08/2020)。 单元格 L2 有 To date (30/08/2020)。
这是我使用的代码。由于宏在第一个实例中退出循环,我认为我在逻辑中遗漏了一些东西。
另外,与其指示用户将他们的邮箱从最旧到最新排序,我们可以强制 VBA 这样做吗? I tried OutlookItems.Sort [ReceivedTime], true 但收到错误“需要对象”。现在我在代码中做了注释。
Sub Download_Emails()
Application.ScreenUpdating = False
Dim OutlookApp As Outlook.Application
Dim OutlookNamespace As Namespace
Dim Folder As MAPIFolder
Dim OutlookMail As Variant
Dim objOwner As Outlook.Recipient
Dim i As Integer
Dim olItems As Object
Dim olItem As Object
Dim LastRow As Long
Dim ToDt As Date
LastRow = Cells(Rows.Count, "A").End(xlUp).Row
ToDt = Range("L2").Value + 1
Set OutlookApp = New Outlook.Application
Set OutlookNamespace = OutlookApp.GetNamespace("MAPI")
Set objOwner = OutlookNamespace.CreateRecipient("xxxxxxxxxx.com") 'Set the Outlook mailbox name
objOwner.Resolve
'OutlookItems.Sort [ReceivedTime], true (results in error Object required)
'Allows the user to select the desired folder from which the emails are to be imported
If objOwner.Resolved Then
Set Folder = GetObject("", "Outlook.Application").GetNamespace("MAPI").PickFolder
End If
i = LastRow
LastRow = LastRow + 1
For Each OutlookMail In Folder.Items
If TypeName(OutlookMail) = "MailItem" Then
'Sets the date from which the user wants to import the emails from
If CDate(OutlookMail.ReceivedTime) < Range("L1").Value Then 'From Date
'Do nothing
ElseIf CDate(OutlookMail.ReceivedTime) < ToDt Then 'To Date
'Imports email subject, received date and time, sender's name, and the email body into the excel file
Range("A1").Offset(i, 0) = OutlookMail.Subject
Range("B1").Offset(i, 0) = OutlookMail.ReceivedTime
Range("C1").Offset(i, 0) = OutlookMail.SenderName
'Range("D1").Offset(i, 0) = OutlookMail.Body
i = i + 1
'If the email date range is crossed, then exit For loop
Else: Exit For
End If
End If
Next OutlookMail
Set Folder = Nothing
Set OutlookNamespace = Nothing
Set OutlookApp = Nothing
'Do not wrap text of the imported emails
Sheet1.Cells.WrapText = False
Application.ScreenUpdating = True
'Pop up saying the import is complete
MsgBox "Email importing is done!", vbOKOnly + vbInformation
End Sub
【问题讨论】:
-
您的代码在发现一封不符合您的日期条件的邮件后立即退出循环...
-
@TimWilliams 非常感谢您的建议!我尝试删除该
Else: GoTo 3,但随后宏将永远运行,因为我猜它会检查包含 8000 封电子邮件的整个邮箱。是否有机会在给定范围内获取宏接收电子邮件? -
查找:行标签可以是任何以字母开头并以冒号 (:) 结尾的字符组合。行标签不区分大小写,必须从第一列开始。 注意以字母开头,以冒号结尾。此外,您应该将标签向上移动几行,紧跟在
Next OutlookMail之后,以关闭那些Folder... -
假设邮件按“最新优先”排序,
L2表示最后收到日期,L1表示第一个收到日期,RD 表示收到日期,那么逻辑是:if RD > L2 then do_nothing else if RD >= L1 then get_mail_data else stop_looping. -
您的第一个测试(如果接收时间 > L2 然后什么也不做)是正确的。下一个测试是错误的,你应该只测试`IF received time > L1 THEN copy the email ELSE exit the search。总共有 3 种情况:1) 电子邮件比 L2 新 - 不感兴趣。 2) 电子邮件比 L1 新 - 很有趣(您无需再次针对 L2 进行测试,您已经知道它比 L2 旧) 3) 电子邮件以及后续电子邮件较旧 - 不感兴趣,退出搜索。