【问题标题】:Copy data from unread email and mark as read从未读电子邮件中复制数据并标记为已读
【发布时间】:2021-10-17 18:04:17
【问题描述】:

我想将 Outlook RSS 源中的“未读电子邮件”复制到 Excel。这些复制的电子邮件应在 Outlook 中标记为“已读”。

下面的代码返回

无效的过程调用或参数。

Private Sub run_btn_Click()
    Dim OutlookApp As Outlook.Application
    Dim OutlookNamespace As Namespace
    Dim Folder As MAPIFolder
    Dim OutlookMail As Variant

    Dim i As Integer

    Set OutlookApp = New Outlook.Application
    Set OutlookNamespace = OutlookApp.GetNamespace("MAPI")
    Set Folder = OutlookNamespace.GetDefaultFolder(olfolderrssfeeds).Folders("Folder Name")

    If Folder.items.Restrict("[UnRead] = True").Count = 0 Then
        MsgBox "No Unread email", vbInformation, "Congratulation!"
    End If

    i = 1

    For Each OutlookMail In Folder.items.Restrict("[UnRead] = True")
        Range("eMail_subject").Offset(i, 0).Value = Left(OutlookMail.Subject, 11)
        Range("eMail_date").Offset(i, 0).Value = OutlookMail.ReceivedTime
        Range("eMail_text").Offset(i, 0).Value = OutlookMail.Body        
        i = i + 1
    Next OutlookMail

    If Folder.items.Restrict("[Unread] = True") Then
        Folder.items.UnRead = False
        Folder.items.Save
    End If

    Set Folder = Nothing
    Set OutlookNamespace = Nothing
    Set OutlookApp = Nothing
End Sub

【问题讨论】:

  • 调试器到底停在哪里?
  • 真的有一个叫“文件夹名”的文件夹吗?另外,最后一次 Restrict 调用是否应该测试 Restrict.Count?

标签: excel vba email outlook


【解决方案1】:

我无法重现您看到的确切错误,而且我不知道错误在哪里。但是,以下对我有用,从 Excel 2013 运行以控制 Outlook 2013。请参阅<== 标记。

Option Explicit    ' <== Always include this at the top of every module

Private Sub run_btn_Click()
    Dim OutlookApp As Outlook.Application
    Dim OutlookNamespace As Namespace
    Dim Folder As MAPIFolder
    Dim OutlookMail As Object   ' <== Doesn't need to be Variant

    Dim rowIndex As Integer     ' <== rename from `i` to `rowIndex` for clarity

    Set OutlookApp = New Outlook.Application
    Set OutlookNamespace = OutlookApp.GetNamespace("MAPI")
    Set Folder = OutlookNamespace.GetDefaultFolder(olFolderRssFeeds)        ' <==
        ' After you call GetDefaultFolder, you already have a folder - you don't
        ' need to call .Folder() on it.

    If Folder.UnReadItemCount = 0 Then      ' <== Don't need to use Restrict for unread-item count
        MsgBox "No Unread email", vbInformation, "Congratulation!"
    End If

    rowIndex = 1

    For Each OutlookMail In Folder.Items.Restrict("[UnRead] = True")
        Range("eMail_subject").Offset(rowIndex, 0).Value = Left(OutlookMail.Subject, 11)
        Range("eMail_date").Offset(rowIndex, 0).Value = OutlookMail.ReceivedTime
        Range("eMail_text").Offset(rowIndex, 0).Value = OutlookMail.Body

        MarkItemReadIfEmail OutlookMail     ' <== Mark each one read as it's processed

        rowIndex = rowIndex + 1
    Next OutlookMail

    'If Folder.UnReadItemCount > 0 Then     ' <== already did this in the loop above
    '    Folder.Items.UnRead = False        '     so don't need to do it here.
    '    Folder.Items.Save
    'End If

    Set Folder = Nothing
    Set OutlookNamespace = Nothing
    Set OutlookApp = Nothing
End Sub

Private Sub MarkItemReadIfEmail(obj As Object)
    Dim mail As PostItem    ' **Edit** - was originally MailItem

    ' Find out if it's a mail item
    Set mail = Nothing
    On Error Resume Next
    Set mail = obj
    On Error GoTo 0

    If mail Is Nothing Then Exit Sub

    ' It's an email, so mark it.
    mail.UnRead = False
    mail.Save
End Sub

Sub MarkItemReadIfEmail 是一种将电子邮件标记为已读的谨慎方式。实际上,我对 Outlook 对象模型的了解还不够,无法知道 Folder.Items 总是为 RSS-feed 文件夹返回 edit PostItem。因此,在将每个项目视为PostItem 之前,我会检查它是否真的是一个。

【讨论】:

  • 非常感谢您的回答和修改!对于 [Set Folder = OutlookNamespace.GetDefaultFolder(olFolderRssFeeds)],我在 RSS 源中有两个文件夹,因此我必须保留 .Folders()。但是,电子邮件仍然显示为“未读”,没有从 Excel 弹出任何错误消息,我不确定是不是因为我使用的是 Outlook 和 Excel 2016...
  • @QuincyChan 奇怪!如果在If mail Is Nothing ... 行上设置断点,objmail 的类型是什么? (您可以为每个添加 Watch,Watch 窗口中的 Type 列会显示给您。)可能它们不是 MailItems,在这种情况下,UnRead=False 行将永远不会运行。解决方法是将Dim mail As MailItem 中的MailItem 更改为obj 的类型。
  • @QuincyChan 尝试将MailItem 更改为PostItem 看看会发生什么。我发现 this forum thread 说 RSS-feed 项目是 PostItem 实例。
  • @cxwStrange........我有 13 个未读的 RSS 提要,但只有 7 个被导出到 Excel 并在 Outlook 中标记为已读...... Outlook 中剩余 6 个未读...... ..
  • @QuincyChan 所以这 6 个可能不是 PostItem 实例。使用 Watch 窗口查看它们是什么,然后将这些选项添加到 MarkItemReadIfEmail 或其副本。或者,您可以将PostItem 更改为Object,但是当您点击不支持UnReadSave 的项目时,您将收到错误消息。如果您仍然有问题,请提出一个新问题,链接到此问题并显示您的最新代码。也许有更多 Outlook 经验的人会有更多的想法。祝你好运!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-15
  • 2016-03-12
  • 1970-01-01
  • 2012-09-30
  • 1970-01-01
  • 2014-10-09
  • 1970-01-01
相关资源
最近更新 更多