Saving All Messages to the Hard Drive Using VBA

Last reviewed on April 1, 2013

Use this code to save messages with the date in the filename, retaining the Outlook file structure.

To save selected messages as PDF files, see Save Outlook email as a PDF

This code sample will save all messages in a specific Outlook folder (and any subfolders of the selected folder) on the hard drive at C:\Messages\, which is hard coded in the VBA. The messages will be in a subfolder of C:\Messages\, where the subfolder is named for the Outlook folder you selected. The drive path can be edited and you can save the messages directly to the upper level folder (Messages) by editing the following line to remove
StrFolder &

StrFolderPath = StrSavePath & StrFolder & "\"

The filename format is yyyymmdd_hhmmAM_subject.msg, as in:

20100422_0319PM_Inquiry.msg

The filename is set using this code:

StrFile = StrSaveFolder & StrReceived & "_" & StrName & ".msg"

Filenames are limited to 256 characters in length, with the subject trimmed if its too long.

If you leave the trailing slash off of the path, the folder will be created for you, in this folder name format: Messages.Inbox

The Function ArrangedDate(StrDateInput) controls the date formatting. If you want to change the date and time formats you'll do it in the function code.

The date format is stored in this string: StrDate = StrYear & StrMonth & StrDay. You can add change the order of the elements, or add spaces or (legal filename) characters using & " " & between the date elements. For example, StrDate = StrYear & "_" & StrMonth & "_" &  StrDay results in 2010_04_22_0319PM_Inquiry.msg

The time format is in  StrTime = Left(StrFullTime, 6) & StrAMPM . If you want to include seconds, use Left(StrFullTime, 8)

Note that it can take some time to run if the folder contains a lot of messages. Allow about 2 seconds per message, or about 15 minutes for 400 messages.

VBA Code

Click in the code area, press Ctrl+A to select all, Ctrl+C to copy then paste into Outlook's VBA editor. Instructions on using the editor are at How to use Outlook’s VBA Editor

Option Explicit
 
Sub SaveAllEmails_ProcessAllSubFolders()
     
    Dim i               As Long
    Dim j               As Long
    Dim n               As Long
    Dim StrSubject      As String
    Dim StrName         As String
    Dim StrFile         As String
    Dim StrReceived     As String
    Dim StrSavePath     As String
    Dim StrFolder       As String
    Dim StrFolderPath   As String
    Dim StrSaveFolder   As String
    Dim Prompt          As String
    Dim Title           As String
    Dim iNameSpace      As NameSpace
    Dim myOlApp         As Outlook.Application
    Dim SubFolder       As MAPIFolder
    Dim mItem           As MailItem
    Dim FSO             As Object
    Dim ChosenFolder    As Object
    Dim Folders         As New Collection
    Dim EntryID         As New Collection
    Dim StoreID         As New Collection
     
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set myOlApp = Outlook.Application
    Set iNameSpace = myOlApp.GetNamespace("MAPI")
    Set ChosenFolder = iNameSpace.PickFolder
    If ChosenFolder Is Nothing Then
GoTo ExitSub:
    End If
     
    
    StrSavePath = "c:\Messages\"
     
    Call GetFolder(Folders, EntryID, StoreID, ChosenFolder)
     
    For i = 1 To Folders.Count
        StrFolder = StripIllegalChar(Folders(i))
        n = InStr(3, StrFolder, "\") + 1
        StrFolder = Mid(StrFolder, n, 256)
        StrFolderPath = StrSavePath & StrFolder & "\"
        StrSaveFolder = Left(StrFolderPath, Len(StrFolderPath) - 1) & "\"
        If Not FSO.FolderExists(StrFolderPath) Then
            FSO.CreateFolder (StrFolderPath)
        End If
         
        Set SubFolder = myOlApp.Session.GetFolderFromID(EntryID(i), StoreID(i))
        On Error Resume Next
        For j = 1 To SubFolder.Items.Count
            Set mItem = SubFolder.Items(j)
            StrReceived = ArrangedDate(mItem.ReceivedTime)
            StrSubject = mItem.Subject
            StrName = StripIllegalChar(StrSubject)
            StrFile = StrSaveFolder & StrReceived & "_" & StrName & ".msg"
            StrFile = Left(StrFile, 256)
            mItem.SaveAs StrFile, 3
        Next j
        On Error GoTo 0
    Next i
     
ExitSub:
     
End Sub




 
Function StripIllegalChar(StrInput)
     
    Dim RegX            As Object
     
    Set RegX = CreateObject("vbscript.regexp")
     
    RegX.Pattern = "[\" & Chr(34) & "\!\@\#\$\%\^\&\*\(\)\=\+\|\[\]\{\}\`\'\;\:\<\>\?\/\,]"
    RegX.IgnoreCase = True
    RegX.Global = True
     
    StripIllegalChar = RegX.Replace(StrInput, "")
     
ExitFunction:
     
    Set RegX = Nothing
     
End Function
 
 
Function ArrangedDate(StrDateInput)
     
    Dim StrFullDate     As String
    Dim StrFullTime     As String
    Dim StrAMPM         As String
    Dim StrTime         As String
    Dim StrYear         As String
    Dim StrMonthDay     As String
    Dim StrMonth        As String
    Dim StrDay          As String
    Dim StrDate         As String
    Dim StrDateTime     As String
    Dim RegX            As Object
     
    Set RegX = CreateObject("vbscript.regexp")
     
    If Not Left(StrDateInput, 2) = "10" And _
    Not Left(StrDateInput, 2) = "11" And _
    Not Left(StrDateInput, 2) = "12" Then
        StrDateInput = "0" & StrDateInput
    End If
     
    StrFullDate = Left(StrDateInput, 10)
     
    If Right(StrFullDate, 1) = " " Then
        StrFullDate = Left(StrDateInput, 9)
    End If
     
    StrFullTime = Replace(StrDateInput, StrFullDate & " ", "")
     
    If Len(StrFullTime) = 10 Then
        StrFullTime = "0" & StrFullTime
    End If
     
    StrAMPM = Right(StrFullTime, 2)
    StrTime = Left(StrFullTime, 6) & StrAMPM
    StrYear = Right(StrFullDate, 4)
    StrMonthDay = Replace(StrFullDate, "/" & StrYear, "")
    StrMonth = Left(StrMonthDay, 2)
    StrDay = Right(StrMonthDay, Len(StrMonthDay) - 3)
    If Len(StrDay) = 1 Then
        StrDay = "0" & StrDay
    End If
    StrDate = StrYear & StrMonth & StrDay
    StrDateTime = StrDate & "_" & StrTime
    RegX.Pattern = "[\:\/\ ]"
    RegX.IgnoreCase = True
    RegX.Global = True
     
    ArrangedDate = RegX.Replace(StrDateTime, "")
     
ExitFunction:
     
    Set RegX = Nothing
     
End Function
 
Sub GetFolder(Folders As Collection, EntryID As Collection, StoreID As Collection, Fld As MAPIFolder)
     
    Dim SubFolder       As MAPIFolder
     
    Folders.Add Fld.FolderPath
    EntryID.Add Fld.EntryID
    StoreID.Add Fld.StoreID
    For Each SubFolder In Fld.Folders
        GetFolder Folders, EntryID, StoreID, SubFolder
    Next SubFolder
     
ExitSub:
     
    Set SubFolder = Nothing
     
End Sub
 
 
Function BrowseForFolder(Optional OpenAt As String) As String
     
    Dim ShellApp As Object
     
    Set ShellApp = CreateObject("Shell.Application"). _
    BrowseForFolder(0, "Please choose a folder", 0, OpenAt)
     
    On Error Resume Next
    BrowseForFolder = ShellApp.self.Path
    On Error GoTo 0
     
    Select Case Mid(BrowseForFolder, 2, 1)
    Case Is = ":"
        If Left(BrowseForFolder, 1) = ":" Then
            BrowseForFolder = ""
        End If
    Case Is = "\"
        If Not Left(BrowseForFolder, 1) = "\" Then
            BrowseForFolder = ""
        End If
    Case Else
        BrowseForFolder = ""
    End Select
     
ExitFunction:
     
    Set ShellApp = Nothing
     
End Function

Written by

Diane Poremsky
A Microsoft Outlook Most Valuable Professional (MVP) since 1999 and involved in IT support since 1985, Diane is the author of several books and video training CDs and online training classes for Microsoft Outlook. You can find her helping people online in Outlook Forums as well as in the Microsoft Answers and TechNet forums.