1
votes

I am trying to import details of every email (sender, received time, subject etc.) in my Inbox into an Excel file. I have code that works fine for a specific folder within the Inbox but my Inbox has several subfolders, and these subfolders also have subfolders.

After much trial and error I have managed to import details of all subfolders under the Inbox. However the code does not import the emails from the 2nd tier of subfolders and it also skips the emails that are still in the Inbox itself. I have searched this site and others but cannot find the code to loop through all folders and subfolders of an Inbox.

For example I have an Inbox with subfolders Reports, Pricing and Projects. The Report subfolder has subfolders called Daily, Weekly and Monthly. I can import the emails in Reports but not in Daily, Weekly and Monthly.

My code as it stands is below:

Sub SubFolders()

Dim olMail As Variant
Dim aOutput() As Variant
Dim lCnt As Long
Dim xlSh As Excel.Worksheet
Dim olApp As Outlook.Application
Dim olNs As Folder
Dim olParentFolder As Outlook.MAPIFolder
Dim olFolderA As Outlook.MAPIFolder
Dim olFolderB As Outlook.MAPIFolder

Set olApp = New Outlook.Application
Set olNs = olApp.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox)

Set olParentFolder = olNs
ReDim aOutput(1 To 100000, 1 To 5)

For Each olFolderA In olParentFolder.Folders
    For Each olMail In olFolderA.Items
    If TypeName(olMail) = "MailItem" Then
    On Error Resume Next
        lCnt = lCnt + 1
        aOutput(lCnt, 1) = olMail.SenderEmailAddress
        aOutput(lCnt, 2) = olMail.ReceivedTime
        aOutput(lCnt, 3) = olMail.Subject
        aOutput(lCnt, 4) = olMail.Sender
        aOutput(lCnt, 5) = olMail.To

    End If
    Next
Next

Set xlApp = New Excel.Application
Set xlSh = xlApp.Workbooks.Add.Sheets(1)

xlSh.Range("A1").Resize(UBound(aOutput, 1), UBound(aOutput, 2)).Value = aOutput
xlApp.Visible = True

End Sub
1
Thanks. I used the code given in the link and it imports everything in Outlook. While this is useful it gives too much information. I was hoping that I could specify a folder (such as the Inbox) and import everything from this and it's subfolders. Do you know if it is possible to modify the above code to achieve this?Colin Torpey

1 Answers

1
votes

From this question Can I iterate through all Outlook emails in a folder including sub-folders?

Replace your attempt to iterate the folders ...

For Each olFolderA In olParentFolder.Folders
    For Each olMail In olFolderA.Items
    If TypeName(olMail) = "MailItem" Then
    On Error Resume Next
        lCnt = lCnt + 1
        aOutput(lCnt, 1) = olMail.SenderEmailAddress
        aOutput(lCnt, 2) = olMail.ReceivedTime
        aOutput(lCnt, 3) = olMail.Subject
        aOutput(lCnt, 4) = olMail.Sender
        aOutput(lCnt, 5) = olMail.To
    End If
    Next
Next

...using the idea of recursion described in the currently accepted answer.

Private Sub processFolder(ByVal oParent As Outlook.MAPIFolder)
    Dim oFolder As Outlook.MAPIFolder
    Dim oMail As Outlook.MailItem

    For Each oMail In oParent.Items

    'Get your data here ...

    Next

    If (oParent.Folders.Count > 0) Then
        For Each oFolder In oParent.Folders
            processFolder oFolder   ' <--- no brackets around oFolder
        Next
    End If
End Sub

The fleshed out second answer shows how to declare variables outside of the code to pass values.

Option Explicit

Dim aOutput() As Variant
Dim lCnt As Long

Sub SubFolders()
'
' Code for Outlook versions 2007 and subsequent
' Declare with Folder rather than MAPIfolder
'
Dim xlApp As Excel.Application
Dim xlSh As Excel.Worksheet

Dim olNs As Namespace
Dim olParentFolder As Folder

Set olNs = GetNamespace("MAPI")
Set olParentFolder = olNs.GetDefaultFolder(olFolderInbox)

lCnt = 0
ReDim aOutput(1 To 100000, 1 To 5)

ProcessFolder olParentFolder

On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
On Error GoTo 0
If xlApp Is Nothing Then Set xlApp = CreateObject("Excel.Application")

Set xlSh = xlApp.Workbooks.Add.Sheets(1)

xlSh.range("A1").Resize(UBound(aOutput, 1), UBound(aOutput, 2)).Value = aOutput
xlApp.Visible = True

ExitRoutine:
    Set olNs = Nothing
    Set olParentFolder = Nothing
    Set xlApp = Nothing
    Set xlSh = Nothing

End Sub

Private Sub ProcessFolder(ByVal oParent As Folder)

Dim oFolder As Folder
Dim oMail As Object

For Each oMail In oParent.Items

    If TypeName(oMail) = "MailItem" Then
        lCnt = lCnt + 1
        aOutput(lCnt, 1) = oMail.SenderEmailAddress
        aOutput(lCnt, 2) = oMail.ReceivedTime
        aOutput(lCnt, 3) = oMail.Subject
        aOutput(lCnt, 4) = oMail.Sender
        aOutput(lCnt, 5) = oMail.To
    End If

Next

If (oParent.Folders.count > 0) Then
    For Each oFolder In oParent.Folders
        ProcessFolder oFolder
    Next
End If

End Sub