Home > Net >  VBA Loop Through Emails in Folder in Order
VBA Loop Through Emails in Folder in Order

Time:09-09

I am trying to loop over the emails in folder, download the attachments and move the message to a folder labelled "processed." I want every email in the folder to the Processed folder and only keep the attachment from the most recent email. I figured the easiest way to do this would be to just loop through them all and have the most recent go last, overwriting the attachment each time.

Code Snippet Below

  oOlInbNo.Items.Sort "[ReceivedTime]", True
    
    Do While oOlInbNo.Items.count > 0
    
    For Each MailItem In oOlInbNo.Items
           For Each atch In MailItem.Attachments
                 If Right(atch.Filename, 3) = "xls" Then
                    atch.SaveAsFile NewFileNameNo
                 End If
            Next atch
                
        MailItem.Move oOlInbNo.Folders("Processed")
     Next MailItem
    Loop

However, when I run this it processes emails in this order

August 31 September 6 September 1 September 2

I cannot figure out why Sept 6 is going out of order.

CodePudding user response:

Sort items not folder.items.

Set oOlInbNoItems = oOlInbNo.items
oOlInbNoItems.Sort "[ReceivedTime]", True

You may have to switch from For Each to a reverse For Next.

Option Explicit

Private Sub MoveItems_OldestFirst()

Dim oOlInbNo As Folder
Dim oOlInbNoItems As items

Dim oOlItem As Object
Dim oOlMailitem As MailItem

Dim atch As Attachment

Dim i As Long

Set oOlInbNo = Session.GetDefaultFolder(olFolderInbox)
Set oOlInbNoItems = oOlInbNo.items

oOlInbNoItems.Sort "[ReceivedTime]", True

If oOlInbNoItems.Count > 0 Then

    For i = oOlInbNoItems.Count To 1 Step -1
        
        If oOlInbNoItems(i).Class = olMail Then
            
            Set oOlMailitem = oOlInbNoItems(i)
            For Each atch In oOlMailitem.Attachments
                If Right(atch.fileName, 3) = "xls" Then
                    atch.SaveAsFile NewFileNameNo
                End If
            Next atch
                
            'Debug.Print oOlMailitem.ReceivedTime
            
            oOlMailitem.Move oOlInbNo.Folders("Processed")
                
        End If
        
    Next

End If

End Sub

CodePudding user response:

Each time you call the Items property of Outlook folders you get a new Items collection with an individual sorting order. You need to deal with the same collection instance if you want to preserve the order.

Dim folderItems as Outlook.Items

Set folderItems = oOlInbNo.Items

folderItems.Sort "[ReceivedTime]", False
Do While folderItems.count > 0  
   If folderItems.Item(0).Class = olMail Then
      Set oOlMailitem = folderItems.Item(0)

As you can see there is no need to have two loops - you can use a single one instead.

I figured the easiest way to do this would be to just loop through them all and have the most recent go last, overwriting the attachment each time.

Looping through all items in the folder is not really a good idea. You may better process items in small bunches, so you could leave the Outlook UI responsive.

Also you may consider using the Find/FindNext or Restrict methods of the Items class helpful. For example, you could find recent items with attachments and process only them for saving attached files on the disk. Other items you can simply move to another folder if required.

Read more about these methods in the articles I wrote for the technical blog:

  • Related