Export Outlook Folders to the File System


 

I stumbled across a question on Experts-Exchange asking if there’s a way to copy/move an Outlook folder to a folder in the file system. The author would like to drag-and-drop the Outlook folder to the file system folder, but notes that while Outlook allows you to drag a message from Outlook to the file system it does not allow you to do the same with a folder. While I’m not aware of any way to do this via dragging and dropping, it’s easy enough to script a solution that allows a user to select a folder and have it copied/moved to the file system. Here’s my solution.

Using this solution the user starts by selecting an Outlook folder, then run one of two macros: one that copies the folder to the file system, or one that moves it to the file system (copies and then deletes the Outlook folder). Once triggered, the code begins by prompting the user for the file system folder to export to. If the user selects a folder, then the code creates a new folder under the target folder and gives it the same name as the Outlook folder. Next, the code copies the contents of the Outlook folder to the new file system folder, saving each item in .msg format. Finally, if the user selected to move the Outlook folder, then the code deletes the selected folder from Outlook. The solution also handles multiple levels of folders. If a folder has sub-folders, then the code copies/moves them to the file system too. If the user opts to move a folder with sub-folders, then the code deletes them too when it deletes the parent folder. Please keep that in mind.

Instructions.

Follow these instructions to add the code to Outlook.

  1. Start Outlook
  2. Press ALT + F11 to open the Visual Basic Editor
  3. If not already expanded, expand Microsoft Office Outlook Objects
  4. If not already expanded, expand Modules
  5. Select an existing module (e.g. Module1) by double-clicking on it or create a new module by right-clicking Modules and selecting InsertModule.
  6. Copy the code from the code snippet box and paste it into the right-hand pane of Outlook’s VB Editor window
  7. Click the diskette icon on the toolbar to save the changes
  8. Close the VB Editor
'On the next line edit the starting folder as desired.  If you leave it blank, then the starting folder will be the local computer.
Const STARTING_FOLDER = ""
 
Dim objFSO As Object
 
Sub CopyOutlookFolderToFileSystem()
    ExportController "Copy"
End Sub
 
Sub MoveOutlookFolderToFileSystem()
    ExportController "Move"
End Sub
 
Sub ExportController(strAction As String)
    Dim olkFld As Outlook.MAPIFolder, strPath As String
    strPath = SelectFolder(STARTING_FOLDER)
    If strPath = "" Then
        MsgBox "You did not select a folder.  Export cancelled.", vbInformation + vbOKOnly, "Export Outlook Folder"
    Else
        Set objFSO = CreateObject("Scripting.FileSystemObject")
        Set olkFld = Application.ActiveExplorer.CurrentFolder
        ExportOutlookFolder olkFld, strPath
        If LCase(strAction) = "move" Then olkFld.Delete
    End If
    Set olkFld = Nothing
    Set objFSO = Nothing
End Sub
 
Sub ExportOutlookFolder(ByVal olkFld As Outlook.MAPIFolder, strStartingPath As String)
    Dim olkSub As Outlook.MAPIFolder, olkItm As Object, strPath As String, strMyPath As String, strSubejct As String, intCount As Integer
    strPath = strStartingPath & "\" & olkFld.Name
    objFSO.CreateFolder strPath
    For Each olkItm In olkFld.Items
        strSubject = RemoveIllegalCharacters(olkItm.Subject)
        strFilename = strSubject & ".msg"
        intCount = 0
        Do While True
            strMyPath = strPath & "\" & strFilename
            If objFSO.FileExists(strMyPath) Then
                intCount = intCount + 1
                strFilename = strSubject & " (" & intCount & ").msg"
            Else
                Exit Do
            End If
        Loop
        olkItm.SaveAs strMyPath, olMSG
    Next
    For Each olkSub In olkFld.Folders
        ExportOutlookFolder olkSub, strPath
    Next
    Set olkFld = Nothing
    Set olkItm = Nothing
End Sub
 
Function SelectFolder(varStartingFolder As Variant) As String
    ' This function is a modified version of the SelectFolder function written by Rob van der Woude (http://www.robvanderwoude.com/vbstech_ui_selectfolder.php)
 
    ' Standard housekeeping
    Dim objFolder As Object, objShell As Object
     
    ' Custom error handling
    On Error Resume Next
 
    ' Create a dialog object
    Set objShell = CreateObject("Shell.Application")
    Set objFolder = objShell.BrowseForFolder(0, "Select the folder you want to export to", 0, varStartingFolder)
 
    ' Return the path of the selected folder
    If TypeName(objFolder) <> "Nothing" Then SelectFolder = objFolder.self.Path
 
    ' Standard housekeeping
    Set objFolder = Nothing
    Set objShell = Nothing
    On Error GoTo 0
End Function
 
Function RemoveIllegalCharacters(strValue As String) As String
    ' Purpose: Remove characters that cannot be in a filename from a string.'
    ' Written: 4/24/2009'
    ' Author:  BlueDevilFan'
    ' Outlook: All versions'
    RemoveIllegalCharacters = strValue
    RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, "<", "")
    RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, ">", "")
    RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, ":", "")
    RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, Chr(34), "'")
    RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, "/", "")
    RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, "\", "")
    RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, "|", "")
    RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, "?", "")
    RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, "*", "") End Function 

Using the Code.

  1. Select an Outlook folder.
  2. Run either the CopyOutlookFolderToFileSystem or the MoveOutlookFolderToFileSystem macro depending on whether you want to copy/move the folder to the file system.

Adding Buttons to Run the Macro with a Single Click

If you want to run the macro with a single click, then you’ll need to add toolbar buttons for each macro in Outlook 2007 or buttons on the Quick Access Toolbar (QAT) for Outlook 2010.

Outlook 2007. Follow these instructions to add toolbar buttons that runs each macro.

Outlook 2010. Follow these instructions to add the macros to the QAT.

Revisions.

Revision 1.

A reader named Chris Robinson suggested a couple of changes, which this revision implements. Specifically, Chris suggested changing

  • The file date/time to match that of the original message instead of using the date/time the message was exported.
  • The file name to include the sender’s name

Using this version the file name format is now

[From] Sender’s Name [Subject] Subject of the Message

'On the next line edit the starting folder as desired.  If you leave it blank, then the starting folder will be the local computer.
Const STARTING_FOLDER = ""
 
Dim objFSO As Object
 
Sub CopyOutlookFolderToFileSystem()
    ExportController "Copy"
End Sub
 
Sub MoveOutlookFolderToFileSystem()
    ExportController "Move"
End Sub
 
Sub ExportController(strAction As String)
    Dim olkFld As Outlook.MAPIFolder, strPath As String
    strPath = SelectFolder(STARTING_FOLDER)
    If strPath = "" Then
        MsgBox "You did not select a folder.  Export cancelled.", vbInformation + vbOKOnly, "Export Outlook Folder"
    Else
        Set objFSO = CreateObject("Scripting.FileSystemObject")
        Set olkFld = Application.ActiveExplorer.CurrentFolder
        ExportOutlookFolder olkFld, strPath
        If LCase(strAction) = "move" Then olkFld.Delete
    End If
    Set olkFld = Nothing
    Set objFSO = Nothing
End Sub
 
Sub ExportOutlookFolder(ByVal olkFld As Outlook.MAPIFolder, strStartingPath As String)
    Dim olkSub As Outlook.MAPIFolder, olkItm As Object, strPath As String, strMyPath As String, strSubejct As String, intCount As Integer
    strPath = strStartingPath & "\" & olkFld.Name
    objFSO.CreateFolder strPath
    For Each olkItm In olkFld.Items
        strSubject = "[From] " & olkItm.SenderName & " [Subject] " & RemoveIllegalCharacters(olkItm.Subject)
        strFilename = strSubject & ".msg"
        intCount = 0
        Do While True
            strMyPath = strPath & "\" & strFilename
            If objFSO.FileExists(strMyPath) Then
                intCount = intCount + 1
                strFilename = strSubject & " (" & intCount & ").msg"
            Else
                Exit Do
            End If
        Loop
        olkItm.SaveAs strMyPath, olMSG
        ChangeTimeStamp strMyPath, olkItm.ReceivedTime
    Next
    For Each olkSub In olkFld.Folders
        ExportOutlookFolder olkSub, strPath
    Next
    Set olkFld = Nothing
    Set olkItm = Nothing
End Sub
 
Function SelectFolder(varStartingFolder As Variant) As String
    ' This function is a modified version of the SelectFolder function written by Rob van der Woude (http://www.robvanderwoude.com/vbstech_ui_selectfolder.php)
 
    ' Standard housekeeping
    Dim objFolder As Object, objShell As Object
     
    ' Custom error handling
    On Error Resume Next
 
    ' Create a dialog object
    Set objShell = CreateObject("Shell.Application")
    Set objFolder = objShell.BrowseForFolder(0, "Select the folder you want to export to", 0, varStartingFolder)
 
    ' Return the path of the selected folder
    If TypeName(objFolder) <> "Nothing" Then SelectFolder = objFolder.self.Path
 
    ' Standard housekeeping
    Set objFolder = Nothing
    Set objShell = Nothing
    On Error GoTo 0
End Function
 
Function RemoveIllegalCharacters(strValue As String) As String
    ' Purpose: Remove characters that cannot be in a filename from a string.'
    ' Written: 4/24/2009'
    ' Author:  BlueDevilFan'
    ' Outlook: All versions'
    RemoveIllegalCharacters = strValue
    RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, "<", "")
    RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, ">", "")
    RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, ":", "")
    RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, Chr(34), "'")
    RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, "/", "")
    RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, "\", "")
    RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, "|", "")
    RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, "?", "")
    RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, "*", "")
End Function

Sub ChangeTimeStamp(strFile As String, datStamp As Date)
    Dim objShell As Object, objFolder As Object, objFolderItem As Object, varPath As Variant, varName As Variant
    varName = Mid(strFile, InStrRev(strFile, "\") + 1)
    varPath = Mid(strFile, 1, InStrRev(strFile, "\"))
    Set objShell = CreateObject("Shell.Application")
    Set objFolder = objShell.NameSpace(varPath)
    Set objFolderItem = objFolder.ParseName(varName)
    objFolderItem.ModifyDate = CStr(datStamp)
    Set objShell = Nothing
    Set objFolder = Nothing
    Set objFolderItem = Nothing
End Sub
Advertisements

91 comments on “Export Outlook Folders to the File System

  1. I’m using Outlook 2010. I copied from Rev 1 but when running, it doesn’t get past this line: objFSO.CreateFolder strPath. Initially gave me ‘Object required’. Added Dim As Object and now I get ‘Object Variable or With block variable not set’. Any ideas?

    • Hi, deharvy.

      Glad you have a fix, but that shouldn’t have been necessary. The object in question is created on line 20 of the code.

  2. Hi David,

    Thanks for the article. When attempting to use Rev1 code, I’m getting Run-time error ‘430’: Class does not support Automation or does not support expected interface on this line:
    strSubject = “[From] ” & olkItm.SenderName & ” [Subject] ” & RemoveIllegalCharacters(olkItm.Subject). The inbox folder and another folder are created on the local drive and a few messages copied before the error occurs. I checked over the References and that seems to be in order. Any ideas on a resolution? Thanks!

    • Hi, Chris.

      My best guess is that there’s a report item (e.g. read receipt, non-delivery report) in the folder. Report items don’t have a sender name property. When I built the solution I didn’t include code to handle reports. I can add that if you like, or you can try removing report items from the folder and see if that solves the problem.

    • David,
      Thanks so much for sharing this! It is a lifesaver as I’m nearing a deadline for using PST files at work. I was wondering how I might edit the script to remove illegal characters from senders – the [From]s as well. A couple of our vendors have them in their email names.
      Thanks for continuing this thread!
      Melissa

    • Hi, Melissa.

      I apologize for being so slow to respond to your post. To remove illegal characters from the sender’s name, change line #34 of the code from

      strSubject = "[From] " & olkItm.SenderName & " [Subject] " & RemoveIllegalCharacters(olkItm.Subject)
      

      to

      strSubject = "[From] " & RemoveIllegalCharacters(olkItm.SenderName) & " [Subject] " & RemoveIllegalCharacters(olkItm.Subject)
      
  3. Hi David,

    First off – thank you for this article! This is a huge time saver for me. I appreciate you sharing this with everyone.

    I’m having the “olkItm.SaveAs strMyPath, olMSG” issue too. It seems to be stopping when it comes to a sub-directory that’s created in Outlook’s folder structure that is not present in the folder structure I have on my file system. I don’t know if it’s coincidence or not, but the issues have occurred when the sub-directory is 4 levels deep (e.g. my Outlook directory is “Mailbox – Erik Runge\Email\Reports\Templates\” while my file system directory is “Documents\Email\Reports\”) If I go in and manually create the folder structure in my file system and then re-run the macro, it seems to work. Is there a way to add code to make sure that the folder structure is the same between Outlook and the file system and if not, to create the folder structure prior to saving the email messages?

    Thanks again!

    • Hi, Erik.

      You’re welcome!

      “Is there a way to add code to make sure that the folder structure is the same between Outlook and the file system and if not, to create the folder structure prior to saving the email messages?”
      The code already does this. It creates the folders in the file system as it goes. I just tested the code on a folder structure that looks like this

      + Main Folder
      ..+ Sub1
      ….+ Sub2
      ……+ Sub3
      ……..+ Sub4

      That’s five levels deep. None of the folders existed in the file system at the start of the run. The code created them all just as it should. Perhaps it’s the folder name that’s the problem. Are there any illegal characters in the name of the folder? The code doesn’t check folder names for illegal characters.

  4. Is there a way to show a folder which has the 10 recently used folders in it? like to safe thing quicker if you have a large directory. Now u select a folder, but is there a ways to show the 10 last used folder beneat them?

    • Hi, Midas.

      I suppose something like that is possible, but not without a lot of effort. You’d have to write code to keep track of the 10 most recently used folders, design a way to display that, and a way to trigger displaying that data. In essence, you’d have to rewrite Outlook’s built-in save functionality. That’s no small task and not something you’d do with macros. You’d want to create an add-in.

  5. Hi David. Using this again, and working very well. If people are having trouble with the line: olkItm.SaveAs strMyPath, olMSG, I have found that if you are trying to run the macro on a shared mailbox, alongside your normal mailbox, it can come up with this problem. However, if you create a new profile, just for that mailbox and run it, it works fine.

    One more question I have, is it possible to take care of multiple spaces in subject lines? I have found the macro falls over when there is more than about 2 or 4 spaces in a subject line. I tried adding a line to the illegal characters part of the macro, with ” ” added on to allow for spaces, but that doesn’t seem to work.

    Any ideas on that? Thanks.

    • Hi, Graham.

      How does the macro fail when there are multiple spaces in the subject line? Is there an error message? If so, what is it? If not, please describe how the macro fails.

    • Hi David. I have taken a couple of screenshots which I will email to you, but will copy out the text here. The ‘Microsoft Visual Basic’ box pops up with:

      Run-time error ‘-2147286788 (800300fc)’: The operation failed.

      Then the Visual Basic editor pops up with the olkItm.SaveAs strMyPath, olMSG line highlighted in yellow.

    • Hi, Graham.

      I’ll take a look at the screenshots later. I’m not aware of any restrictions on spaces in a file name. I just tested saving a message as a file with between three and six consecutive spaces in the filename. Worked perfectly.

    • Ok. Thanks David. It may be something else that’s causing the the macro to fail, but the spaces is just what jumped out at me straight away as being the common theme amongst the few that did fail. The macro also doesn’t seem to like “Postmaster@” bounce emails, but we don’t need to archive those so it’s not a problem.

    • The bounce emails aren’t actually emails. They’re reports. They look like emails, but are actually a different object type in Outlook.

      Are you saving the messages to the local computer or to a network drive? How long is the path name?

    • Ah, that would explain why it doesn’t like the bounces then. I am saving them first to a temp directory on my local computer, before copying them across to our storage servers.

    • I can modify the code to process reports too. I just need to know which version of the code you’re using.

    • I stand corrected. The code should handle report objects also. I just tested it to make sure and it worked properly for me. Here too maybe it has something to do with where you’re saving to, or the length of the file path.

    • Wouldn’t have thought that would have been a problem. I am saving them to a c:\temp directory on the root of the PC. Would it be better doing it to a temp directory in my documents folder?

    • No. I’d seen some comments on another site where some people we’re reporting the same problem you’re having. For some of them, the problem only occurred when saving to a network drive. For others, it happened without regard to where they were saving. No one had yet determined exactly why. If you can share one of the messages, then send it to me and I’ll see if I can figure out what’s going on. If you do that, then please send me an email with the problem message attached. Don’t forward the message to me as that changes the message.

  6. Hi David. Is it possible to automatically move the emails into folders based on closest file name match once its exported into the file system. In other words, folders needs to be created automatically and grouped based on closest file name (email subject)

    • Hi, shahiem.

      Yes, it’s possible to save messages into folders based on the file name. What I’m not clear on is what you mean when you say “closest file name”. What does “closest” mean in this context? Please give me a couple of examples.

    • Thank you for your quick response..
      What I’m looking for is once the emails are exported and there’s matching subjects or partially matching subject (file name) e.g.
      1. fax from 011423123 – page 1
      2. fax from 011423123 – page 2
      3. fax from 011423123 – page 3
      4. fax from 011423456 – page 1
      5. fax from 011423456 – page 1
      in this case it should create a folder and move fax from 011423123 and move emails 1,2 and 3 into that folder.
      The same for fax from 011423456 and move those 2 emails into it
      Hope this explains my request..
      Thank You so much for assisting!!

    • The problem with this is what constitutes a “partially matching subject”? Using the sample file names you listed, “fax”, “fax from”, “fax from 011423”, and “page 1” are all “partially matching subjects”. For this to work there has to be a rule that defines what portion of the subject is used to determine a partial match. For example, if the first 10 characters match, or the first two words match, or all the letters before the hyphen, then consider that a partial match. Whatever the rule is, it must work for all messages or you must have multiple rules. If you have multiple rules, then each rule must clearly describe a set of messages and the rules must be unique.

    • That sounds simple, but it’s not that easy. Unless the numbers always begin in the same location and are always the same length, then the code can’t easily pick out the numbers to perform the match. Of course if you only want the code to handle messages about faxes (e.g. messages that begin with “fax from” followed by some number of digits, then this becomes a lot simpler.

    • Hi David
      unfortunately we don’t only receive fax emails. I did however come across this code which is used in a batch file that kinda sorts out the moving of files into folders with an “ok” filename. The script u will find below…
      Is it possible for you to combine the two scripts?
      That would really be awesome!!

      @echo off
      setlocal

      set “basename=.”
      for /F “tokens=1* delims=.” %%a in (‘dir /B /A-D ^| sort /R’) do (
      set “filename=%%a”
      setlocal EnableDelayedExpansion
      for /F “delims=” %%c in (“!basename!”) do if “!filename:%%c=!” equ “!filename!” (
      set “basename=!filename!”
      md “!basename!”
      )
      move “!filename!.%%b” “!basename!”
      for /F “delims=” %%c in (“!basename!”) do (
      endlocal
      set “basename=%%c
      )
      )

    • Hi, shahiem.

      That batch file creates a folder for each file it finds, gives the folder the name of the file minus the file extension, then moves the file with that name into the folder. I don’t understand what that has to do with your original request, unless I’ve completely misunderstood what it is you want. I thought you wanted to group messages together based on the subject lines and save the group to a file system folder. Using the sample subject lines you gave, I thought you wanted all the messages with “fax from 011423123” in the subject line saved to one file system folder and the messages with “fax from 011423456” in the subject line saved to a different file system folder. If that is what you want, then I don’t see how this batch file is going to help accomplish that. It’s the grouping that’s the problem. As I explained, in order to group messages based on a portion of the subject line you must define a rule or set of rules that governs the matching process. That rule or rules must then work for every message the solution will ever encounter. If not, then you aren’t going to get the results you want. If instead you want a solution that creates a file system folder for each message and saves the message to that folder, then I can do that.

    • Hi, Julio.

      Yes, that’s possible. To do that we just need to remove the FOR … NEXT loop used to export the contents of the folders from the ExportOutlookFolder subroutine. Here is the modified version of that subroutine. Use it in place of the ExportOutlookFolder subroutine from the original code, leaving the rest of the code as is.

      Sub ExportOutlookFolder(ByVal olkFld As Outlook.MAPIFolder, strStartingPath As String)
          Dim olkSub As Outlook.MAPIFolder, olkItm As Object, strPath As String, strMyPath As String, strSubejct As String, intCount As Integer
          strPath = strStartingPath & "\" & olkFld.Name
          objFSO.CreateFolder strPath
          For Each olkSub In olkFld.Folders
              ExportOutlookFolder olkSub, strPath
          Next
          Set olkFld = Nothing
          Set olkItm = Nothing
      End Sub
      
  7. Pingback: Export Outlook Folders to the File System | VBA Help XYZ

  8. Hello everyone,

    Did someone have Run-time? it either works and only makes a file system folder on the PC without mails in it or it gives an error:
    Run-time error -2147287037 (80030003)
    The operation failed.

    • it is line 46 olkItm.SaveAs strMyPath, olMSG. it is strange, at home the same thing it work, but not on my work pc. can it be a credential issue?

    • Hi, Istvan.

      I suppose it could be a permissions issue. Can you save files to that folder outside of Outlook? If so, then it’s not a permissions issue. How long is the path? It could be that the path is too long. Is the path on a network drive? If so, does the path use a drive mapping?

    • hello David, yes i can save in that folder. it is a partition on the computers hard disk. i tried in the first folder so the path wouldn’t be long and it was the same error.

    • Hi, istvan.

      Is there a file or folder there already with the same name? What is the constant “STARTING_FOLDER” set to?

  9. Is it possible to adjust the macro so that it remove illegal characters from Folder Names in Excel? For instance one of the folders I am trying to do this on is named * XXXXX * (X’s are just replacing folder name). The macro throws up a run error because of these star’s and I am not allowed to change the shared mailbox name.

    It would also seem this macro cannot save to a network drive? Not essential as I can simply copy them across.

    • Hi, Graham.

      Is it possible to adjust the macro so that it remove illegal characters from Folder Names in Excel?
      Sorry, but I’m confused. This solution doesn’t do anything with Excel. Even if it did, I’m not clear on what “Folder Names in Excel” means.

      It would also seem this macro cannot save to a network drive?
      It can save to a network drive. Modify line #2 and set STARTING_FOLDER to a network folder (e.g. \\SomeShare\SomeFolder) or to the literal value “Computer” which will allow you to browse to the network and find a folder.

    • Sorry David, I had Excel on the brain that day. I meant illegal characters in Folder Names in Outlook. There is a subfolder of the folder I am trying to save messages from the contains a ‘*’ at the beginning and the end of the folder name.

    • Hi David. Apologies for the confusion in my previous message, I meant to type ‘Outlook Folders’ , not Excel!! I got around it by moving the messages I wanted to archive into a subfolder without any illegal characters.

      My next question… is it possible to adjust the code so that instead of the file name using the “From” address, it uses the “To” address instead? I would like to archive a rather large ‘Sent Items’ folder. Thanks.

    • Sorry David, I meant Outlook, not Excel. The Inbox subfolder contains an ‘illegal’ character, a ‘*’ on either side of the name. I got around it by simply creating another sub folder with no illegal characters, and running the macro from there.

  10. We have to upload email messages sent into a file system at work based upon the company which received them. After finding your webpage I thought my problems were solved – I created ‘company’ folders in outlook and moved the corresponding emails to those folders.
    I ran your script and it beautifully made explorer folders and the corresponding emails. the problem I’m running into now is that I was wanting to zip the emails into one file and just upload that into our file system.
    When I try to do by right clicking and saying “Send to compressed folder” I get the following error: “compressed (zipped) Folders Error”, with the actual error as “File not found or no read permission.”

    After searching around I found some posts about the TEMP directory windows creates being limited to certain users. (but I was made an administrator so I could run the code and I’ve set the folder properties to not be read only)
    Others have stated that the script may be lacking a file.Close() command?

    Any ideas?

    • Hi, Chris.

      Unless the script is still running when you attempt the zip operation, I don’t think it’s the culprit. I don’t know how the TEMP directory factors into this, unless Windows uses it during the zip operation or that’s where you’re exporting to. As to the script lacking a file.Close(), there’s no file to close. You can completely eliminate the script as the cause by closing Outlook before you attempt the zip operation. Closing Outlook will terminate the script if it’s still running and will close any files it or the script have open. If the zip operation doesn’t work with Outlook shut down, then neither it nor the script are responsible for the problem. The next step is to reboot the computer then try the zip operation again. If it still doesn’t work, then the problem is definitely something to do with the folder, permissions on the folder, your account permissions, or Windows. Can you create any zip files on this computer? If so, then create a text file in one of the folders you exported the messages to and try to zip it. Let me know what happens.

    • Thanks for writing back!

      I don’t think it’s the script/outlook/rebooting issues because I had the macro copy the folders onto our network drive. The busy work task of uploading the files was split between me and my supervisor. She started before I did actually, and when she tried to zip the files using the right click/sent to folder option, she got the error I mentioned:
      [cid:image001.png@01D16B2D.17A90BF0]
      It’s not the end of the world if we upload both files, but it seems silly because the only difference is that they went to two different people at the same company. Sometimes it’s one person, the most is probably 6. Being OCD engineers, we’re trying to cut down on the clutter in the file managing program if possible.

      It was when I searched for those terms when I came across the various Microsoft support answers
      http://answers.microsoft.com/en-us/windows/forum/windows_7-files/attempting-to-create-zip-file-results-in-access-is/a582c461-379e-44cf-847f-f3ce4b92ff78
      http://answers.microsoft.com/en-us/windows/forum/windows_vista-files/when-i-try-to-use-the-send-to-compressed-zipped/264ba861-1262-4181-94ed-0f00325604f5?page=4

      (here’s the page that was talking about the close() command (most programming languages are completely greek to me)
      http://stackoverflow.com/questions/14699767/copy-folder-contents-to-a-created-zip-file-file-not-found-or-no-read-permissi)

      those do seem to be deadends because when I go to the mentioned directories, I have all the permissions which seem to be necessary:
      [cid:image006.png@01D16B2E.CA7CA8D0]
      (I even created a different directory in winzip to see if that would help)
      [cid:image002.png@01D16B2F.336B9AE0]

      I’m able to make a new compressed folder:
      [cid:image003.png@01D16B2D.9DAEE440]
      It lets me add a dummy text file I made
      [cid:image004.png@01D16B2D.9DAEE440]
      But absolutely refuses to have anything to do with the outlook messages when I try and drag and drop.
      [cid:image005.png@01D16B2D.9DAEE440]

      (I can tell something is trying to happen because the mouse cursor will flicker a bit, but nothing ever shows up.)

      If I open Winzip and try to manually create a zip file I get a similar error (I assume)
      [cid:image007.png@01D16B2F.76A27BD0][cid:image008.png@01D16B2F.76A27BD0] this was the closest I could find for this error: http://kb.winzip.com/kb/entry/35/

      In a fit of desperation I downloaded a different zip program (7-zip) http://www.7-zip.org/
      And it seems to work for some reason?!? I don’t like it as much but it seems to do the job.

      I just wish I knew why winzip wasn’t working…

    • Hi, Chris.

      You’re welcome.

      I use WinZip myself and am able to zip folders I export using this same code. Since 7-zip works it’s clear that your account has the necessary permissions to access the files. If you’re able to zip other files/folders using WinZip, then I’d look at the differences between these files and the folders they are in and the Outlook export folders and files. For example, some applications have problems with long path names.

    • Do you think the following could have anything to do with the problem I was having zipping the files? (again, coming from somebody that knows virtually nothing about programming)

      I think I mentioned that we upload all correspondences into a file managing system.
      I noticed today that one of the files that was uploaded gave this crazy upload (last modified) date:

      [cid:image001.png@01D17572.F61F8F40]

      Is it possible that when the macro creates the file somehow it isn’t “finishing” the file? I think in my first email to you I had mentioned that somebody else spoke of that concept? (maybe I just read about it)

      So that for some reason the date isn’t getting accurately encoded and winzip doesn’t allow that kind of thing but the 7-zip doesn’t care?

    • Hi, Chris.

      That’s not a last modified date. That’s the notation Outlook uses to represent an embedded image. The script isn’t capable of not finishing the file because the script doesn’t write the file. It’s using Outlook’s built-in methods to do that. All the script does is call those methods. I’m confident that Outlook’s file and attachment save methods are working. If they were unreliable, then dragging and dropping a message to the file system would fail as would saving an attachment. That said, if you’re seeing files with those kinds of names (i.e. “[cid:image001.png@01D17572.F61F8F40]”), then that’s a problem. First, the script shouldn’t be saving embedded images. It’s designed to skip over them. Second, that type of file name could explain why WinZip won’t zip the files. It might be tripping over that type of file name whereas 7-zip isn’t.

  11. Pingback: Outlook: Export all mail into Explorer | Dave Gernon's Tech Blog

  12. This was exactly what I needed. Thanks a lot! Now I can export outlook email to file system with correct date time stamp. The only thing that puzzles me is why this isn’t possible in Outlook already. But thanks to all who made this possible (David Lee and other contributors).

  13. David, Great work. Your code works fantastic for email messages but fails when it tries to export public folders with word docs, excel spreadsheets and pdf’s. Would you have the tweak to do this. Thanks

    Tim

    • Hi, Tim.

      Thanks!

      How is it failing? Is there an error message? What version of Outlook are you using? I just ran the code against a folder containing files of various types and it worked perfectly.

  14. Hi,

    Good Morning,
    I am using outlook 2010, I take Revision1 code but, getting error message like “Compile error: Variable not defined” and highlighting line number 36, “strSubject = “[From] ” & olkItm.SenderName & ” [Subject] ” & RemoveIllegalCharacters(olkItm.Subject)”

    please help

  15. Thanks for sharing! I added checks for non-deliverable email notifications (NDR) and message recall success/failures. In these three instances the SenderName and/or ReceivedTime wasn’t set causing the macro to halt.

    • B Johnson, would you mind posting the code for the checks that you came up with for the non-deliverable notifications? I think I have having similar trouble with smtpbounces emails. Thanks.

    • Hi David,

      I reply to this post as I had some troubles with your script so I tried the one from Alex, which worked but only for Eamil itesms.
      My situation is that I have a Public Folder with +4000 subfolders. The items inside are mostly emails but there are some ppt, jpg, pdf, doc and other type of files (it is easy to drag and drop items in Public folders but no one thought of exporting them outsice).
      Would it be possible to make a script that can copy/move more than just msg?

    • Hi, Vassil.

      Please try this version.

      'On the next line edit the starting folder as desired.  If you leave it blank, then the starting folder will be the local computer.
      Const STARTING_FOLDER = ""
       
      Dim objFSO As Object
       
      Sub CopyOutlookFolderToFileSystem()
          ExportController "Copy"
      End Sub
       
      Sub MoveOutlookFolderToFileSystem()
          ExportController "Move"
      End Sub
       
      Sub ExportController(strAction As String)
          Dim olkFld As Outlook.MAPIFolder, strPath As String
          strPath = SelectFolder(STARTING_FOLDER)
          If strPath = "" Then
              MsgBox "You did not select a folder.  Export cancelled.", vbInformation + vbOKOnly, "Export Outlook Folder"
          Else
              Set objFSO = CreateObject("Scripting.FileSystemObject")
              Set olkFld = Application.ActiveExplorer.CurrentFolder
              ExportOutlookFolder olkFld, strPath
              If LCase(strAction) = "move" Then olkFld.Delete
          End If
          Set olkFld = Nothing
          Set objFSO = Nothing
      End Sub
       
      Sub ExportOutlookFolder(ByVal olkFld As Outlook.MAPIFolder, strStartingPath As String)
          Dim olkSub As Outlook.MAPIFolder, olkItm As Object, olkAtt As Outlook.Attachment, strPath As String, strMyPath As String, strSubejct As String, intCount As Integer
          strPath = strStartingPath & "\" & RemoveIllegalCharacters(olkFld.Name)
          objFSO.CreateFolder strPath
          For Each olkItm In olkFld.Items
              Select Case TypeName(olkItm)
                  Case "DocumentItem"
                      For Each olkAtt In olkItm.Attachments
                          strFilename = olkAtt.FileName
                          intCount = 0
                          Do While True
                              strMyPath = strPath & "\" & strFilename
                              If objFSO.FileExists(strMyPath) Then
                                  intCount = intCount + 1
                                  strFilename = objFSO.GetBaseName(olkAtt.FileName) & " (" & intCount & ")" & objFSO.GetExtensionName(olkAtt.FileName)
                              Else
                                  Exit Do
                              End If
                          Loop
                          olkAtt.SaveAsFile strMyPath
                      Next
                  Case "MailItem"
                      If Not IsEmpty(olkItm.SenderName) Then
                          If Not IsEmpty(olkItm.Subject) Then
                              strSubject = RemoveIllegalCharacters(olkItm.SenderName) & " - " & RemoveIllegalCharacters(olkItm.Subject)
                              strFilename = Trim(strSubject) & ".msg"
                              intCount = 0
                              Do While True
                                  strMyPath = strPath & "\" & strFilename
                                  If objFSO.FileExists(strMyPath) Then
                                      intCount = intCount + 1
                                      strFilename = strSubject & " (" & intCount & ").msg"
                                  Else
                                      Exit Do
                                  End If
                              Loop
                              If Len(strMyPath) >= 255 Then
                                  strMyPath = Left(strMyPath, 200)
                              End If
                              olkItm.SaveAs strMyPath
                              ChangeTimeStamp strMyPath, olkItm.ReceivedTime
                          End If
                      End If
                  Case "PostItem"
                      If Not IsEmpty(olkItm.Subject) Then
                          strSubject = RemoveIllegalCharacters(olkItm.Subject)
                          strFilename = Trim(strSubject) & ".msg"
                          intCount = 0
                          Do While True
                              strMyPath = strPath & "\" & strFilename
                              If objFSO.FileExists(strMyPath) Then
                                  intCount = intCount + 1
                                  strFilename = strSubject & " (" & intCount & ").msg"
                              Else
                                  Exit Do
                              End If
                          Loop
                          If Len(strMyPath) >= 255 Then
                              strMyPath = Left(strMyPath, 200)
                          End If
                          olkItm.SaveAs strMyPath
                          ChangeTimeStamp strMyPath, olkItm.ReceivedTime
                      End If
      
              End Select
          Next
          For Each olkSub In olkFld.Folders
              ExportOutlookFolder olkSub, strPath
          Next
          Set olkFld = Nothing
          Set olkItm = Nothing
      End Sub
       
      Function SelectFolder(varStartingFolder As Variant) As String
          ' This function is a modified version of the SelectFolder function written by Rob van der Woude (http://www.robvanderwoude.com/vbstech_ui_selectfolder.php)
       
          ' Standard housekeeping
         Dim objFolder As Object, objShell As Object
           
          ' Custom error handling
         On Error Resume Next
       
          ' Create a dialog object
         Set objShell = CreateObject("Shell.Application")
          Set objFolder = objShell.BrowseForFolder(0, "Select the folder you want to export to", 0, varStartingFolder)
       
          ' Return the path of the selected folder
         If TypeName(objFolder) <> "Nothing" Then SelectFolder = objFolder.self.Path
       
          ' Standard housekeeping
         Set objFolder = Nothing
          Set objShell = Nothing
          On Error GoTo 0
      End Function
       
      Function RemoveIllegalCharacters(strValue As String) As String
          ' Purpose: Remove characters that cannot be in a filename from a string.'
         ' Written: 4/24/2009'
         ' Author:  BlueDevilFan'
         ' Outlook: All versions'
          RemoveIllegalCharacters = strValue
          RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, "<", "")
          RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, ">", "")
          RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, ":", "")
          RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, Chr(34), "'")
          RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, "/", "")
          RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, "\", "")
          RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, "|", "")
          RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, "?", "")
          RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, "*", "")
          RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, "@", "_at_")
          RemoveIllegalCharacters = Replace(RemoveIllegalCharacters, Chr(9), "")
      
      End Function
       
      Sub ChangeTimeStamp(strFile As String, datStamp As Date)
          Dim objShell As Object, objFolder As Object, objFolderItem As Object, varPath As Variant, varName As Variant
          varName = Mid(strFile, InStrRev(strFile, "\") + 1)
          varPath = Mid(strFile, 1, InStrRev(strFile, "\"))
          Set objShell = CreateObject("Shell.Application")
          Set objFolder = objShell.NameSpace(varPath)
          Set objFolderItem = objFolder.ParseName(varName)
          objFolderItem.ModifyDate = CStr(datStamp)
          Set objShell = Nothing
          Set objFolder = Nothing
          Set objFolderItem = Nothing
      End Sub
      
  16. Hi There, Not sure if you’re still following this thread, but I’m trying this script with Exchange 2003 and Outlook 2010 (using the first set of code). When I try to export a folder I often get a failures on this line:
    ChangeTimeStamp strMyPath, olkItm.ReceivedTime

    This prevents me from getting through the entire folder tree. I assume this is because it hits a message that it doesn’t like and then craps out. Before it fails it usually gets through a number of messages, folders, and subfolders, so i’m not sure I’ve discovered a pattern.

    FWIW, when I try the revision 1 code, which would be much better for us as it preserves the dates, it fails every time on the first message with an error that says
    Run-time error ‘438’:
    Object doesn’t support this property or method

    And debug takes me to this line of code:
    strSubject = “[From] ” & olkItm.SenderName & ” [Subject] ” & RemoveIllegalCharacters(olkItm.Subject)

    I’m no vb expert, so wondering if you’ve ever seen this before or if an answer to the problem pops quickly to mind.

    If not, any recommendations on other tools that would dump a public folder tree and content to file folders would be very helpful. We’re struggling here.

    Many thanks!
    Adam

    • Hi, Adam.

      Yes, I’m still following this thread.

      I’m a little confused. If I understand correctly, you said that you’re using the original version of the code and are encountering an error on the line

      ChangeTimeStamp strMyPath, olkItm.ReceivedTime
      

      What confuses me is that the original version doesn’t contain that line of code. That line is only in the revision.

      As for the error on this line

      strSubject = “[From] ” & olkItm.SenderName & ” [Subject] ” & RemoveIllegalCharacters(olkItm.Subject)
      

      what type of items are in the folder you’re trying to export?

    • First, thanks for your super-fast reply. You’re right about the original script thing – I meant to say the original version stops here:
      olkItm.SaveAs strMyPath, olMSG

      Sorry about that, I’ve been switching back and forth quite a bit.

      The directory I’m trying to export has read and unread items that include

      · Messages

      · Posts

      · Meeting Requests

      · Meeting Cancellations

      I also got this error when the script hit a conflict message – removing the conflict message seemed to fix that one.

    • Hey, Adam.

      No worries.

      When you say “conflict message” do you mean a sync error message?

      Rev 1 would fail when processing any type of item other than an email. That’s because emails are the only type of item that has a “SenderName” property. We can fix that by changing this line

      strSubject = “[From] ” & olkItm.SenderName & ” [Subject] ” & RemoveIllegalCharacters(olkItm.Subject)
      

      We’d either remove the “SenderName” portion leaving just the subject or remove “SenderName” and use some other piece of data to construct the filename the item will be saved to.

    • Hi David,
      I removed the “[From] ” & olkItm.SenderName from the revised version and it now dumps at the same spot the original does ( at olkItm.SaveAs strMyPath, olMSG) after about 180 items. The next item it would have looked at appears to be a normal message, so I’m not sure why it’s failing there. Any other ideas before I give up?
      Either way, I really appreciate the help!
      Adam

    • Ha, still night time here (I’m in New Caledonia) I think it was a just a normal mail message, though I’m not 100% sure which one it failed on- it looks like it works it’s way sequentially by date so I’m assuming it failed on the first message that’s not in the export.

      Sent from my iPhone

    • Adam,

      Wow, the other side of the planet. Well, it’s morning here on the east coast of the U.S.

      We need to isolate the item that’s failing to understand what’s happening. The two most logical potential causes are that the item is something other than a message or that there’s some character in the subject that’s causing the problem. Here’s the simplest way t find out which item it is.

      1. When the error message appears click Debug.
      2. The code editor should open and the line causing the error will be highlighted in yellow.
      3. Hover your mouse pointer over olkItm.Subject which is a few lines above the line causing the error. The value of that item will appear in a rectangle next tot he mouse pointer.
      4. Jot down the subject, then go find the item with that subject in the folder you’re exporting from.
      5. Note what type of item it is and what the item’s subject is.
      6. Send me those two pieces of information and we’ll take it from there.
  17. Hello David,
    This macro is exactly what I was looking for. Thank you.
    I have one issue though. When saving the mails I sometimes get an error code from the macro. This only happens when the from name contains illigal characters (example: “John Doe (RY/ETM)” ).

    Regards, Bas

    • Hi, Bas.

      You’re welcome! I’m glad the macro is useful.

      What line is the error occurring on and what is the exact error message? The sender’s name isn’t used in the file name, so I don’t think that’s the problem.

  18. Thanks for the scripts – it works great. A couple of enhancements that would make it more useful, 1) store the sender as the author of the email 2) either have an option to copy individual emails (or select multiple) and send to a folder or ignore the fact that the destination folder already exists. With the current implementation, if you copy rather than move, you can’t update again later because the folder already exists – Thank you for your excellent work!

    • Hi, Jason.

      You’re welcome. I’m glad you found the solution useful.

      Thanks for the suggestions. I’m not sure I understand your first suggestion though. When you say “store the sender as the author of the email”. Store it where? Are you saying that you’d like the sender added to the file name of the saved message? I like the idea of enabling the solution to save new messages to an existing folder. When I have time, I’ll modify the code to do that.

  19. All working, thanks David. For my own peace of mind I have commented out the Move options in my copy. Setting the starting folder in line 2 doesn’t seem to do anything – the dialog box opens at Desktop.
    I’ve started to think that if I have time, I might try to add to this code to get user control over the filename – at present the exported folder will be hard to work with, especially as all the files acquire the same date and time of creation so you can’t sort the .msg files by date and time of sending (I don’t know if it’s possible to specify the creation date when saving a file from VBA, but preserving the original date and time would be useful). It should be fairly easy to let the user create the filename format using up to three parameters selected by dropdowns, eg “from Chris Robinson to David Lee 05/10/2013 14:57.msg” or “0001 Re: Export Outlook Folders to the File System from Chris Robinson.msg”. I can see that having applications in creating an integrated folder with other forms of document to create an electronic equivalent of a paper file for a person or transaction. I already have a Word macro that compiles a contents list for a folder as a Word document based on the filenames (hyperlinking the files), so adding emails with sensible filenames would be a big bonus.
    Best, Chris

    • Chris,

      Thanks for pointing that out. When I converted the function from VBscript to VBA I changed the parameter that gets passed into the SelectFolder function from Variant to String. Apparently it has to be Variant to work properly. I’ve corrected the code. Please grab it again or at least replace that one function with the updated version.

      How would you prefer the file name read? I can change it to almost anything.

    • The default folder is working now, thanks.
      On filenames, the main problem for me will be that with all the emails being exported to new files all with the same date and time, and many emails with similar filenames, it will be very hard to know what each one is or to sort them sequentially. So I would probably go for something complicated like “0001[sequential number, mainly to keep them in order, assumes that the export/copy function exports them in ascending date order – does it?] Email from [truncated to 10 characters] to [truncated to 10 characters] “. Very long winded but easier for the user to edit down than to add to the code.
      Best, Chris

    • You’re welcome, Chris.

      How about if I date stamp the exported files with the date the message was received and set the file name to a truncated version of the message subject?

    • Yes, if the datestamp of the file (by which I understand the date shown as the file creation date) was the date and time of sending the email, that would help a lot. It shouldn’t be necessary to truncate the heading, but if there’s an easy was including sender and recipient it would be useful. In essence the problem is that all the emails in a folder are very likely to look very similar (dozens of emails between the same people with the same headings), and anything that helps the user search, automatically or manually, will help, and keeping them in the right order is essential..

  20. David, this is fantastic (why doens’t Oullook have this functionality as standard?) but I had a problem when I tried it. A folder with about 20 messages in it exported as a folder with only four. Fortunately i was using “copy” and not “move”! My best guess at what is happening is that the macro is using the message heading to create the filename for the .msg file, so if the heading is identical on a second message it will just overwrite the first one. there were only four unique headings on messages in the folder so I ended up with only four messages, with the rest discarded.
    For my own use I think I will discard the “move” code, as I want to be sure not to lose anything accidentally, and I can easily delete from Outlook manually if required.
    Best, Chris

    • Chris,

      Thanks! That’s a good question.

      Good catch on the file name. I’ll modify the code to make each file name unique. What do you think would be the best solution to that, adding a number to file name (e.g. Copy 1 of – some subject) or adding the date/time the message was received (e.g. Some Subject – Received on 2013/5/9 09:59 AM)?

    • Just adding a number to the filename, I would think – if you drag and drop multiple messages from Outlook to the file system (I didn’t know you could do this till I read your post, so thanks for that) it appends (1), (2) etc. But the date and time would work well too and might be more useful – especially if the (1), (2) were not in date/time order – but there should then be a trap in case two messages had the same time, which they often would if to the nearest minute.

    • Chris,

      I just updated the code to add a number to the file name if a file with that name already exists. Please replace the code you have now with the updated code and let me know if that works for you.

      Cheers!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s