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) in a folder you select on the hard drive. The messages will be in a subfolder of the selected folder, where the subfolder is named for the Outlook folder you selected.
Note: if you select a subfolder of a top-level folder, for example, a subfolder of the Inbox, folder named Inbox needs to exist in path on the hard drive.
The filename format is yyyymmdd_hhmm_subject.msg, as in:
20100422_0319_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.
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 Dim StrSavePath As String 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 StrFolder As String Dim StrSaveFolder As String Dim StrFolderPath 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 BrowseForFolder StrSavePath 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 = Format(mItem.ReceivedTime, "YYYYMMDD-hhmm") 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 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(StrSavePath As String, Optional OpenAt As String) As String Dim objShell As Object Dim objFolder ' As Folder Dim enviro enviro = CStr(Environ("USERPROFILE")) Set objShell = CreateObject("Shell.Application") Set objFolder = objShell.BrowseForFolder(0, "Please choose a folder", 0, enviro & "\Documents\") StrSavePath = objFolder.self.Path On Error Resume Next On Error GoTo 0 ExitFunction: Set objShell = Nothing End Function
How to use this macro
First: You need to have macro security set to low during testing. The macros will not work otherwise.
To check your macro security in Outlook 2010 or 2013, go to File, Options, Trust Center and open Trust Center Settings, and change the Macro Settings. In Outlook 2007 and older, it’s at Tools, Macro Security.
After you test the macro and see that it works, you can either leave macro security set to low or sign the macro.
Open the VBA Editor by pressing Alt+F11 on your keyboard.
- Right click on Project1 and choose Insert > Module
- Copy and paste the macro into the new module.
More information as well as screenshots are at How to use the VBA Editor
More Information
- How to Save Email in Windows File System
- Import Messages from File System into Outlook Folders
- OWA: Save Messages to My Documents
- Save a Message as HTML and Delete the (Annoying) Folder
- Save email message as text file
- Save Outlook Email as a PDF
- Save Selected Email Message as .msg File
- Saving All Messages to the Hard Drive Using VBA
Thank you for a very useful and smoothly running macro!
Love peace and respect!
This script is great, exactly what I was looking for. Thank you! I will note I found 2 issues that I'll try to fix. You may already know about these. If you cancel when asked to select a save folder it will error out rather than handling the exception. If you select a folder in outlook to save and that folder is not a top level folder, ie InBox\NewFolder the script will error out saying the path does not exist. This looks to be because its trying to save in inbox\newfolder initially and hasnt yet created the inbox folder first so it cannot create the folder newfolder and thus it doesnt exist yet. Here's where that happens, I made a few mods so I'm not sure the line number, its around 40-45 and at this point strfolderpath = inbox\newfolder what it needs to do is create inbox then create newfolder in 2 seperate actions. If Not FSO.FolderExists(StrFolderPath) Then FSO.CreateFolder (StrFolderPath) End If Neither are a big deal to me, no impact, but thought I'd mention it. If you're looking for improvements it would be really cool if it gave a progress status of some sort. For me it just puts… Read more »
How can I modify the above to get items off a Microsoft exchange server? Code works as long as its not in exchange server.
It should work with email in any account in Outlook. It won't work with Outlook on the web.
I get the error "Run-time error '76': Path not found. "
Any ideas of how to fix this?
At what point in the macro does it return this error? It means there is an error in the path - you can add one of these lines right before that line to see what it is using for the path. Which line you use depends on which line it errors on.
msgbox StrSaveFolder
or
msgbox StrFile
hello, i tried to apply this but I keep receiving the error message.
Hi Diane, so grateful for your work, but when i run it, is said the macros disables even after i changed the settings in trust centre to accept all macros. Would there be any way to fix it? thanks!
This is after you restarted outlook? Are these new macros - or did you previously use them with a digital signature?
Hello Diane,
it is a great work and very useful for me.
I am thankful for your work.
But i would like to choose also sub-folders to save the Emails in this folder to any other folder on the harddrive. Is it possible?
So you want to save the email in just one folder to the hard drive? This one saves the selected messages to a folder of your choice.
Save Selected Email Message as .msg File (slipstick.com)
No. I mean i want to choose and save sub-folders, not Parent folder. Is it possible?
Hi. I am working on archivation tool for Outlook. Only problem (or actual) is that I am not able to Save encrypted emails. Your script will skip such mails. It is not possible to extract ReceivedTime nor SenderName from such encrypted Items. I could not find solution for this anywhere on the internet. Do you think it is somehow possible? Thanks.
Diane. This code is Awesome! Thank you so much!