vba - For Each 循环 : Some items get skipped when looping through Outlook mailbox to delete items

标签 vba for-loop outlook

我想开发这样的 VBA 代码:

  • 遍历邮箱中的所有电子邮件项目
  • 如果有任何类型的其他项目,请说“日历邀请”跳过该项目。
  • 找出带附件的电子邮件
  • 如果附件有“.xml”扩展名和特定标题,则将其保存到目录中,否则继续搜索
  • 执行第 4 步后,将所有包含 .xml 附件的电子邮件放入“已删除邮件”文件夹,并通过循环删除该文件夹中的所有电子邮件。

  • 代码完美运行,除了;
    例如
  • 您的邮箱中收到了 8 封附有“.xml”文件的电子邮件。
  • 运行代码
  • 您将看到 8 个项目中只有 4 个成功处理,其他 4 个保留在它们的位置。
  • 如果您再次运行代码,现在将成功处理 2 个项目,另外 2 个保留在您的邮箱中。

  • 问题:运行代码后,它应该处理所有文件并在每次运行中将它们全部删除而不是其中的一半。我希望它在一次运行中处理所有项目。

    顺便说一句,每次打开 Outlook 时都会运行此代码。
    Private Sub Application_Startup()
    'Initializing Application_Startup forces the macros to be accessible from other offic apps
    
    'Process XML emails
    
    Dim InboxMsg As Object
    
    Dim DeletedItems As Outlook.Folder
    Dim MsgAttachment As Outlook.Attachment
    Dim ns As Outlook.NameSpace
    Dim Inbox As Outlook.Folder
    
    Dim fPathTemp As String
    Dim fPathXML_SEM As String
    Dim fPathEmail_SEM As String
    Dim i As Long
    Dim xmlDoc As New MSXML2.DOMDocument60
    Dim xmlTitle As MSXML2.IXMLDOMNode
    Dim xmlSupNum As MSXML2.IXMLDOMNode
    
        'Specify the folder where the attachments will be saved
        fPathTemp = "some directory, doesn't matter"
        fPathXML_SEM = "some directory, doesn't matter"
        fPathEmail_SEM = "some directory, doesn't matter"
    
        'Setup Outlook
        Set ns = GetNamespace("MAPI")
        Set Inbox = ns.Folders.Item("mailbox-name").Folders("Inbox")
        Set DeletedItems = ns.Folders.Item("mailbox-name").Folders("Deleted Items")
    
    
        'Loop through all Items in Inbox, find the xml attachements and process if they are the matching reponses
        'On Error Resume Next
        For Each InboxMsg In Inbox.Items
            If InboxMsg.Class = olMail Then 'if it is a mail item
    
                'Check for xml attachement
                For Each MsgAttachment In InboxMsg.Attachments
    
                    If Right(MsgAttachment.DisplayName, 3) = "xml" Then
    
                        'Load XML and test for the title of the file
                        MsgAttachment.SaveAsFile fPathTemp & MsgAttachment.FileName
                        xmlDoc.Load fPathTemp & MsgAttachment.FileName
                        Set xmlTitle = xmlDoc.SelectSingleNode("//title")
                        Select Case xmlTitle.Text
                            Case "specific title"
                                'Get supplier number
                                Set xmlSupNum = xmlDoc.SelectSingleNode("//supplierNum")
                                'Save the XML to the correct folder
                                MsgAttachment.SaveAsFile fPathXML_SEM & xmlSupNum.Text & "_" & Format(Date, "yyyy-mm-dd") & ".xml"
                                'Save the email to the correct folder
                                InboxMsg.SaveAs fPathEmail_SEM & xmlSupNum.Text & "_" & Format(Date, "yyyy-mm-dd") & ".msg"
                                'Delete the message
                                InboxMsg.Move DeletedItems
                            Case Else
    
                        End Select
                        'Delete the temp file
                        On Error Resume Next
                        Kill fPathTemp & MsgAttachment.FileName
                        On Error GoTo 0
                        'Unload xmldoc
                        Set xmlDoc = Nothing
                        Set xmlTitle = Nothing
                        Set xmlSupNum = Nothing
                    End If
                Next
            End If
        Next
    
        'Loop through deleted items and delete
        For Each InboxMsg In DeletedItems.Items
            InboxMsg.Delete
        Next
    
        'Clean-up
        Set InboxMsg = Nothing
        Set DeletedItems = Nothing
        Set MsgAttachment = Nothing
        Set ns = Nothing
        Set Inbox = Nothing
        i = 0
    
    End Sub
    

    最佳答案

    可能的原因:当您这样做时 InboxMsg.Move ,收件箱中移动的邮件之后的所有邮件都会在列表中上升一个位置。所以你最终会跳过其中的一些。这是 VBA 的一个主要烦恼 For Each构造(它似乎也不一致)。

    可能的解决方案:更换

    For Each InboxMsg In Inbox.Items
    


    For i = Inbox.Items.Count To 1 Step -1 'Iterates from the end backwards
        Set InboxMsg = Inbox.Items(i)
    

    这样你就从列表的末尾向后迭代。当您将消息移至已删除项目时,列表中的以下项目何时增加一个并不重要,因为您已经处理了它们。

    关于vba - For Each 循环 : Some items get skipped when looping through Outlook mailbox to delete items,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10725068/

    相关文章:

    VBA(Microsoft Excel)用字符串替换数组

    vba - 值更改时添加带值的行

    ms-access - 在 VBA 中获取查询类型属性

    java - 为什么列表在 python 和 Java 中表现不同?

    python - 如何优化循环和条件语句?

    outlook - 关于何时在 Outlook 插件中使用 EWS 与 Rest API 的持久传奇

    vba - 如何替换 VBA 中的空格字符?

    python - 可以像在 Python 中一样在 MATLAB 中完成并行遍历吗?

    excel - 将消息发送到非 Outlook 客户端时,VBA HTML 格式丢失

    html - HTML 电子邮件中的可折叠表格 (Outlook 2007-2010)