• Outlook User
  • New Outlook app
  • Outlook.com
  • Outlook Mac
  • Outlook & iCloud
  • Developer
  • Microsoft 365 Admin
    • Common Problems
    • Microsoft 365
    • Outlook BCM
    • Utilities & Addins

Save Selected Email Message as .msg File

Slipstick Systems

› Developer › Code Samples › Save Selected Email Message as .msg File

Last reviewed on August 19, 2024     275 Comments

This code sample will save one or more selected messages to your My Documents folder as individual .msg files. The file name includes the received date and time. Spaces and invalid characters are replaced with underscores.

Save msg

A variation of this macro that saves as a text file is at Save email message as text file. Included is a version that saves selected messages as one text file. For more information on saving to other formats, see How to Save Email in Windows File System.

See How to use the VBA Editor if you don't know how to use macros or the VBA Editor.

Updated December 17 2014: macro checks for message class and skips meetings and report/receipt messages. I also added character replacements for single quote and asterisk.

Option Explicit
Public Sub SaveMessageAsMsg()
  Dim oMail As Outlook.MailItem
  Dim objItem As Object
  Dim sPath As String
  Dim dtDate As Date
  Dim sName As String
  Dim enviro As String
 
    enviro = CStr(Environ("USERPROFILE"))
   For Each objItem In ActiveExplorer.Selection
   If objItem.MessageClass = "IPM.Note" Then
    Set oMail = objItem
   
  sName = oMail.Subject
  ReplaceCharsForFileName sName, "-"
 
  dtDate = oMail.ReceivedTime
  sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
    vbUseSystem) & Format(dtDate, "-hhnnss", _
    vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"
     
    sPath = enviro & "\Documents\"
  Debug.Print sPath & sName
  oMail.SaveAs sPath & sName, olMSG
  
  End If
  Next
  
End Sub
 
Private Sub ReplaceCharsForFileName(sName As String, _
  sChr As String _
)
  sName = Replace(sName, "'", sChr)
  sName = Replace(sName, "*", sChr)
  sName = Replace(sName, "/", sChr)
  sName = Replace(sName, "\", sChr)
  sName = Replace(sName, ":", sChr)
  sName = Replace(sName, "?", sChr)
  sName = Replace(sName, Chr(34), sChr)
  sName = Replace(sName, "<", sChr)
  sName = Replace(sName, ">", sChr)
  sName = Replace(sName, "|", sChr)
End Sub

 

Pick the Folder Location

To select the folder where you want to save the selected messages, you can use the BrowseForFolder function. You'll need to select the folder before you begin saving the messages. If you select it after the For Each loop, you'll need to select a folder for each message.

Don't forget to get the BrowseForFolder function.

Option Explicit
Public Sub SaveMessageAsMsg()
  Dim oMail As Outlook.MailItem
  Dim objItem As Object
  Dim sPath As String
  Dim dtDate As Date
  Dim sName As String
  Dim enviro As String
  Dim strFolderpath As String
  
    enviro = CStr(Environ("USERPROFILE"))
'Defaults to Documents folder
' get the function at http://slipstick.me/u1a2d
strFolderpath = BrowseForFolder(enviro & "\documents\")

' Cleanly exit if Cancel is clicked
 If StrFolderpath = "False" Then
      Cancel = True
      Exit Sub
  End If
   
   For Each objItem In ActiveExplorer.Selection
   If objItem.MessageClass = "IPM.Note" Then
    Set oMail = objItem
    
  sName = oMail.Subject
  ReplaceCharsForFileName sName, "-"
  
  dtDate = oMail.ReceivedTime
  sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
    vbUseSystem) & Format(dtDate, "-hhnnss", _
    vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"
      
  sPath = strFolderpath & "\"
  Debug.Print sPath & sName
  oMail.SaveAs sPath & sName, olMSG
   
  End If
  Next
   
End Sub

 

Save messages as they are sent

This version of the macro will save messages to the user's My Documents folder as they are added to the Sent Items folder, using "Now" to create the time and date stamp. If the subject contains illegal filename characters, you'll need the ReplaceCharsForFileName sub above.

Private WithEvents objSentItems As Items

Private Sub Application_Startup()
Dim objSent As Outlook.MAPIFolder
Set objNS = Application.GetNamespace("MAPI")
Set objSentItems = objNS.GetDefaultFolder(olFolderSentMail).Items
Set objNS = Nothing
End Sub
 
Private Sub objSentItems_ItemAdd(ByVal Item As Object)
  Dim sPath As String
  Dim dtDate As Date
  Dim sName As String
  Dim enviro As String
 
enviro = CStr(Environ("USERPROFILE"))
   
  sName = Item.Subject
  ReplaceCharsForFileName sName, "-"
 
  dtDate = Item.ReceivedTime
  sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
    vbUseSystem) & Format(dtDate, "-hhnnss", _
    vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"
     
    sPath = enviro & "\Documents\"
  Debug.Print sPath & sName
  Item.SaveAs sPath & sName, olMSG
End Sub

Use a Userform to display locations to choose from

This version of the macro uses a userform to display locations to choose from.
choose a folder to save to
To use this macro, you need to put this line in a module, not in Thisoutlooksession.

Public lstNum As Long

This code goes into ThiOutlookSession:

Option Explicit
Public WithEvents objSentItems As Items


Public Sub Application_Startup()
Dim objSent As Outlook.MAPIFolder
Dim objNS As Object
Set objNS = Application.GetNamespace("MAPI")
Set objSentItems = objNS.GetDefaultFolder(olFolderSentMail).Items
Set objNS = Nothing
End Sub
Public Sub objSentItems_ItemAdd(ByVal Item As Object)
Dim dtDate As Date
Dim sName As String
Dim sPath As String
UserForm1.Show

Debug.Print lstNum
    Select Case lstNum
    Case -1
'  -1 is what you want to use if nothing is selected
         sPath = "C:\Users\slipstick\Documents\"
    Case 0
         sPath = "C:\Users\slipstick\Documents\Email Attach\"
    Case 1
        sPath = "C:\Users\slipstick\Documents\pics\"
    Case 2
         sPath = "C:\Users\slipstick\Documents\Balsam Lake\"
    End Select

sName = Item.Subject
ReplaceCharsForFileName sName, "-"
dtDate = Item.ReceivedTime
sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
vbUseSystem) & Format(dtDate, "-hhnnss", _
vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"
 
Debug.Print sPath & sName
Item.SaveAs sPath & sName, olMSG
End Sub

Public Sub ReplaceCharsForFileName(sSubject As String, _
sChr As String _
)
  sName = Replace(sName, "'", sChr)
  sName = Replace(sName, "*", sChr)
  sName = Replace(sName, "/", sChr)
  sName = Replace(sName, "\", sChr)
  sName = Replace(sName, ":", sChr)
  sName = Replace(sName, "?", sChr)
  sName = Replace(sName, Chr(34), sChr)
  sName = Replace(sName, "<", sChr)
  sName = Replace(sName, ">", sChr)
  sName = Replace(sName, "|", sChr)
End Sub

This code goes into the UserForm. Name the OK button btnOK. See VBA UserForm sample: Select from a list of templates for step-by-step instructions to design the userform.

Private Sub UserForm_Initialize()
  With ListBox1
    .AddItem "Email Attach"
    .AddItem "pics"
    .AddItem "Balsam Lake"
  End With
End Sub

Private Sub btnOK_Click()
    lstNum = ListBox1.ListIndex
    Unload Me
End Sub

When you send a message, the userform comes up with the list of folder locations to choose from.

How to use the macros on this page

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 and newer, go to File, Options, Trust Center and open Trust Center Settings, and change the Macro Settings. In Outlook 2007 and older, look 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.

Some macros need to be in ThisOutlookSession, others go into a module or can be placed in either ThisOutlookSession or a module. The instructions are below.

Open the VBA Editor by pressing Alt+F11 on your keyboard.

To put the code in a module:

  1. Right click on Project1 and choose Insert > Module
  2. Copy and paste the macro into the new module.

To put the macro code in ThisOutlookSession:

  1. Expand Project1 and double click on ThisOutlookSession.
  2. Copy then paste the macro into ThisOutlookSession. (Click within the code, Select All using Ctrl+A, Ctrl+C to copy, Ctrl+V to paste.)

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
  • Saving All Messages to the Hard Drive Using VBA

To save all incoming messages as files as they arrive in your Inbox, see E-Mail: Save new items immediately as files (VBOffice.net)

Save Selected Email Message as .msg File was last modified: August 19th, 2024 by Diane Poremsky
Post Views: 54

Related Posts:

  • Save all incoming messages to the hard drive
  • Save email message as text file
  • Save Messages as *.DOC or *.DOCX File Type
  • Save Outlook Email as a PDF

About Diane Poremsky

A Microsoft Outlook Most Valuable Professional (MVP) since 1999, Diane is the author of several books, including Outlook 2013 Absolute Beginners Book. She also created 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.

Comments

  1. KBa says

    December 17, 2023 at 10:21 am

    Hi everybody,

    How can I deleta an e-mail in Outlook after copying it to a disk?

    Reply
  2. KBa says

    December 16, 2023 at 3:39 pm

    How to remove an e-mail after it has been saved as an *.msg file?

    Reply
  3. Duy Pham says

    August 15, 2023 at 10:04 pm

    Hello Diane,
    Thanks for your sharing, it has been a of a great help for me in daily task now!
    However, Due to the requirements of my job, I want to set the file name by the principle: items in content body email+year/month/day_number of ascending from 1..n.

    For example, here is the body content email:

    From: xxx@yyy.zzzz
    Sent: 15 August, 2023 8:34 AM
    To: pic@abc.com
    Subject: Notice of change of e-invoice

    " Dear: ABC Company (MST: 0345287134)
    Invoice of Company with information:
    - Invoice form symbol: 1
    - Invoice symbol: C23TYY
    - Invoice number: 10
    - Date of establishment: August 14, 2023
    - Seller of goods and providing services: XYZ CO., LTD (MST:2912857402) Has been replaced by invoice form symbol: 1, invoice symbol: C23TYY, invoice number: 12, date of making : 15/08/2023 In case you need more detailed information, please contact the seller of goods and provide services.
    Sincerely thank you! "

    With this email, i would like to save as msg file with the name:
    0345287134_20230815-1

    If have more email from this supplier, the name file will be:
    0345287134_20230815-2
    0345287134_20230815-3
    .....
    0345287134_20230815-n

    Hope to have your continued support, thanks you!

    Reply
  4. Jon D says

    March 5, 2023 at 11:36 am

    Hi Diane,

    I hope you are doing well.

    I was wondering if you are still responding to comments from this article? This code has proven so valuable to me but I am having some issues trying to change the folder path to which I want the emails saved when running the code.

    May I ask if you can could please offer some input? I want to change to a folder I've created inside my Documents folder but I can't get them there for some unknown reason. I'm very new to all of this so I'm not entirely sure as to how to incorporate other functions into the code if that is required (?). I'm using the default code (the first one in the article). I have a folder called 'OLAttachments' in my Documents folder but I've tried changing the path in the script to the full one that leads to that to no avail.

    I'm at a standstill here and would be more than grateful for any and all help.

    I wish you all the best!

    Reply
  5. Danick says

    February 13, 2023 at 5:43 pm

    Hi Diane

    Been using this VBA for years and am now finding that my Office 365 which has just been updated by the company is now giving that error message,

    "Cannot Open MSG File (Error: We can't open .msg. Its possible the file is already open, or you don't have permission)"..

    The work around is to go into File Explorer and select the file properties and change it to Read-Only. This works, but a real pain to do it every time.

    Here's a ref to the error.

    https://answers.microsoft.com/en-us/outlook_com/forum/all/cannot-open-saved-msg-file/095ff296-5fd1-44fa-955c-61e4f4197430?page=1

    Thought maybe there is a one liner I could add to the VBA that would automatically save the .msg file with read-only property. Do you know if that could be done? Then I'd just make the line in-active if Microsoft ever fixes this thing again. It took them 5 years to fix it the last time...

    Thanks

    Reply
  6. Zack W says

    December 9, 2022 at 12:54 pm

    This is really wonderful - thank you for your contribution!

    Rather than run on selected messages, is there a way to loop through the entire contents of a PST file (including subfolders)? I'm trying to do some mass backups, and this would be incredibly useful.

    Reply
  7. Wim Meeus says

    October 28, 2021 at 4:04 am

    Hi All,

    I used this script with success but faced issues with path/filename length.
    It would be nice that at least the name of the msg file would be shortened till the maximum length.
    I'm not sure how to implement it so any help is appreciated.

    Reply
    • Diane Poremsky says

      October 28, 2021 at 7:56 am

      This block sets the file name -

      sName = Item.Subject
      ReplaceCharsForFileName sName, "-"
      dtDate = Item.ReceivedTime
      sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
      vbUseSystem) & Format(dtDate, "-hhnnss", _
      vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"

      the first two lines use the subject and remove characters that are illegal in the file name. If you have a long subject, you can shorten it - this gets the first 20 characters of the subject.
      sName = left(item.subject, 20)
      This would remove illegal characters instead of replacing them
      ReplaceCharsForFileName sName, ""

      The next part is the received date - in 20211028-080822 format. The reason for using the full time is in the event there are two messages with the same subject and received minute.

      You can shorten it to 2110280808 by removing 2 2's, the -, and the s's from the date format.
      dtDate = Item.ReceivedTime
      sName = Format(dtDate, "yymmdd", vbUseSystemDayOfWeek, _
      vbUseSystem) & Format(dtDate, "hhnn", _
      vbUseSystemDayOfWeek, vbUseSystem)

      This line puts the two together - you can remove '& -' to use "2110280808subject-20-character"
      & "-" & sName & ".msg"

      Reply
  8. Rafael says

    September 9, 2021 at 8:54 am

    Hello Diane,

    Thanks for your script, it has been a of a great help for me for almost 2 years now. Which is fantastic.

    However, last week I updated from MS 2010 to O365 and since then the first time Outlook lauches all the new e-mails that were received overnight (when outlook was closed) are not flagged as new items and not backed up. The scripts starts normally and save all the new messages after outlook is opened, but I miss the automatick backups on the ones received overnight.

    I've been manually saving those few e-mails, but was wondering if you have had (or know about) any similar issue and knows how I can work around it.

    Appreciate your time and Attention

    Reply
    • Diane Poremsky says

      October 20, 2021 at 1:44 pm

      What type off email account are you using? It shouldn't matter... and there should be no differences with the versions.

      Reply
  9. David says

    August 23, 2021 at 1:13 pm

    Your VBA was updated to skip meetings and report/receipt messages. How do you include all selected items.

    Reply
    • Diane Poremsky says

      August 24, 2021 at 12:44 am

      Remove this line and the matching End if. Then it will run on all items.
      If objItem.MessageClass = "IPM.Note" Then

      Reply
      • Raf Verschueren says

        September 28, 2021 at 11:05 am

        Hi Diane,
        If I remove the line and matching End if, I get an error on Set oMail = objItem (Types don't match) when I try to safe a receipt message.

      • Diane Poremsky says

        September 28, 2021 at 12:11 pm

        is objItem and omail dim'd as an object or mailitem? They needs to be object to work on non-email items.

      • Raf Verschueren says

        October 20, 2021 at 5:25 am

        Hi Diane,
         
        Thanks for your response.
        I tried to reply but it can't see my reaction so new attempt.

        The code now is: 
         Dim oMail As Outlook.MailItem
         Dim objItem As Object
         
        When I change Outlook.MailItem into Object I get "Error 438 during execution. This feature or method is not supported by this object."

      • Diane Poremsky says

        October 20, 2021 at 1:42 pm

        The code sample is working for me, for both email and meeting invites. (That's all I have in my test mailbox).

        20210322-005132-subject.msg
        20211020-115819-Declined- .msg <== meeting response
        20210612-131347-Testing moving.msg <== meeting invite

      • Raf Verschueren says

        October 22, 2021 at 5:39 am

        I'm working with Office 365 in Belgium.
        It's not a meeting but a report/receipt message.
        Can that be the problem?

      • Raf Verschueren says

        October 20, 2021 at 5:25 am

        Complete code:

        Option Explicit
        Public Sub SaveMessageAsMsg()
         Dim oMail As Object
         Dim objItem As Object
         Dim sPath As String
         Dim dtDate As Date
         Dim sName As String
         Dim enviro As String
         
          enviro = CStr(Environ("USERPROFILE"))
          For Each objItem In ActiveExplorer.Selection
         
          Set oMail = objItem
          
         sName = oMail.Subject
         ReplaceCharsForFileName sName, "-"
         
         dtDate = oMail.ReceivedTime
         sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
          vbUseSystem) & Format(dtDate, "-hhnnss", _
          vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"
           
          sPath = enviro & "\Documents\"
         Debug.Print sPath & sName
         oMail.SaveAs sPath & sName, olMSG
          
         
         Next
          
        End Sub
         
        Private Sub ReplaceCharsForFileName(sName As String, _
         sChr As String _
        )
         sName = Replace(sName, "'", sChr)
         sName = Replace(sName, "*", sChr)
         sName = Replace(sName, "/", sChr)
         sName = Replace(sName, "\", sChr)
         sName = Replace(sName, ":", sChr)
         sName = Replace(sName, "?", sChr)
         sName = Replace(sName, Chr(34), sChr)
         sName = Replace(sName, "<", sChr)
         sName = Replace(sName, ">", sChr)
         sName = Replace(sName, "|", sChr)
        End Sub

      • Matt B says

        May 18, 2023 at 2:22 pm

        Were you able to get your Received/Read Receipts to save?

        I've also been trying to get this to work for some time. I've tried using *REPORT.IPM.NOTE.IPNRN and REPORT.IPM.NOTE.DR instead of IPM.Note, but neither one worked.
        Nothing works unless it's IPM.Note (which Note can not be NOTE to work.)

        Any further help would be great.

  10. Flavio Moutinho says

    July 25, 2021 at 4:10 pm

    Private WithEvents objSentItems As Items
    
    Private Sub Application_Startup()
    Dim objSent As Outlook.MAPIFolder
    Set objNS = Application.GetNamespace("MAPI")
    Set objSentItems = objNS.GetDefaultFolder(olFolderSentMail).Items
    Set objNS = Nothing
    End Sub
     
    Private Sub objSentItems_ItemAdd(ByVal Item As Object)
      Dim sPath As String
      Dim dtDate As Date
      Dim sName As String
      Dim enviro As String
     
    enviro = CStr(Environ("USERPROFILE"))
       
      sName = Item.Subject
      ReplaceCharsForFileName sName, "-"
     
      dtDate = Item.ReceivedTime
      sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
        vbUseSystem) & Format(dtDate, "-hhnnss", _
        vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"
         
        sPath = enviro & "\Documents\"
      Debug.Print sPath & sName
      Item.SaveAs sPath & sName, olMSG
    End Sub
    
    Reply
  11. Flavio Moutinho says

    July 25, 2021 at 3:32 pm

    Hello, I was in need of a macro so as to send or reply to a message, create a .msg file, I'm not getting it, could you help me?

    Reply
  12. Robert says

    July 10, 2021 at 1:11 pm

    Hello,

    I have been trying to use this script to save the emails from a public folder within Outlook but keep getting the error "Path Not Found". The script works fine with a small test folder under my inbox, so instantly I know the script can't see the Public Folder. I tried to modify the script using the info found here (olPublicFoldersAllPublicFolders ), but I can not get it to work properly for the life of me. Any help you can offer would be greatly appreciated!

    Reply
  13. Michael Petrozelli says

    April 5, 2021 at 3:36 pm

    Hi Diane, a while back you greatly helped me with an Outlook rule script to move an email to a network folder. Now I have to add a timestamp and can't for the life of me get it to work:

    Public Sub saveAttachtoDisk3(olItem As Outlook.MailItem)

      Dim olAttachment As Outlook.Attachment
      Dim SaveFolder As String
        SaveFolder = "\\10.33.XX.XXX\folder\Auto Email Attachments\"
      Dim dateandtime As String
        dateandtime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")
       For Each olAttachment In olItem.Attachments
        olAttachment.SaveAsFile SaveFolder & "\" & olAttachment.DisplayName
        Set olAttachment = Nothing
      Next

      End Sub
    Sub RunScript()
     Dim objApp As Outlook.Application
     Dim objItem As MailItem
     Set objApp = Application
     Set objItem = objApp.ActiveExplorer.Selection.Item(1)
     
     saveAttachtoDisk3 objItem

     End Sub

    It prompts me for Object required, but I'm not sure what else is needed for it.

    Reply
    • Diane Poremsky says

      April 5, 2021 at 8:52 pm

      >> dateandtime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")
      Is not a valid file name.

      Try using this:
      dateandtime = format(Now, "yyyyMMdd_HHmmss")

      olAttachment.SaveAsFile SaveFolder & "\" & dateandtime & olAttachment.DisplayName

      if you need to use the date at the end, you will need to get the file extension and add it.
      ' get the last 5 characters for the file extension
      strExt = Right(olAttachment.DisplayName, 5)
      olAttachment.SaveAsFile SaveFolder & "\" & olAttachment.DisplayName & dateandtime & strExt

      https://www.slipstick.com/developer/code-samples/save-rename-outlook-email-attachments/

      Reply
      • Michael Petrozelli says

        April 6, 2021 at 1:02 pm

        Thanks so much Diane, I notice that it appears to be maybe (?) grabbing the clock time, and was wondering if instead it could do ReceivedTime based on when Outlook is receiving it?

        I checked, and both Outlook and the PC clock are both set to the same exact time UTC Eastern.

      • Diane Poremsky says

        April 8, 2021 at 10:51 pm

        This gets the received time - dtDate = oMail.ReceivedTime

        you could try omail.senton that gets you the time the sender sent it - which should only be a few seconds or so before you receive it.

      • Michael Petrozelli says

        May 20, 2021 at 3:29 pm

        Diane, if I want to get both would it look like this:

        Dim olAttachment As Outlook.Attachment
          Dim SaveFolder As String
            SaveFolder = "xxxxxxxxxx"
          Dim dateandtime As String
            dtDate = oMail.ReceivedTime
          Dim dtDate As Date
            dateandtime = Format(Now, "yyyyMMdd_HHmmss")
          For Each olAttachment In olItem.Attachments
            olAttachment.SaveAsFile SaveFolder & "\" & dateandtime & dtDate & olAttachment.DisplayName
            Set olAttachment = Nothing

      • Michael Petrozelli says

        June 4, 2021 at 1:14 pm

        Sorry to bother you Diane, but would you mind telling me if the below code is scripted properly (May 20th)?

      • Diane Poremsky says

        June 4, 2021 at 4:04 pm

        Oh, sorry. I read it as saying it that is what you got working, not asking me if it was correct. 50 lashes with a cold wet noodle. (It's hot today... a cold noodle might be refreshing, not punishment. LOL)

        The code is good - but you are using 'now' not the received time in dateandtime variable - is that what you wanted? (the DIM need to be before you set the value too.)

         Dim dateandtime As String
         Dim dtDate As Date   

        dtDate = oMail.ReceivedTime
         dateandtime = Format(Now, "yyyyMMdd_HHmmss")
          For Each olAttachment In olItem.Attachments
            olAttachment.SaveAsFile SaveFolder & "\" & dateandtime & dtDate & olAttachment.DisplayName

        If you want the filename to be the received date, use

        dtDate = oMail.ReceivedTime
         dateandtime = Format(dtDate, "yyyyMMdd_HHmmss")
          For Each olAttachment In olItem.Attachments
            olAttachment.SaveAsFile SaveFolder & "\" & dateandtime & olAttachment.DisplayName

        or for a shorter version:
         dateandtime = Format( oMail.ReceivedTime, "yyyyMMdd_HHmmss")
          For Each olAttachment In olItem.Attachments
            olAttachment.SaveAsFile SaveFolder & "\" & dateandtime & olAttachment.DisplayName

        If you want both now and the received date, you need to format the received date.

        dtDate = Format(oMail.ReceivedTime, "yyyyMMdd_HHmmss")
         dateandtime = Format(Now, "yyyyMMdd_HHmmss")
          For Each olAttachment In olItem.Attachments
            olAttachment.SaveAsFile SaveFolder & "\" & dateandtime & dtDate & olAttachment.DisplayName

      • Michael Petrozelli says

        June 4, 2021 at 4:34 pm

        You're the best, thanks so much Diane!!!

  14. Andy says

    December 11, 2020 at 4:03 am

    Hi,

    This is awesome, thanks!

    One question: if I run the code on a lot of selected emails the code stops running after 200 emails because it seems to think I have 200 emails "open" and my system admin has set a limit on this. Is there something that can be added to the code that will effectively close each mail item after it's been saved to the file system in order to prevent this?

    Thanks.

    Reply
    • Diane Poremsky says

      April 5, 2021 at 8:55 pm

      close the message after saving:
      oMail.SaveAs sPath & sName, olMSG
      oMail.Close olDiscard

      Reply
  15. Andy says

    December 11, 2020 at 3:31 am

    Hi,

    This is awesome, thanks!

    One question: if I run the code on a lot of selected emails the code stops running after 200 emails because it seems to think I have 200 emails "open" and my system admin has set a limit on this. Is there something that can be added to the code that will effectively close each mail item after it's been save to the file system in order to prevent this?

    Thanks.

    Reply
  16. mastho sonander says

    December 10, 2020 at 12:48 pm

    Hello, this post, just to say Thank You!
    You saved my day :-)
    Take care

    Reply
  17. Gustavo Britto says

    September 25, 2020 at 7:46 pm

    Good night Diane, how are you? Please, could you help me? I have a doubt, how do I do if the files exist he warns before overwriting for the user to be aware.

    Reply
    • Diane Poremsky says

      September 27, 2020 at 11:17 pm

      You want a warning if the file exists?

      You'd use something like this:

      if Len(Dir(sName)) > 0 then
      ' save
      end if

      Reply
  18. Yohann says

    July 22, 2020 at 6:09 am

    Hello, how can we adapt it to apply to the message that has just been sent? Thank you! Yohann

    Reply
    • Diane Poremsky says

      July 22, 2020 at 9:21 am

      You would use an itemadd macro and watch the sent folder. The macro in the heading 'Save messages as they are sent' will do it.

      Reply
      • Yohann says

        July 28, 2020 at 3:49 am

        Hello Diane, many thanks.
        I have now 2 macros: the one watching the sent folder, so that I can save the "just sent" email; the second one enables to save any email or group of emails in any folder (I select the email(s) in any folder of the main window of Outlook (Inbox, Sent Items, etc.), then I launch the macro).
        It is quite practical, but the must-have would also to enable the saving of an email that is opened in its own window; for example, I open any email by double-clicking, then I can save it directly from that opened window, without having to go back into the folder of the main window of Outlook in which the email is stored.
        Do you know if there is a way to define the window that has the focus please?
        Thank you in advance.
        Yohann

      • Diane Poremsky says

        September 18, 2020 at 12:07 pm

        That is possible - use the GetCurrentItem function to work with either opened or selected items. (It will only work with 1 open item, not all if you have several open)

        This line goes in the macro, replacing the one that uses the selected item (replace objitem with the object name you are using)

        Set objItem = GetCurrentItem()

        and get the function from here:
        https://www.slipstick.com/developer/outlook-vba-work-with-open-item-or-select-item/

      • Yohann says

        September 21, 2020 at 3:51 am

        Excellent; thank you very much Diane

      • Yohann says

        January 25, 2021 at 2:58 am

        Hello Diane,
        happy new year!
        My macros work quite well, but there is something boring. Indeed, for I use "olFolderSentMail" to suggest the recording of each sent email, if we open Outlook in a second environment (e.g. on another computer) after having sent some emails in a 1st environment, when that other Outlook session updates (including the Sent Mail folder), the macro runs to suggest the recording of each email that has already been sent and eventually recorded in the 1st session. If there is only one email, that's okay (but not great), but if there are several ones...

        Could you please tell me how we can get around that difficulty?
        Thank you in advance.

        Yohann

      • Diane Poremsky says

        April 8, 2021 at 10:53 pm

        to avoid that, you need to set a property on the message after it is processed - this could be a hidden custom field, a category, a completed flag etc - then check for that value and skip any that have that field set.

  19. Prado says

    February 3, 2020 at 9:44 am

    Hi Diane,

    Thanks a lot, this all save a lot of time.

    A took the "Save messages as they are sent" code and apply the Nik reply changes.

    Therefore, now all incoming messages that go through the rules are saved in a specific folder.

    But, i'd like to save in different folder, as an exemple: messages that has in the subject "Company 01-2020", the message will be saved in the 01-2020 folder. Could you help me doing that?

    Thanks in advance and sorry for my english :/

    Reply
  20. Gary Blair says

    December 9, 2019 at 11:15 am

    Hi Diane,
    I'm a total novice with VBA, I started with what you and others have provided in different posts and have been able to put together a Macro to save selected emails as .msg to a folder that I can select/create.
    It's working great but I can't figure out how to have it automatically rename a file by adding filename(1).msg if the files exists instead of overwriting.
    Hope you can help, here's what I've got.

    Public Sub Save_Email_As_Msg_Select_Folder()
    Dim oMail As Outlook.MailItem
    Dim objItem As Object
    Dim sPath As String
    Dim dtDate As Date
    Dim sName As String
    Dim SenderName As String
    Dim enviro As String
    Dim strFolderpath As String

    enviro = CStr(Environ("USERPROFILE"))

    strFolderpath = BrowseForFolder(enviro & "\\")

    For Each objItem In ActiveExplorer.Selection
    If objItem.MessageClass = "IPM.Note" Then
    Set oMail = objItem

    sName = oMail.Subject
    ReplaceCharsForFileName sName, "-"

    SenderName = oMail.SenderName
    ReplaceCharsForFileName SenderName, "-"

    dtDate = oMail.ReceivedTime
    sName = Format(dtDate, "yyyy-mm-dd_h-nn-ss AM/PM", vbUseSystemDayOfWeek, _
    vbUseSystem) & "_" & sName & "_From-" & SenderName & ".msg"

    sPath = strFolderpath & "\"
    Debug.Print sPath & sName
    oMail.SaveAs sPath & sName, olMSG

    End If
    Next

    End Sub

    Private Sub ReplaceCharsForFileName(sName As String, _
    sChr As String _
    )
    sName = Replace(sName, "'", sChr)
    sName = Replace(sName, "*", sChr)
    sName = Replace(sName, "/", sChr)
    sName = Replace(sName, "\", sChr)
    sName = Replace(sName, ":", sChr)
    sName = Replace(sName, "?", sChr)
    sName = Replace(sName, Chr(34), sChr)
    sName = Replace(sName, "", sChr)
    sName = Replace(sName, "|", sChr)
    End Sub

    Function BrowseForFolder(Optional OpenAt As Variant) As Variant
    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

    Set ShellApp = Nothing
    Select Case Mid(BrowseForFolder, 2, 1)
    Case Is = ":"
    If Left(BrowseForFolder, 1) = ":" Then GoTo Invalid
    Case Is = "\"
    If Not Left(BrowseForFolder, 1) = "\" Then GoTo Invalid
    Case Else
    GoTo Invalid
    End Select
    Exit Function

    Invalid:
    BrowseForFolder = False
    End Function

    Reply
  21. reach4thesky says

    September 13, 2019 at 4:07 pm

    how to add timestamp after .msg extension?

    Reply
    • Diane Poremsky says

      September 14, 2019 at 12:00 am

      I'm not sure I'd do that but its just a matter of changing the order in sname variable:

      sName = sName & ".msg" & Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
      vbUseSystem) & Format(dtDate, "-hhnnss", _
      vbUseSystemDayOfWeek, vbUseSystem)

      Reply
  22. Shahrooz Bral says

    July 12, 2019 at 9:49 am

    Hi Daine,
    wishing you a good day.
    I am using your code SaveMessageAsMsg() but when i search a email in All mailboxes and after finding email , this function does not work.
    please let us know how to change a part of code to use it.

    Reply
    • Diane Poremsky says

      September 14, 2019 at 12:13 am

      it's not working on the search results? The first 2 should work on search results - I'll double check.

      Reply
  23. Michelle says

    February 7, 2019 at 11:31 pm

    Hello Diane,

    Thank you for the fabulous code--it's a real time saver!

    Would you know how to run this macro and have automatic replies included? They are not saved when the macro is run.

    I am new to this but have tried looking in the comments and searching Google, and have not found my answer. I'd really appreciate it if you could help me out.

    Thank you,

    Michelle

    Reply
  24. Isaac Cheng says

    December 12, 2018 at 9:52 pm

    Hi Daine,

    Thanks for the sharing.

    However, when I run the code, it appears Run-time error. I tried to debug the highlighted row is on oMail.SaveAs sPath & sName, olMSG

    What i am trying to do is I would like to save a specific email with the same SUBJECT+current date to a specific folder with named 'today date.

    Do I need to change any parameter from your code? Also the place i would like to save is a company network drive, sth like M:\HK\Dailytest\

    Thanks.

    Reply
    • Diane Poremsky says

      December 13, 2018 at 12:10 am

      It may be the fact that you are trying to save to a network drive - Outlook (and macros) can be funny about network drives. On the other hand, in looking at the screenshot, it looks like you are using the original code, which saves to the user's Documents folder.
      Open the immediate window - (Ctrl+G or look on the View menu) - the Debug.print line writes the file path there so you can see if its correct.

      Reply
  25. Andy says

    November 30, 2018 at 12:36 pm

    Diane, I have been using your program and it is great (here it comes)...but, I noticed if a start out with 3,180 emails when I finish running your program that I only get 2,924 .msg files? Figuring that it's encountering messages with the same received date and subject that its simply overwriting the files. So I tried changing the sname item to EntryID which is the closest thing I can find to a unique identifier for email and the numbers are the same? Do you have any suggestions?
    Thanks

    Reply
    • Diane Poremsky says

      December 4, 2018 at 11:00 pm

      I would use the current (saved) date and time (its a shorter value than the entryid) or number the saves (i have a macro here somewhere that does this).
      You could use the current time (as hhnnss) as a unique number:
      sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
      vbUseSystem) & Format(dtDate, "-hhnnss", _
      vbUseSystemDayOfWeek, vbUseSystem) & Format(Time, "-hhnnss-") & sName & ".msg"

      Reply
      • Andy says

        December 7, 2018 at 7:06 am

        Diane, I want to thank you and apologize. When I ask my question above, I broke the cardinal rule. That rule was to read all of the prior comments before posting a new question. In one your prior response to a comment you mentioned an icount feature. This icount feature coupled with the subject provided me with enough uniqueness. So no overwrites! In my application of your code current time was not unique enough. I can't tell you how much time this code will save me! Again thanks, happy holiday and a prosperous new year!

      • Diane Poremsky says

        December 13, 2018 at 12:11 am

        You are forgiven... 221 comments is a bit much to make you read all of them. :)

        Glad you got it solved.

  26. Deros says

    July 18, 2018 at 4:34 pm

    The code above works great on normal email messages. the code uses "IPM.Note"...
    For Each objItem In ActiveExplorer.Selection
    If objItem.MessageClass = "IPM.Note" Then
    Set oMail = objItem

    What do I need to change in the code to allow it to save messages that have a MessageClass of REPORT.IPM.note.DR or REPORT.IPM.Note.Relayed

    Reply
    • Diane Poremsky says

      December 5, 2018 at 10:57 am

      Since they all contain ipm.note, check for that in the message class name:
      If instr(objItem.MessageClass, "IPM.Note") > 0 Then

      Reply
  27. Hola says

    July 3, 2018 at 10:02 am

    I suggest to add a line to account for long email titles resulting in too long filename:
    If Len(sName) > 250 Then sName = Left(sName, 250) & ".msg"

    Reply
  28. Steve says

    June 7, 2018 at 4:27 pm

    `Option Explicit
    Public WithEvents objSentItems As Items
    Public Sub Application_Startup()
    Dim objSent As Outlook.MAPIFolder
    Dim objNS As Object
    Set objNS = Application.GetNamespace("MAPI")
    Set objSentItems = objNS.GetDefaultFolder(olFolderSentMail).Items
    Set objNS = Nothing

    End Sub

    Public Sub objSentItems_ItemAdd(ByVal Item As Object)
    Dim sPath As String
    Dim dtDate As Date
    Dim sName As String
    Dim enviro As String

    UserForm1.Show

    ‘ Works until here, opens UserForm 1 allows section and allows pressing of OKButton_Click() but then ‘gets errors shown below – see next to last sub, (1) objSentItems2_ItemAdd at end.
    'The sub below, Public Sub objSentItems2_ItemAdd(ByVal Item As Object),
    'is what the the Oneonta Button on UserForm1 will call to put in Oneonta Folder
    'I put the whole thing in the user form. That didnt work so I took out the body and just left the call in
    ‘did not work either

    End Sub

    Public Sub objSentItems2_ItemAdd(ByVal Item As Object)
    Dim sPath As String
    Dim dtDate As Date
    Dim sName As String
    Dim enviro As String
    sName = Item.Subject
    ReplaceCharsForFileName sName, "-"
    dtDate = Item.ReceivedTime
    sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
    vbUseSystem) & Format(dtDate, "-hhnnss", _
    vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"

    'sPath below works perfectly in your orignal macro
    sPath = "\\HVSBS\PROJECTS\Oneonta\"

    End Sub

    Public Sub ReplaceCharsForFileName(sName As String, _
    sChr As String _
    )

    sName = Replace(sName, "", sChr)
    sName = Replace(sName, "*", sChr)
    sName = Replace(sName, "/", sChr)
    sName = Replace(sName, "\", sChr)
    sName = Replace(sName, ":", sChr)
    sName = Replace(sName, "?", sChr)
    sName = Replace(sName, Chr(34), sChr)
    sName = Replace(sName, "", sChr)
    sName = Replace(sName, "|", sChr)

    End Sub

    Private Sub OKButton_Click()

    Dim objSentItems2_ItemAdd as Variant

    objSentItems2_ItemAdd

    ‘(1) if I don’t define objSentItems2_ItemAdd, I get – Variable not Defined. If I do define it, I get – ‘Expected Sub, Function or Property.
    ‘Have tried making all the subs public and putting them in different modules but no luck.
    ‘Thanks for looking Diane!

    End Sub

    Private Sub ONEONTA_Click()

    End

    Reply
    • Diane Poremsky says

      December 13, 2018 at 12:34 am

      Ok... (I added the macro to the page as well).
      This goes into a module - it can't be declared in Thisoutlooksession.
      Public lstNum As Long

      This goes into Thisoutlooksession
      'Option Explicit
      Public WithEvents objSentItems As Items

      Public Sub Application_Startup()
      Dim objSent As Outlook.MAPIFolder
      Dim objNS As Object
      Set objNS = Application.GetNamespace("MAPI")
      Set objSentItems = objNS.GetDefaultFolder(olFolderSentMail).Items
      Set objNS = Nothing
      End Sub
      Public Sub objSentItems_ItemAdd(ByVal Item As Object)
      Dim dtDate As Date
      Dim sName As String
      UserForm1.Show

      Select Case lstNum
      Case -1
      ' -1 is what you want to use if nothing is selected
      sPath = "C:\Users\slipstick\Documents\"
      Case 0
      sPath = "C:\Users\slipstick\Documents\Email Attach\"
      Case 1
      sPath = "C:\Users\slipstick\Documents\pics\"
      Case 2
      sPath = "C:\Users\slipstick\Documents\Balsam Lake\"
      End Select

      sName = Item.Subject
      ReplaceCharsForFileName sName, "-"
      dtDate = Item.ReceivedTime
      sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
      vbUseSystem) & Format(dtDate, "-hhnnss", _
      vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"

      Debug.Print sPath & sName
      Item.SaveAs sPath & sName, olMSG
      End Sub

      Public Sub ReplaceCharsForFileName(sName As String, _
      sChr As String _
      )
      sName = Replace(sName, "", sChr)
      sName = Replace(sName, "*", sChr)
      sName = Replace(sName, "/", sChr)
      sName = Replace(sName, "\", sChr)
      sName = Replace(sName, ":", sChr)
      sName = Replace(sName, "?", sChr)
      sName = Replace(sName, Chr(34), sChr)
      sName = Replace(sName, "", sChr)
      sName = Replace(sName, "|", sChr)
      End Sub

      This in the userform - I'm using a list box so the paths are all visible in the list box, rather than a combobox menu
      Private Sub UserForm_Initialize()
      With ListBox1
      .AddItem "Email Attach"
      .AddItem "pics"
      .AddItem "Balsam Lake"
      End With
      End Sub

      Private Sub btnOK_Click()
      lstNum = ListBox1.ListIndex
      Unload Me
      End Sub

      Reply
  29. Steve says

    June 7, 2018 at 4:24 pm

    Hi Diane, how have your been? Fine I hope.

    I have your 'Save messages as they are sent' macro working perfectly with your help. I'm trying to use a UserForm to open on sending an email that will give me a few choices of what folder to save the email in.

    I don't have enough experience with optional arguments and private/public subs though to make it work. Would appreciate your thoughts here.

    Code below with symptoms

    Reply
    • Diane Poremsky says

      December 13, 2018 at 12:18 am

      I have a sample at https://www.slipstick.com/developer/code-samples/vba-userform-sample-select-list-templates/ that picks templates. The process is the same for file paths. (Sorry I missed this earlier.)

      Reply
  30. jitender singh says

    February 15, 2018 at 2:19 am

    Change Outlook 2007 Default message save format to msg instead of html

    Reply
    • Diane Poremsky says

      February 15, 2018 at 7:09 pm

      Yeah... but its about 3 or 4 steps more than you need with a macro. :)

      Reply
  31. shermaine says

    September 27, 2017 at 2:50 am

    Hi Diane,

    Thank you for sharing these codes on your website, really appreciate it.

    I am using the 'Pick the Folder Location' code and an error keeps popping up at the omail.SaveAs sPath & sname, olMSG line: 'Run-time error '13': Type mismatch'.

    Basically the user would start from the default root folder (Trusted documents) and open subfolders (depending on the coname)/create new folders and the email would be saved in the folders.

    I have tried changing Dim omail As Outlook.MailItem and olMSG As MailItem to Dim omail As Object and Dim olMSG as Object respectively and also tested whether the BrowseForFolder returns the full file path but these don't seem to be what's the problem here.

    Would be great if you could take a look at my code and see if anything else could be causing the error?
    ---------------------------------------------------------------------------------------------------------
    Option Explicit
    Public Sub SaveMessageAsMsg()

    'Dim oMail As Object
    Dim omail As Outlook.MailItem
    Dim objItem As Object
    Dim dtDate As Date
    Dim coname, sname, sPath, strfolderpath As String
    Dim olMSG As MailItem
    Dim irow As Long
    Dim ws As Worksheet

    Set ws = Worksheets("New Slate")

    irow = ws.Cells.Find(What:="*", SearchOrder:=xlRows, _
    SearchDirection:=xlPrevious, LookIn:=xlValues).Row + 1

    coname = Cells(irow - 1, 2)
    strfolderpath = BrowseForFolder("C:\Users\engw\Documents\Trusted Documents\" & coname)

    For Each objItem In ActiveExplorer.Selection
    If objItem.MessageClass = "IPM.Note" Then
    Set omail = objItem

    sname = omail.Subject

    sPath = strfolderpath & "\"
    Debug.Print sPath & sname
    MsgBox (sPath)
    omail.SaveAs sPath & sname, olMSG

    Cells(irow - 1, 13).Value = strfolderpath

    End If
    Next

    End Sub

    Thank you in advance Diane! :)

    Reply
    • Diane Poremsky says

      October 8, 2017 at 9:36 pm

      does it work if you remove coname from the path? strfolderpath = BrowseForFolder("C:\Users\engw\Documents\Trusted Documents\" & coname)
      It can be picky with variables...

      Reply
  32. darren says

    September 14, 2017 at 1:55 pm

    Hi Diane,
    I am a new user to macro and VBA. My company wants to save the email in msg folder with the format of "YYMMDD-HHmm-SenderName-RecipientName-Subject.msg". Therefore, I was trying to use the code"Save Selected Email Message as .msg File". What I did was to go to "This outlookSession" and paste the code-> hit save -> restart outlook-> double click outlook session-> hit play, but it does not seem to work. By not working the code is not running at all
    What I did was to hit "save as" at the email. I just wonder if there is a specific way to save the email to make the code works.

    Reply
    • Diane Poremsky says

      September 14, 2017 at 3:13 pm

      Do you get any error messages?
      Did you change the macro security?

      The macro for SaveMessageAsMsg doesn't need to be in thisoutlooksession - it is run manually, so you can put it in a new module. To make it easier, at a button for it to the ribbon - then you just need to click the button after selecting a message.

      Reply
  33. Nik says

    August 29, 2017 at 2:35 am

    Hello Diane,

    how to modify the 1. code of "Save Selected Email Message as .msg File" to save the incoming e-mails via the rule (in the rule assistant via executing a script)?

    The original code is with the line "For Each objItem In ActiveExplorer.Selection" which automatically prevents to select the correct e-mail. Witch line have I to mode to get the correct focus (= to process the e-mails that are filtered via the rule)?

    Thanks
    Nik

    Reply
    • Diane Poremsky says

      August 30, 2017 at 12:44 am

      Response is at https://forums.slipstick.com/threads/95040-save-selected-email-message-as-msg-file/#post-349660

      Reply
      • Nik says

        August 30, 2017 at 12:57 am

        perfect ;-)! Now the focus is set correct.

  34. Miyamoto Kouta says

    April 24, 2017 at 9:44 am

    Hi, Diane!
    I'm trying to use the code in "Save messages as they are sent" for Outlook 10 but doesn't work well.
    Have something between O10 and O13 in this sense (of arguments or applications) in these code that could cause some trouble?

    Reply
    • Diane Poremsky says

      May 25, 2017 at 12:23 pm

      These macros should definitely work in all current versions. Are you getting any error messages? Remove error handling so you can see where it fails.

      Reply
  35. Anand says

    January 16, 2017 at 9:08 am

    Everything works great except one thing. This code is updated to avoid the read receipts messages. I want to save the read receipts too. Please let me know how could i do it? Urgent.

    Reply
    • Diane Poremsky says

      February 6, 2017 at 8:56 am

      You need to also do reports message class (or, to do all, remove the if ipm.notes line AND change Dim oMail As Outlook.MailItem to Dim oMail As object.

      Reply
      • Anand says

        March 7, 2017 at 6:16 pm

        Followed as per your alternate option. Saves other emails as the same. But when it comes to read receipts, error '438' pops up. Please advice. Below is the edited module as per your comment.

        Option Explicit
        Public Sub SaveMessageAsMsg()
        Dim oMail As Object
        Dim objItem As Object
        Dim sPath As String
        Dim dtDate As Date
        Dim sName As String
        Dim enviro As String
        Dim strFolderpath As String

        enviro = CStr(Environ("USERPROFILE"))
        strFolderpath = BrowseForFolder(enviro & "123")

        For Each objItem In ActiveExplorer.Selection

        Set oMail = objItem

        sName = oMail.Subject
        ReplaceCharsForFileName sName, "-"

        dtDate = oMail.ReceivedTime
        sName = Format(dtDate, "yyyy.mm.dd", vbUseSystemDayOfWeek, _
        vbUseSystem) & Format(dtDate, "-hh.nn.ss", _
        vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"

        sPath = strFolderpath & ""
        Debug.Print sPath & sName
        oMail.SaveAs sPath & sName, olMSG

        Next

        End Sub

      • Diane Poremsky says

        March 7, 2017 at 9:41 pm

        step through it and see which lines it fails on, or add msgbox oMail.Subject, oMail.ReceivedTime after Set oMail = objItem then step through it so you can see if the fields have values.

      • Anand says

        March 13, 2017 at 2:08 pm

        This line has the error 438. Tried variations. Nothing working out.
        dtDate = oMail.ReceivedTime

      • Diane Poremsky says

        March 14, 2017 at 12:44 am

        Is the message it fails on an email from someone or a read receipt or other non-message item?

      • Anand says

        March 15, 2017 at 2:55 pm

        It fails on read receipt. Please provide a code which save all the items in the inbox. Please and thank you.

      • Diane Poremsky says

        March 15, 2017 at 3:25 pm

        Try changing
        Dim oMail As Outlook.MailItem
        to
        Dim oMail As Object

        The macro at https://www.slipstick.com/developer/macro-move-aged-mail/#case shows another way to do it - you could use this method to get the date if using it in the filename.

      • Anand says

        April 6, 2017 at 3:34 pm

        Tried everything :( Does not seem to work. Please see the below code and help me get this.

        Option Explicit
        Public Sub SaveMessageAsMsg()
        Dim oMail As Object
        Dim objItem As Object
        Dim sPath As String
        Dim dtDate As Date
        Dim sName As String
        Dim enviro As String
        Dim strFolderpath As String

        enviro = CStr(Environ("USERPROFILE"))
        strFolderpath = BrowseForFolder(enviro & "123")

        For Each objItem In ActiveExplorer.Selection

        Set oMail = objItem

        sName = oMail.Subject
        ReplaceCharsForFileName sName, "-"

        dtDate = oMail.ReceivedTime
        sName = Format(dtDate, "yyyy.mm.dd", vbUseSystemDayOfWeek, _
        vbUseSystem) & Format(dtDate, "-hh.nn.ss", _
        vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"

        sPath = strFolderpath & ""
        Debug.Print sPath & sName
        oMail.SaveAs sPath & sName, olMSG

        Next

        End Sub

      • Diane Poremsky says

        May 25, 2017 at 12:34 pm

        Sorry for missing this earlier.

        if you check your path, it's not valid:
        enviro = CStr(Environ("USERPROFILE"))
        Debug.Print enviro & "123"

        There is no slash after the username:
        Returns C:\Users\MaryContrary123
        use
        enviro = CStr(Environ("USERPROFILE"))
        enviro = enviro & "\"
        strFolderpath = BrowseForFolder(enviro & "123")

        (if wordpress removes the slash, there is on in the double quotes. It will probably also screw up the 'and' sign)

      • mattgreenbean says

        May 22, 2018 at 3:00 pm

        I have the
        sSenderName = oMail.SenderName
        included in my macro which stops the macro from working as a delivery/read receipt doesn't have a sender name. Is there a way to skip the sender name if there is none?

      • Diane Poremsky says

        July 3, 2018 at 11:43 am

        Sorry I missed this earlier - use an If statement:
        if sSendername = "" then exit sub
        you may want or need to test it earlier with
        if oMail.SenderName = "" then exit sub

  36. Kaustubh Thakur says

    December 21, 2016 at 5:04 pm

    This is awesome! I've been looking for a similar code for a while! Many thanks!
    Any chance of modifying the code so it automatically stores the .MSG file in the above "date and time" format every time I drag an email into a windows folder?

    That would be an ideal solution for my team's needs. Thanks in advance and look forward to hearing back

    Reply
    • Diane Poremsky says

      February 6, 2017 at 9:01 am

      Not that I am aware of using an Outlook macro. You'd need a utility that watched windows folders and could make the change.

      Reply
  37. Hudson says

    October 21, 2016 at 1:43 pm

    this is working excellent , needed small changes in it. email is saving with what ever name that is in subject can this be more dynamic and save with "Memo Number" that has come in email body .

    Reply
  38. Rob J says

    October 17, 2016 at 11:51 am

    I too am having issues with oMail.SaveAs sPath & sName, olMSG generating an error. All Paths are correct, I have permission and can save there manually? I am using the above code as posted, OL2010

    Reply
    • Diane Poremsky says

      October 17, 2016 at 11:51 pm

      Are you trying to use a network path? Does it work with a local path? Does the path exist?

      Reply
      • Rob J says

        October 18, 2016 at 8:02 am

        Hi Diane, and thank you for replying. I have tried both network and local. The path exists and I can drag messages into it. When I try to run, the error is RT error 287. App- defined or obj-defined error. During debug if I hover over the line that errors, sPath and sName both appear to be correct:

        Public Sub SaveMessageAsMsg()
        Dim oMail As Outlook.MailItem
        Dim objItem As Object
        Dim sPath As String
        Dim dtDate As Date
        Dim sName As String
        Dim enviro As String

        enviro = "P:"
        For Each objItem In ActiveExplorer.Selection
        If objItem.MessageClass = "IPM.Note" Then
        Set oMail = objItem

        sName = Left(oMail.Subject, 45)
        ReplaceCharsForFileName sName, "-"

        dtDate = oMail.ReceivedTime
        sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
        vbUseSystem) & Format(dtDate, "-hhnnss", _
        vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"

        sPath = enviro & "\OLDump"
        oMail.SaveAs sPath & sName, olMSG

        End If
        Next

        End Sub

      • Diane Poremsky says

        October 18, 2016 at 10:52 am

        I think it is this - it needs an ending \
        sPath = enviro & "\OLDump"
        you are trying to save it in the root of P, named oldump20161018-105122.msg

        Tip: to double check paths when errors come up do this: (or use debug.print and check the immediate window in the vba editor)
        sPath = enviro & "\OLDump"
        msgbox sPath & sName
        oMail.SaveAs sPath & sName, olMSG

      • Rob J says

        October 18, 2016 at 11:35 am

        So I fixed those things, all looks good, but still errororing on that line. I've linked some screenshots .. https://goo.gl/photos/uXK8pBTpuDuLBUZCA

      • Diane Poremsky says

        October 18, 2016 at 11:38 am

        That is saving to A, which is typically the floppy disk. Do you have a drive at A: ?

      • Rob J says

        October 18, 2016 at 12:33 pm

        Yes, I do. I use it for testing, but it is a local drive. I have also tried a folder on C and a network location. Same error each time.

  39. Pierre-Luc says

    October 16, 2016 at 5:12 pm

    Hello. I'm using the macro SaveMessageAsMsg().
    Will there be a way to modify the macro in a manner where the .msg files will not include any attachment ? However attachements should NOT be deleted from the original e-mail.

    Thank you

    Reply
    • Diane Poremsky says

      October 16, 2016 at 11:27 pm

      Try this modification -
      Set oMail = objItem
      Dim oAttachments As Attachments
      Dim lngAttachmentCount As Long
      Set oAttachments = oMail.Attachments
      lngAttachmentCount = oAttachments.Count
      ' Loop through attachments until attachment count = 0.
      While lngAttachmentCount > 0
      oAttachments(1).Delete
      lngAttachmentCount = oAttachments.Count
      Wend
      sName = oMail.Subject

      Then at the end - discard the changes.
      oMail.SaveAs sPath & sName, olMSG
      oMail.Close olDiscard
      End If
      Next

      It might look like the attachments are gone, but if you select another message then come back, the attachments will be there.

      Reply
  40. Nick says

    September 30, 2016 at 5:12 pm

    Thank you so much for this code and the detailed explanation as to how to implement it. Everything worked as you described from creating the macro, browsing for a folder to signing it and creating a button on the toolbar. Very nicely done. I was using the “Save as” dialog in Outlook for months and today thought of getting an addin or something to automate the process. Lots of choices out there, but I’m a little frugal  – so I was very happy to find your page. Now I’m trying to add a few extra lines of code to get it to remember the last path used before using the default. Haven’t had any success yet, but even so, this is so much better than before. Thanks again and have a great weekend!!

    Reply
    • Diane Poremsky says

      October 17, 2016 at 12:01 am

      i haven't been able to make it work and don't think it's possible. sorry.

      Reply
      • Nick says

        October 20, 2016 at 4:42 pm

        So I stopped trying to get it to work using one button and just broke it up using two. At the end of the first SaveMessageAsMsg(), I end it with previousPath = sPath.

        The just created another Public sub called SaveAnotherMessageAsMsg()

        For errors, I used:

        If previousPath = vbNullString Then
        strFolderpath = BrowseForFolder(enviro & "\Documents\...")
        Else
        strFolderpath = BrowseForFolder(previousPath)
        End If

        So now I have two buttons on the ribbon instead of one. No big deal.

        Thanks again...

  41. Matt says

    August 16, 2016 at 10:03 pm

    Hi Diane, Loved the Macro works beautifully.

    At the moment I have the BrowseForFolder Function in my module section of VBA and the remaining in the ThisOutlookSession Section and it works great.

    I am looking to duplicate the code essentially so that I can have two buttons that go to two different places on my computer (Current Jobs & Completed jobs).

    In my eyes this should be fairly simple, all I should have to do is change the file directory for my duplicated code.

    But I am struggling to get it to work as I don't know where to paste my new code? Do I put it under my current code in the ThisOutlookSession section? or do I need to make an additional ThisOutlookSession Section, if so how do I do that?

    Thanks in Advance,

    Matt.

    Reply
    • Diane Poremsky says

      August 17, 2016 at 12:11 am

      Because the macro is not an automatic macro, it should be in a module, not thisoutlooksession. You don't need to copy the entire macro, you just need to make a new "stub" macro to pass the path string to the main macro.

      If you want to hardcode the paths, remove this line:
      strFolderpath = BrowseForFolder(enviro & "FILEDIRECTORY")

      Move Dim strFolderpath As String so it's just under option explicit.
      Change Public in the macro name to Private
      Create a new macro that sets strFolderpath: (in the same module as SaveMessageAsMsg) - i always put the stub macro at the top of the page with the main macro under it - i think it's a little neater and easier to read but it really don't matter which is first.
      Sub mynewmacro ()
      strFolderpath = "c:\newpath"
      SaveMessageAsMsg
      End sub

      Copy the macro above, change the name and file path.

      Reply
      • Matt says

        August 19, 2016 at 2:54 am

        Diane,

        Thanks very much for that, but I still seem to be having difficulty with this sorry, the below code is all in module1 but still seems to not be working, any help would be greatly appreciated.

        `Option Explicit
        Dim strFolderpath As String

        Sub CurrentQuotes()
        strFolderpath = "\\Current Quotes FILE DIRECTORY"
        SaveMessageAsMsg
        End Sub

        Private Sub SaveMessageAsMsg()
        Dim oMail As Outlook.MailItem
        Dim objItem As Object
        Dim sPath As String
        Dim dtDate As Date
        Dim sName As String
        Dim enviro As String

        enviro = CStr(Environ("\\Current Jobs FILE DIRECTORY"))

        For Each objItem In ActiveExplorer.Selection
        If objItem.MessageClass = "IPM.Note" Then
        Set oMail = objItem

        sName = oMail.Subject
        ReplaceCharsForFileName sName, "-"

        dtDate = oMail.ReceivedTime
        sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
        vbUseSystem) & Format(dtDate, "-hhnnss", _
        vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"

        sPath = strFolderpath & "\"
        Debug.Print sPath & sName
        oMail.SaveAs sPath & sName, olMSG

        End If
        Next

        End Sub

        Private Sub ReplaceCharsForFileName(sName As String, _
        sChr As String _
        )
        sName = Replace(sName, "'", sChr)
        sName = Replace(sName, "*", sChr)
        sName = Replace(sName, "/", sChr)
        sName = Replace(sName, "\", sChr)
        sName = Replace(sName, ":", sChr)
        sName = Replace(sName, "?", sChr)
        sName = Replace(sName, Chr(34), sChr)
        sName = Replace(sName, "", sChr)
        sName = Replace(sName, "|", sChr)
        End Sub

        Function BrowseForFolder(Optional OpenAt As Variant) As Variant
        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

        Set ShellApp = Nothing
        Select Case Mid(BrowseForFolder, 2, 1)
        Case Is = ":"
        If Left(BrowseForFolder, 1) = ":" Then GoTo Invalid
        Case Is = "\"
        If Not Left(BrowseForFolder, 1) = "\" Then GoTo Invalid
        Case Else
        GoTo Invalid
        End Select
        Exit Function

        Invalid:
        BrowseForFolder = False
        End Function

        Thanks,

        Matt.

      • Diane Poremsky says

        August 19, 2016 at 12:43 pm

        if you aren't using the user's folder path (C:\Users\diane), remove enviro = CStr(Environ("\\Current Jobs FILE DIRECTORY")) - it's a shortcut to the user path. It's not preventing the macro from running, since its not actually used but it would not work if you tried using it.

        It's working here with a local folder. It's working with a network folder - i needed to be logged into the network computer before running the macro.

      • Matt says

        August 22, 2016 at 11:02 pm

        Sorry Diane, I am still having isses. Specifically with the line "oMail.SaveAs sPath & sName, olMSG" it keeps telling me it has a run-time error '-2147287037 "the Operation Failed."

        is it the wording of this line? I had no issues with this line prior.

        Thanks in advance.

      • Diane Poremsky says

        August 22, 2016 at 11:08 pm

        The macro worked here with a local path and a network path, so the code is good.

        Add Debug.print sPath & sName
        before that line and run the macro - look in the immediate window, is the path correct?

        Does it work if you use a local path? There aren't too many things that can cause problems - if you are writing to a network drive, the drive needs to be open/logged in in windows.

      • Matt says

        August 23, 2016 at 10:20 pm

        The path is correct - It is a network path (\\Server\Folder\Subfolder\Subfolder\Current Jobs) - for current jobs
        (\\Server\Folder\Subfolder\Subfolder\Current Quotes) - for current quotes

        If the network drive is the issue how is that resolved?

      • Diane Poremsky says

        August 23, 2016 at 10:39 pm

        Do you need to enter a password to open those folders when you first log on the computer?

        Try mapping the drives and use the mapped path - see if that works better.

      • Nick says

        October 1, 2016 at 10:07 am

        Sorry to get into this a little late. I had the same issue but with only some emails. The reason being that the path was too long. Too many characters in the subject line. It wouldn't even work with the normal Outlook Save As dialog. Strange thing is I added code to shorten the subject line to 45 characters - but that still didn't help. Probably need to find a way to capture the shortened name prior. But in any case, it works 99 percent of the time. So for those emails that have a long subject line, just use the normal Outlook Save As and shorten the subject line on a case-by-case.

        Hope this helps...

      • Diane Poremsky says

        October 16, 2016 at 11:30 pm

        How did you trim the subject? This should work -
        sName = Left(oMail.Subject, 45)
        or
        sName = oMail.Subject
        ReplaceCharsForFileName sName, "-"
        sName = Left(sName, 45)

  42. Jose Manuel says

    August 9, 2016 at 6:58 am

    Hi Diane,

    Thanks a lot for your Macro.
    I have a Retention Policy of 6 months and even It is not allow to move the emails to a local outlook folder.
    So your makro is the only solution I found to save my emails.
    The makro is very good. I would like to add the SENDER address or the TO address also to the name of the file.
    My idea is to do two makros: one for the inbox folder and one for the sent folder.
    So the idea is:
    (SENT): Date + Hour + To address (just the first one) + Subject.
    (INBOX): Date + Hour + SENDER address + Subject.
    Do you think this could be possible?
    Thanks

    Reply
    • Diane Poremsky says

      August 9, 2016 at 10:37 am

      For To, yes, it will definitely work for sender's - use something like sName = oMail.Subject &"-" & omail.SenderName (or omail.senderaddress). To get the display name in the sent folder, use oMail.To. If you send to multiple people, it will include all names in the to field but not in the cc field. to avoid too long filenames, you may need to get just the first name using the recipients collection or trim the length of the string.

      Reply
  43. Lukasz says

    July 15, 2016 at 7:15 am

    Hi Diane,
    I would like to ask you how can I combine your method of saving emails as they sent with my macro in access that after button click open new message in outlook and attach most recent file from my directory. Can I do everything in one access vba module in one button? It is important not to include it in outlook because I would like other people on their computers use this access file and be able to do that in one click in form. Really thank you in advance!

    Reply
    • Diane Poremsky says

      July 17, 2016 at 1:00 am

      As long as you properly reference the outlook object model, you can control outlook using vba in other office products.

      Reply
  44. Doug says

    July 14, 2016 at 8:08 pm

    Hi, I have set the "save messages as they are sent" to a module, but I cant get the Rules box to allow me to run it? This image may work:

    How do I fix this?

    Thanks,

    Doug

    Reply
    • Diane Poremsky says

      July 17, 2016 at 12:53 am

      Save messages as they are sent is an automatic rule - it runs every time you send a message. You need to restart outlook for it to start working.

      Reply
  45. Mike says

    June 20, 2016 at 10:22 pm

    Hi Diane,
    My apologies as I am new at using VBA and Macros. I was wondering where exactly I paste in the "BrowseForFolder" function code as I cannot seem to get this working so obviously I am just not putting it in the correct location within your "Pick the Folder Location" code.

    Reply
    • Diane Poremsky says

      July 4, 2016 at 10:31 pm

      it can either go at the end of the macro or you can add a module, rename it functions, and paste it there. (This makes it easier to share functions between multiple macros.)

      Reply
  46. Ray says

    May 11, 2016 at 5:04 pm

    Hi Diane I was trying out your macros and I was wondering if you could help me with three things:

    1. When an opened email is closed, is there a macro for a pop up to appear to save that email to a server and not the C Drive? I am thinking of being able to go select a folder on the server from the macro or maybe selecting from a previous list of folders? Then, when saved, being asked if you want that email to be deleted from your inbox, or if it has been saved already for the save pop up box to not appear.
    2. Similar to above, when an email is sent, a pop up will appear to ask where that email is to be saved on the server, again, maybe selecting from a previous server folder list or being able to select a new destination. Then, when saved, being asked if you want that email to be deleted from your sent items. Again, if saved already, the pop up would not appear.
    3. Finally (!), maybe wishful thinking here, but if an email is saved, then an icon would appear both on the email when opened or on the Inbox and Sent Items windows to let you know that the email has been saved already.

    I am having awful trouble with many emails and tight 3 month restrictions on emails that I just cant handle. If you can assist with the above I would be very, very grateful.

    Reply
    • Diane Poremsky says

      May 11, 2016 at 5:21 pm

      1. As you are closing the message i think we can move it.
      2. Yes.
      3. Possibly. I'd need to look into it.

      Reply
      • Ray says

        May 17, 2016 at 11:37 am

        Thanks Diane, any help would be appreciated.

      • Ray says

        September 20, 2016 at 9:12 am

        Diane, sorry to bother you but I wonder if you had some time to look at my macro query above? Just if you have some time, I would greatly appreciate it. Thanks. Ray.

      • Diane Poremsky says

        September 20, 2016 at 11:20 am

        On this? 3. Finally (!), maybe wishful thinking here, but if an email is saved, then an icon would appear both on the email when opened or on the Inbox and Sent Items windows to let you know that the email has been saved already.

        Does it need to be an icon? Flags and Categories, or custom fields are easier to do and in 2 of those cases, work on most computers and devices (custom fields work in outlook windows desktop only). Plus, if you reply, the icon will either be replaced or not show that you replied.

        To change the icon, you need to use a custom form with the different icon. It's actually not that much harder than a custom field https://www.slipstick.com/developer/vba-set-existing-contacts-custom-form/ - and sounds like a fun macro sample. (Just tried it - my custom icon isn't used when i change the message class :()

  47. Steve says

    May 6, 2016 at 3:24 pm

    Hi again Diane! Your macro was working fabulously for a month until today when I suddenly received an error. Unfortunately I didn't save the error message but when I debugged it, the following was highlighted: Item.SaveAs sPath & sName, olMSG.

    After the initial fail, the macro doesn't work but I do not get the error message anymore.

    Any ideas? (btw, enviro = CStr(Environ("USERPROFILE")) wasn't working so I texted it out and hard coded MyDocumnents)

    Thanks again Diane, really appreciate what you do here.

    Option Explicit

    Private WithEvents objSentItems As Items

    Private Sub Application_Startup()
    Dim objSent As Outlook.MAPIFolder
    Dim objNS As Object
    Set objNS = Application.GetNamespace("MAPI")
    Set objSentItems = objNS.GetDefaultFolder(olFolderSentMail).Items
    Set objNS = Nothing
    End Sub

    Private Sub objSentItems_ItemAdd(ByVal Item As Object)
    Dim sPath As String
    Dim dtDate As Date
    Dim sName As String
    Dim enviro As String

    'enviro = CStr(Environ("USERPROFILE"))

    sName = Item.Subject
    ReplaceCharsForFileName sName, "-"

    dtDate = Item.ReceivedTime
    sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
    vbUseSystem) & Format(dtDate, "-hhnnss", _
    vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"

    sPath = "\\HVSBS\RedirectedFolders\sunderhill\My Documents\"
    Debug.Print sPath & sName
    Item.SaveAs sPath & sName, olMSG
    End Sub

    Private Sub ReplaceCharsForFileName(sName As String, _
    sChr As String _
    )
    sName = Replace(sName, "'", sChr)
    sName = Replace(sName, "*", sChr)
    sName = Replace(sName, "/", sChr)
    sName = Replace(sName, "\", sChr)
    sName = Replace(sName, ":", sChr)
    sName = Replace(sName, "?", sChr)
    sName = Replace(sName, Chr(34), sChr)
    sName = Replace(sName, "", sChr)
    sName = Replace(sName, "|", sChr)
    End Sub

    Reply
    • Diane Poremsky says

      May 6, 2016 at 8:28 pm

      is this path valid? sPath = "\\HVSBS\RedirectedFolders\sunderhill\My Documents\"
      Can you open it in explorer without logging in.

      This: enviro = CStr(Environ("USERPROFILE"))
      would add the path C:\users\steve\ - won't do you much good with a network path. You can delete it and all references to it.

      Reply
      • Steve says

        May 9, 2016 at 12:41 pm

        Yep, path valid. No login needed for the folder once I'm on the system. And it worked perfectly for a month and now appears to do nothing and no error messages except for that first time. And I'm searching every other folder I have access to to see if they're landing someplace else...

        Any thoughts?

      • Diane Poremsky says

        May 9, 2016 at 11:59 pm

        add msgbox "working" lines at the beginning of the macro and msgbox spath after the path is set - if the dialogs don't come up, its not working.

      • Steve says

        May 10, 2016 at 12:51 pm

        The earth's core must've stopped spinning. Did as you suggested and both msgboxes appeared as they should have. But only the first time and the email wasn't saved. Tried several times and never got the message boxes again, or the saved email. Checked to be sure enable all macros on and it was. Even tried deleting the whole thing and starting from scratch with the enviro command knowing that wouldn't work. And it didn't, no error message, no msgbox and no saved email....

        Appreciate your help but you've gone above and beyond.

        Thanks.

        Steve

      • Diane Poremsky says

        May 11, 2016 at 1:08 am

        You're using one that is an application start macro and an error will basically kill it - that's why it works once and never again. The problem is figuring out what is erroring. It's probably something with the network drive - does it work if you use a local drive? It might work if the drive is mapped.

      • Steve says

        May 11, 2016 at 12:19 pm

        Core is rotating again, but have no idea why. Tried a local folder but was denied authority to save via the macro though I could save something directly.

        Tried one last time by completely deleting and re-installing and now it works just fine again. Go figure.

        Thanks so much for your help! May have to come back again when I try to modify to more closely match what I'll need.

        Do you offer any products or consulting? Feel bad getting all this great help for free.

      • Diane Poremsky says

        May 11, 2016 at 1:38 pm

        No products yet (I keep planning on an e-book, but never find time to work on it and i don't know why lol) but i do consulting via gotomeeting. Although not necessary, I won't turn down donations at paypal - my paypal address is diane at slipstick.

  48. David says

    April 25, 2016 at 12:21 am

    Thank you, for your post of information!

    Reply
  49. Steve says

    April 2, 2016 at 8:38 pm

    Diane - thanks so much for your work here, I really appreciate it! I can get the first two macros to work fine, but not Save Messages As They Are Sent.

    After saving it in the vba editor, "Private WithEvents objSentItems As Items" is changed to red font but there's no error message. When I send items, they are sent as normal, but no copy in Documents and no error message.

    Any thought?

    Thanks again, Steve

    Reply
    • Diane Poremsky says

      April 3, 2016 at 11:50 pm

      Did you put it in ThisOutlookSession? Any macro that runs automatically needs to be there.

      Reply
      • Steve says

        April 4, 2016 at 10:24 am

        Whoa - that did it, thanks!! Works famously. Added Dim objNS As Object because without it error message: Compile error: Variable not defined.

        Really appreciate it Diane.

  50. Sugat says

    March 28, 2016 at 11:35 pm

    Hi Diane,

    First of all i would like to thank you for making this site and helping people with the content.

    I am trying to use your code to save all the outlook mails from inbox to a specified hard drive folder but getting a warning saying " A program is trying to automatically send mails on your behalf" do you wnna allow this ", below is the link for outlook warning message:

    https://msdn.microsoft.com/en-us/library/office/aa168346(v=office.11).aspx

    What code we need to modify to get rid of this warnign message and save all mails.msg to a hard drive location. Could you please help me with this.

    Reply
    • Diane Poremsky says

      April 3, 2016 at 11:41 pm

      What version of Outlook are you using? Do you have antivirus installed and updated? You shouldn't get that message with Outlook 2013 or 2016.

      Reply
      • sugat says

        May 25, 2016 at 11:34 am

        I am using outlook 2010. and also after executing the code sometimes the macro stops at mItem.SaveAs StrFile, 3.
        Not able to track the reason for it

      • Diane Poremsky says

        July 4, 2016 at 10:56 pm

        Do a debug.print strFile so you can see the files and path - it sounds like there is a problem with the file name. Are you removing all illegal characters?

  51. Devin says

    March 15, 2016 at 12:53 pm

    Diane:
    I've got the script working for myself in Outlook 2013. Now I want to modify it a bit so that instead of it saving the Outlook messages to a hard coded Windows Explorer directory, I want to have the code to have the Outlook messages saved to a directory that is named based on the Outlook folder the message resides in. So if the message is in the "Inbox" folder, the code will create a "Inbox" Explorer sub-directory and save messages there, or if the message is in the "Sent" folder, the code will create a "Sent" Explorer sub-directory and save messages there, or if the message is in a non-default Outlook folder like say "Messages from John", the code will create a "Messages from John" Explorer sub-directory and save messages there.

    In order to do this when a Outlook message gets processed, the Outlook folder it resides in needs to get stored into a variable so that I can refer back to that variable when building the sub-directory. How do I get the value a message's Outlook folder?

    Thank you

    Reply
    • Diane Poremsky says

      March 23, 2016 at 12:50 am

      See https://www.slipstick.com/developer/saving-messages-to-the-hard-drive-using-vba/ for a macro that contains most of what you need. You can get the parent folder name part gets the folder name or get the folder name by entry id if you are walking the folder list-
      Set SubFolder = myOlApp.Session.GetFolderFromID(EntryID(i), StoreID(i))

      Reply
  52. Luis Alberto says

    March 7, 2016 at 7:28 pm

    Hola Diane,

    Gracias por tu trabajo ta profesional e importante. Me ayudas indicando como ejecuto desde vba Excel tu macro: "Save Messages As They Are Sent". Tu macro "Save selected email message as .msg file" funciona muy bien.

    Gracias,

    Thank you for your professional and important ta work. Help me indicating your macro run from Excel vba: "Save Messages As They Are Sent". " Your selected email message as .msg file "Save macro" works very well. "

    Reply
    • Diane Poremsky says

      March 23, 2016 at 12:41 am

      This is one way to call outlook from excel -
      Dim olApp As Outlook.Application
      Set olApp = Outlook.Application
      If olApp Is Nothing Then
      Set olApp = Outlook.Application
      End If

      Reply
      • Luis Alberto says

        July 4, 2016 at 3:28 pm

        Diane,

        Muchas gracias. No obstante, me ayudas con esto: cuando ejecuto lo siguiente "Set objSentItems = objNS.GetDefaultFolder(olFolderSentMail).Items" devuelve un cuadro emergente que dice: "se requiere un objeto".

        Me ayudas cómo hago para encontrar o citar el objeto.

        Muchas gracias,

      • Diane Poremsky says

        July 4, 2016 at 9:35 pm

        It sounds like objNS is not set. Try changing objNS to Session or application and see if it works.

  53. Luis Alberto says

    March 5, 2016 at 10:34 pm

    Gracias por el procedimiento: Save Messages As They Are Sent

    Deseo me ayude como ejecutar desde excel.

    Gracias,

    Thank you for the procedure: Save Messages As They Are Sent desire help me how to execute from excel.

    Reply
    • Diane Poremsky says

      March 23, 2016 at 12:33 am

      This macro: https://www.slipstick.com/developer/create-appointments-spreadsheet-data/ shows how use an excel macro to work with the outlook object model.

      Reply
  54. Bryan says

    March 3, 2016 at 6:55 pm

    Trying to use your as sent sub and it always says that objNS is not defined. How do I define it?

    Reply
    • Diane Poremsky says

      March 22, 2016 at 12:46 am

      This line should be in with the Dim's
      Set objNS = Application.GetNamespace("MAPI")

      Reply
  55. Maciej says

    February 24, 2016 at 9:17 am

    Hello,

    Is it possible to implement this solution for calendar items (appointments)?

    Thanks for any help

    Reply
    • Diane Poremsky says

      March 4, 2016 at 10:42 pm

      It can be changed. Change the dim to Dim oMail As Outlook.AppointmentItem - you'll also need to change the filename you save it as - receivedtime will error.

      Reply
  56. JAMES MATTHEW says

    February 18, 2016 at 2:59 pm

    Hi Diane - I've been using this macro for years and love it. However the resulting .msg files are often copied over to a database system that limits filename lengths to 60 characters (including ".msg"). Is there a way to shorten the file to name to just 60 characters starting at the left? Many Thanks, JM.

    Reply
    • Diane Poremsky says

      February 18, 2016 at 5:37 pm

      if you are adding the date and it's always the same length, I would trim just sName (before .msg):
      sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
      vbUseSystem) & Format(dtDate, "-hhnnss", _
      vbUseSystemDayOfWeek, vbUseSystem) & "-" & left(sName, 45) & ".msg"

      otherwise, put the entire part before the extension inside left()

      Reply
  57. Doug says

    January 3, 2016 at 11:34 pm

    Hi, these are terrific routines. Thanks very much!

    One issue is that I cannot get "Save messages as they are sent" to work simultaneously with your "Run as a script rule" from your page using the ItemAdd method?

    Would love it if you could solve this one! i've tried everything (complete VBA noob!).

    Thanks again.

    Reply
    • Diane Poremsky says

      February 23, 2016 at 5:15 pm

      You can't use a run a script rule to save sent messages - you need to use an itemadd macro and watch the sent folder.

      Which macro won't work with it? As long as it's looking at the sent folder and everything is named correctly, it should work, although sent items are missing some properties that are on incoming mail (where run a script works).

      Reply
  58. Nancy Revelle says

    November 19, 2015 at 12:18 pm

    Hi, I want to set up a macro in Outlook 2010 that saves the email I'm working on to a template (.oft) in the default template directory to the same file (overwriting). I do this several times a day and it would be so nice to have it automated. I can't seem to find how to do this specifically. Thank you!! Nancy

    Reply
  59. Bruce says

    November 4, 2015 at 2:05 pm

    Hi
    Is there any way to open a dialog box from excel that will allow you to select a mail item from Outlook and then export that selected mail item to .msg file in my documents folder.
    Thanks
    Bruce

    Reply
    • Diane Poremsky says

      November 4, 2015 at 5:05 pm

      You can; I don't have any code samples but basically, you need to load the outlook object model, read the inbox and load it into a list control in a userfrom and get the selections index number.

      Reply
  60. Mike says

    October 21, 2015 at 10:54 am

    This is great but if I select too many emails to move I always get an out of memory error. Any way to fix that?

    Reply
    • Los says

      July 11, 2016 at 9:37 am

      I am having the same issue. Not enough resources and I get an error, when i debug code and variable values look ok.

      Reply
      • Diane Poremsky says

        July 17, 2016 at 12:57 am

        Try moving the Dim omail line into the If loop and then set it to nothing it at the end.

        For Each objItem In ActiveExplorer.Selection
        If objItem.MessageClass = "IPM.Note" Then
        Dim oMail As Outlook.MailItem
        Set oMail = objItem

        --snip--

        Set oMail = Nothing
        End If

  61. Christine E. says

    October 14, 2015 at 12:59 am

    Hello,

    I need to setup a script and/or a macro to automatically run when I receive an outlook email with a .pdf attachment which has the word "image" in the name of the attachment. I need to have the file(s) automatically copied to K\IPOS\SF - SEA Reading File\2015\10 - 15\. I also need to have the same file copied to K\IPOS\Program Review\SharePoint\ERM\. How do I go about doing this with the code you have out there. I have tried to modify some of the code to perform this operation and I have had may different errors.

    Can you assist me?

    Reply
    • Diane Poremsky says

      October 14, 2015 at 8:06 am

      The macro on this page works with the message, you want the one at https://www.slipstick.com/developer/save-attachments-to-the-hard-drive/ -
      To save into two locations, set the locations:
      ' Set the Attachment folder.
      strFolderpath = "\\K\IPOS\SF - SEA Reading File\2015\10 - 15\"
      strFolderpath2 = "\\K\IPOS\Program Review\SharePoint\ERM\"

      get the pdf:
      For i = lngCount To 1 Step -1

      ' Get the file name.
      strFile = objAttachments.Item(i).filename

      ' This code looks at the last 4 characters in a filename
      sFileType = LCase$(Right$(strFile, 4))

      if sFiletype = ".pdf" then
      if instr(strfile, "image") then

      use these lines to save:
      strFile = strFolderpath & strFile
      objAttachments.Item(i).SaveAsFile strFile
      strFile = strFolderpath2 & strFile
      objAttachments.Item(i).SaveAsFile strFile
      end if
      end if

      Reply
  62. Ralf says

    October 13, 2015 at 10:53 am

    Thanks a lot for this great collection. You made my day!

    Finally I found an easy to use alternative to ship around the .pst file which is restricted where I am working.

    Ralf

    Reply
  63. Chieri Thompson says

    August 26, 2015 at 9:08 am

    Nevermind! I think i got it!

    Sub Test()
    Dim oMail As Outlook.MailItem
    Dim oItem As Object
    Dim strTemp As String
    Dim strFilenum As Variant
    Dim sPath As String
    Dim sName As String

    Set oItem = ActiveInspector.CurrentItem

    strFilenum = InputBox("If all/one Exists click X in Field to proceed. ", "ADD Design #, PO #, SO #")

    If strFilenum = False Then Exit Sub
    If strFilenum = "" Then Exit Sub
    On Error Resume Next
    strTemp = "[" & strFilenum & "] " & oItem.Subject

    Set oMail = oItem
    oItem.Subject = strTemp
    'oItem.Save

    sName = "[" & strFilenum & "] " & oItem.Subject & sName & ".msg"
    'ReplaceCharsForFileName sName, "-"

    sPath = "C:\Users\cthompson\Desktop\Downloaded Artwork\"
    'sPath = "\\ac-fs1\NetVol\LOGO DEPT\APPROVAL LETTERS\"

    oMail.SaveAs sPath & sName, olMSG

    End Sub

    Reply
  64. Chieri Thompson says

    August 25, 2015 at 3:45 pm

    Okay, So I realize this post is older. But I have been trying to Utilize an "input box" to add data and use your save msg file to a drive. To Elaborate. Add data to subject line using Input box, save data in subject then save to drive. I am real close but I cannot pin point why its replacing my subject with the new subject and not keeping "date + original sub"

    Sub AddSaveTest()

    Dim oMail As Outlook.MailItem
    Dim oItem As Object
    Dim sPath As String
    Dim sName As String
    Dim addSub As Variant

    'On Error Resume Next
    Set oItem = ActiveInspector.CurrentItem
    'Set oItem = ActiveExplorer.Selection

    addSub = InputBox("Add Design Number")
    If addSub = False Then Exit Sub
    If addSub = "" Then Exit Sub
    On Error Resume Next

    Set oMail = oItem
    oItem.Subject = sName
    oItem.Save '

    '
    '
    'For Each oItem In ActiveExplorer.Selection
    'If oItem.MessageClass = "IPM.Note" Then
    '
    '
    ''sName = oMail.Subject

    sName = "[" & addSub & "] " & oItem.Subject & sName & ".msg"
    ReplaceCharsForFileName sName, "-"

    sPath = "C:\Users\cthompson\Desktop\Downloaded Artwork\"

    oMail.SaveAs sPath & sName, olMSG

    'End If
    'Next
    End Sub

    Reply
  65. Nick says

    July 24, 2015 at 10:55 am

    I need some help with this macro...I'm having a problem if the email has the same subject line, it just gets overwritten. So if I were to select multiple emails and use the macro and a few had the same subject line, it would overwrite them i.e. I use it on 8 emails and it only saves 6, because 2 got overwritten as it had the same subject line. Is there a remedy for this? Thank you in advance.

    Reply
    • Diane Poremsky says

      July 25, 2015 at 6:18 pm

      Either add the received time to the subject or add a code. Actually this:
      sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
      vbUseSystem) & Format(dtDate, "-hhnnss", _
      vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"

      uses the date and time so it shouldn't overwrite. If you removed the date & time, you can add a number:

      If you are saving a selection, you can count the selection and add the count the subject.
      at the beginning:
      lcount = 1

      ' snipped code
      sName = sName & lcount & ".msg"
      lcount = lcount + 1

      Reply
  66. MIke O'Reilly says

    July 14, 2015 at 10:46 am

    I came on this today. It is excellent. I have added it with a button to put any highlighted email into a specific folder. That folder is a PaperPort folder where I am now storing all my files. t works perfectly thank you so much.

    Reply
  67. Sameer says

    July 7, 2015 at 3:46 am

    Hey Diane,
    I'm trying to create a Macro to open the saved mails (.msg) which are saved in a folder and then copy the date and time of receiving the the mail.
    Can we have it like an excel sheet
    Subject line of mail - date received - time received

    incase of repetition of mail,
    Subject line of mail - date received - time received, date received, time received and so on

    Your help is very much appreciated on this.

    Thanks in advance.

    Reply
    • Diane Poremsky says

      July 13, 2015 at 8:32 am

      In a text file? Yes, as long as you use tab or comma delimiters. I have a sample here - https://www.slipstick.com/developer/code-samples/save-email-message-text-file/ - that does line feeds but you can change the vbcrlf to vbtab or "," &. If you use commas and the text has a comma, you'll need to wrap the fields in quotes (add chr(34) &)

      Reply
  68. Anand says

    June 16, 2015 at 10:41 pm

    Hi Diane - thank you for your hard work! I was able to set up the macro to save messages along with BroweseForFolder function. Only issue I am facing now is saving multiple message to the same folder using BrowseForFolder function. The file location prompt comes up for each individual message. Is there a way to select multiple message and save them to a specific folder using BrowseForFolder function? Please let me know. Thanks

    Reply
    • Diane Poremsky says

      July 13, 2015 at 8:53 am

      You'd put the browse for folder stuff before the for each... line. This defaults to documents but uses
      Dim strFolderpath As String
      enviro = CStr(Environ("USERPROFILE"))
      strFolderpath = BrowseForFolder(enviro & "\documents\")
      For Each objItem In ActiveExplorer.Selection

      Change the spath to to this to set the path at the end:
      sPath = strFolderpath & "\"

      Reply
  69. Alan McGowan says

    June 3, 2015 at 10:15 am

    I'm trying to use the code to save messages as they are sent. I have changed enviro = "c:\Inbox" but when I send an email it is not being saved into c:\Inbox

    Reply
    • Diane Poremsky says

      June 3, 2015 at 11:01 am

      Try changing this line:
      sPath = enviro & "\Documents\"

      to sPath = "C:\Inbox\"

      Reply
    • Alan McGowan says

      June 3, 2015 at 11:09 am

      The problem seems to be becuase I have a Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean) macro also in the ThisOutlookSession. If I delete this code it works fine but if I leave it in the message isn't saved.

      Reply
      • Diane Poremsky says

        June 3, 2015 at 2:09 pm

        Yeah, you can only have one itemsend - you can combine them and use if statements to apply the code to certain messages.

  70. Mark says

    May 4, 2015 at 6:09 am

    I'm running it from Excel. I think i changed the reference, but by the lack of knowles of VBA i'm not sure.
    The error on "Dim oMail As Outlook.MailItem" is still there.
    Would you be so kind the check the code below and make some suggestions for improvement?

    The code i have so far is:

    Sub SaveMessageAsMsg()
    Dim oMail As Outlook.MailItem
    Dim objitem As Object
    Dim sPath As String
    Dim dtDate As Date
    Dim sName As String
    Dim enviro As String
    enviro = CStr(Environ("USERPROFILE"))
    For Each objitem In ActiveExplorer.Selection
    If objitem.MessageClass = "IPM.Note" Then
    Set oMail = objitem
    sName = oMail.Subject
    ReplaceCharsForFileName sName, "-"
    dtDate = oMail.ReceivedTime
    sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
    vbUseSystem) & Format(dtDate, "-hhnnss", _
    vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"
    sPath = enviro & "\Documents\"
    Debug.Print sPath & sName
    oMail.SaveAs sPath & sName, olMSG
    End If
    Next
    End Sub
    Private Sub ReplaceCharsForFileName(sName As String, _
    sChr As String _
    )
    sName = Replace(sName, "'", sChr)
    sName = Replace(sName, "*", sChr)
    sName = Replace(sName, "/", sChr)
    sName = Replace(sName, "\", sChr)
    sName = Replace(sName, ":", sChr)
    sName = Replace(sName, "?", sChr)
    sName = Replace(sName, Chr(34), sChr)
    sName = Replace(sName, "", sChr)
    sName = Replace(sName, "|", sChr)
    End Sub

    Reply
  71. Mark says

    May 1, 2015 at 3:38 pm

    Hi,

    My intention is the select from a excelsheet a selection of email messages in Outlook and then save them on a directory like C:\data\....

    So your code for "Save selected email message as .msg file" seems to be the right one for my assignment. Unfortunaly i get a few error messages with the code

    • Dim oMail As Outlook.MailItem
    I get a compile error. A Datatype is not difined.

    • For Each objitem In ActiveExplorer.Selection
    I get a compile error. A variable is not difined.

    I hope you can help me.

    Reply
    • Diane Poremsky says

      May 3, 2015 at 10:43 am

      Are you running the macro in outlook or excel? The objects are declared - but if you run it from excel, you need to reference the outlook object model.
      Dim oMail As Outlook.MailItem
      Dim objItem As Object

      Reply
  72. John says

    March 11, 2015 at 2:12 am

    "Dim oMail As Object" did the trick. Much thanks, Diane. If I had an adblocker, I'd whitelist your site ;-)

    Reply
  73. John says

    March 10, 2015 at 9:52 pm

    Ugh.. note that my sPath value was removed when I submitted my comment. The path is not my issue.

    Reply
  74. John says

    March 10, 2015 at 9:49 pm

    I use a version of this macro with very satisfactory results. But now, I want to be able to save Lync Conversations (IPM.Note.Microsoft.Conversation) and meeting invites (IPM.Schedule.Meeting.Request). The latter often contain large presentation attachments.

    When I attempt my macro (below) on these Message Classes, nothing is saved in my designated "sPath". No errors are thrown.

    Is this because "oMail" is ONLY for IPM.Note classes? Can I simply insert a few extra lines at the top to accomodate these additional classes referenced above? If so, what do I need to add?

    ----
    Public Sub SaveMessageAsMsg()
    Dim oMail As Outlook.MailItem
    Dim objItem As Object
    Dim sPath As String
    Dim dtDate As Date
    Dim sName As String
    Dim enviro As String

    enviro = CStr(Environ("USERPROFILE"))
    For Each objItem In ActiveExplorer.Selection
    Set oMail = objItem

    sName = oMail.SenderName & " - " & oMail.Subject
    ReplaceCharsForFileName sName, "_"

    dtDate = oMail.ReceivedTime
    sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
    vbUseSystem) & Format(dtDate, "-hhnnss", _
    vbUseSystemDayOfWeek, vbUseSystem) & " - " & sName & ".msg"

    sPath = ""
    Debug.Print sPath & sName
    oMail.SaveAs sPath & sName, olMSG
    Next
    End Sub

    Private Sub ReplaceCharsForFileName(sName As String, _
    sChr As String _
    )
    sName = Replace(sName, "/", sChr)
    sName = Replace(sName, "\", sChr)
    sName = Replace(sName, ":", sChr)
    sName = Replace(sName, "?", sChr)
    sName = Replace(sName, Chr(34), sChr)
    sName = Replace(sName, "", sChr)
    sName = Replace(sName, "|", sChr)
    End Sub

    Reply
    • Diane Poremsky says

      March 11, 2015 at 1:33 am

      Try changing Dim oMail As Outlook.MailItem to
      Dim oMail As Object
      (Yes, it's probably because of the class.)

      Reply
      • Adam says

        May 3, 2016 at 12:20 pm

        My most-functional code:

        Option Explicit
        Public Sub SaveMessageAsMsg()
        Dim oMail As Outlook.MailItem
        Dim objItem As Object
        Dim sPath As String
        Dim dtDate As Date
        Dim sName As String
        Dim enviro As String
        Dim strFolderpath As String

        enviro = CStr(Environ("USERPROFILE"))
        'Defaults to Documents folder
        ' get the function at http://slipstick.me/u1a2d
        strFolderpath = BrowseForFolder("H:\Outlook Files\Manual archives")

        For Each objItem In ActiveExplorer.Selection
        If objItem.MessageClass = "IPM.Note" Then
        Set oMail = objItem

        sName = oMail.Subject
        ReplaceCharsForFileName sName, "-"

        dtDate = oMail.ReceivedTime
        sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
        vbUseSystem) & Format(dtDate, "-hhnnss", _
        vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"

        sPath = strFolderpath & "\"
        Debug.Print sPath & sName
        oMail.SaveAs sPath & sName, olMSG

        End If
        Next

        End Sub

        Function BrowseForFolder(Optional OpenAt As Variant) As Variant
        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

        Set ShellApp = Nothing
        Select Case Mid(BrowseForFolder, 2, 1)
        Case Is = ":"
        If Left(BrowseForFolder, 1) = ":" Then GoTo Invalid
        Case Is = "\"
        If Not Left(BrowseForFolder, 1) = "\" Then GoTo Invalid
        Case Else
        GoTo Invalid
        End Select
        Exit Function

        Invalid:
        BrowseForFolder = False
        End Function

        Private Sub ReplaceCharsForFileName(sName As String, _
        sChr As String _
        )
        sName = Replace(sName, "'", sChr)
        sName = Replace(sName, "*", sChr)
        sName = Replace(sName, "/", sChr)
        sName = Replace(sName, "\", sChr)
        sName = Replace(sName, ":", sChr)
        sName = Replace(sName, "?", sChr)
        sName = Replace(sName, Chr(34), sChr)
        sName = Replace(sName, "", sChr)
        sName = Replace(sName, "|", sChr)
        sName = Replace(sName, vbTab, "_")
        End Sub

  75. phillfri says

    March 6, 2015 at 9:35 am

    Just a heads up. Recently needed to develop code along these lines for an Excel/Outlook interface and ran into two "gotchas". [1] VBA code can change environment strings within VBA itself and the result one gets from using the environ command afterwards will be the changed string - not the original environment string. Probably safer to use the shell object to get the USERPROFILE. [2] If you are using OneDrive for storage the USERPROFILE environment variable string being returned contains an https:\\ url address rather than a local drive. Code will need to be changed to convert that into a path string that VBA will recognize.

    Reply
    • Diane Poremsky says

      March 6, 2015 at 10:30 am

      Do you have a code sample that exhibits these behaviors?

      Reply
  76. Paul says

    March 3, 2015 at 7:35 pm

    This code does not seem to work on messages which have an attachment.

    I've been looking for a way to add this ability but with no luck.

    Does anyone have a solution to this?

    Thanks
    Paul

    Reply
    • Diane Poremsky says

      March 4, 2015 at 12:43 am

      What happens when you try? It should work on all messages - when you save the msg file, the attachment is wrapped within the message. If you want the attachment saved separately, it uses different code.

      Reply
      • Adam says

        May 3, 2016 at 12:02 pm

        I am having the same issue. The code does not seem to take action on messages having attachments. After running the macro on a standard message, the cursor icon changes to the 'working/thinking' icon and the message appears in the designated folder. However, this process does not happen with messages containing attachments (to include digitally signed messages, encrypted messages, meeting invites, out-of-office replies).

        I have tried:
        Changing *Dim oMail As Object
        Changing *If objItem.MessageClass = "IPM" Then
        Including *sName = Replace(sName, vbTab, "_"
        Changing and running on an appointment message *If objItem.MessageClass = "IPM.Appointment" Then
        Getting desperate, didn't work on any message type *If objItem.MessageClass = "IPM" & "*" Then

      • Diane Poremsky says

        May 11, 2016 at 1:11 am

        >> digitally signed messages, encrypted messages, meeting invites, out-of-office replies
        Macros will struggle with signed and encrypted - it can't open them.
        Invites and OOF responses are a problem because they aren't mail...

    • Paul says

      March 4, 2015 at 5:50 am

      It produces a run-time error stating the operation failed
      -2147286788 (800300fc) and when clicking debug points to
      oMail.SaveAs sPath & sName, olMSG

      Reply
    • Paul says

      March 4, 2015 at 6:34 am

      Hi I have resolved the issue, what it was in some instances there may be a tab delimiter in the subject if it has say been copied from excel.
      So the invalid character of vbtab needs to be included

      sName = Replace(sName, vbTab, "_")

      Reply
  77. Janice says

    March 2, 2015 at 8:31 am

    GREAT! thanks :)

    Reply
  78. Tomas Bouska says

    February 27, 2015 at 9:21 am

    Hi all,

    I changed this part of code to fight the path length limitation of 260 characters:

    sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
    vbUseSystem) & Format(dtDate, "-hhnnss", _
    vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName

    sPath = enviro & "\Documents\.Private\"
    Debug.Print sPath & sName
    sPath = Left(sPath & sName, 255) & ".msg"

    oMail.SaveAs sPath, olMSG

    Also I got an error when saving a message with TAB in the subject, so I extended the conversion routine with this line: sName = Replace(sName, Chr(9), sChr)

    Cheers, Tomas

    Reply
  79. Janice says

    February 19, 2015 at 3:11 pm

    Dianne -

    I love this macro! but...it seems that if there are too many addresses in the 'TO' field I get an error. Is there a way to limit the characters of the TO field so that I don't get an error?

    thanks!

    Reply
    • Diane Poremsky says

      February 27, 2015 at 7:15 pm

      See Tomas' change.

      Reply
  80. Roberto says

    January 28, 2015 at 11:00 am

    Hello When I test the macro I get a compile error on Option Explicit Public Sub SaveMessageAsMsg()

    Are there any fixes?

    I am using Outlook 2010 on Windows 7

    Reply
    • Diane Poremsky says

      February 9, 2015 at 10:48 pm

      is this all one line? Option Explicit Public Sub SaveMessageAsMsg()
      it should be two lines:
      Option Explicit
      Public Sub SaveMessageAsMsg()

      Reply
  81. Emmanuel Morin says

    January 24, 2015 at 11:30 am

    Diane, I was searching for that for so long, I am pleased. But can we get it a little bit further? Here what I am looking for: Select the mail that I want to save, then drag-and-drop it to the destination Windows folder using a right clic of the mouse. Actually Windows provide a sub-menu with "Copy", "Move", "Cancel" options. Can we have an third option pointing the macro? Thanks

    Reply
    • Diane Poremsky says

      January 26, 2015 at 1:36 am

      As far as I know, no, you can't. At least, not easily - it's doable (as utilities add to it) but I don't have code samples and it might require a compiled dll, rather than a macro.

      Reply
  82. Brett says

    January 15, 2015 at 3:36 pm

    Hi Diane. I was wondering if you have had a chance to review this? Again if it is not possible that is fine.

    Reply
    • Diane Poremsky says

      January 15, 2015 at 11:37 pm

      No, not yet. I've been swamped the last couple of weeks. Sorry.

      Reply
  83. Brett says

    January 6, 2015 at 8:27 am

    The only edits to the macros was from your comments above in regards to adding code for have the ability to select the file the message is to be stored in. I replaced the sPath line with StrFolderPath = BrowseForFolder ("C:\Users\myusername\documents\")
    sPath = StrFolderPath & "\"and defined the variable Dim StrFolderPath as String.

    When I use the BrowseForFolder listed in you article "How to use Windows filepaths in a macro", this macro works fine.

    However when I add the SaveAllEmails_ProcessAllSubfolders code I get the “Compile error: Ambiguous name detected“ due to multiple functions with the same name. So by removing the one from "How to use Windows filepaths in a macro" that is when I am getting a Run-time error' - 2147287035 (80030005)'" You don't have appropriate permission to perform this operation . I can select the folder, but when I hit OK I get the run-time error.
    It is like the BrowseForFolder function in the SaveAllEmails_ProcessAllSubfolders won't work with SaveMessageAsMsg but works on it's own just fine and vice versa.

    Sorry I guess I am looking for the best of both worlds and perhaps it is just not possible.

    Reply
    • Diane Poremsky says

      January 6, 2015 at 8:46 am

      Ah, ok. so the problem is with the browseforfolder code - I'm guessing an object is not referenced the same in both codes, but will check.

      Reply
  84. Brett says

    January 5, 2015 at 11:09 pm

    Dianne, thank you for the quick response. I am saving this to an existing folder that I have full permissions for. The thing I can't figure out is if I temporarily remove the the code for SaveAllEmails_ProcessAllSubfolders from my system (adding back in the BrowseforFolder code), the SaveMessageAsMsg code works flawlessly and I can save to any folder. I also have no issues using the SaveAllEmails_ProcessAllSubfolders with both codes on my system, it seems to work fine. I am not too sure what it is and not being overly familiar with VBA, I am stumped. These are the only two modules I have on my system and separately they seem to work fine but together they the SaveMessageAsMsg code seems to lock up. I know it is awfully tough to analyze things over a forum, so I thank you for your patience with me.

    Reply
    • Diane Poremsky says

      January 6, 2015 at 12:52 am

      Did you edit the macros? They both work fine here, even when entered in the same module.

      Reply
  85. Brett says

    January 5, 2015 at 9:57 pm

    Dianne, further to this post, when I debug the SaveMessageAsMsg code it goes directly to the mail.SaveAs sPath & sName, 01MSG. I should have included this originally, sorry.

    Thanks Dianne, worked like a charm and I can now select the appropriate folder. Another issue arose however where I am getting a Run-time error' - 2147287035 (80030005)'" You don't have appropriate permission to perform this operation so I cannot save the email message. It worked flawlessly before I loaded the SaveAllEmails_ProcessAllSubfolders code and if I remove that code and just run with the SaveMessageAsMsg code it once again works without any issues. Any thoughts here as I would very much like to utilize both codes.

    Reply
    • Diane Poremsky says

      January 5, 2015 at 10:45 pm

      do the subfolders you are saving messages to exist? If not, you need to create the folder.

      Something like this -
      If Len(Dir("c:\" & strNewFolderName, vbDirectory)) = 0 Then
      MkDir ("c:\" & strNewFolderName)
      End If

      Reply
  86. Brett says

    December 30, 2014 at 10:23 am

    Dianne, thank you for this wonderful code. I am also new at VBA so I have utilized both the code above (with the BrowseForFolder option) and also your SaveAllEmails_ProcessAllSubfolders code to save entire folders of email to my hard drive. Upon loading the second code though I am getting an error on the SaveMessageAsMsg code stating “Compile error: Ambiguous name detected“ highlighting the BrowseForFolder on the StrFolderPath line. Any thoughts as to why the SaveMessageAsMsg has stopped working?

    Reply
    • Diane Poremsky says

      December 30, 2014 at 9:17 pm

      you only need one copy of browseforfolder - all macros can use the one copy. What the error is telling you is that you are using a macro name twice - you need unique names for all macros and functions.

      Reply
  87. Winfred says

    December 17, 2014 at 8:01 pm

    I need to skip all invitation manually, which is painful as I have many... There is no error after 130 and it stop without any notification... i just accidentally realize it as the folder size seems small comparing to the email size that I save...

    Reply
    • Diane Poremsky says

      December 17, 2014 at 9:10 pm

      Replace
      enviro = CStr(Environ("USERPROFILE"))
      For Each objItem In ActiveExplorer.Selection
      Set oMail = objItem

      with
      enviro = CStr(Environ("USERPROFILE"))
      For Each objItem In ActiveExplorer.Selection
      if objItem.messageclass = "IPM.Note" then
      Set oMail = objItem

      then before the Next at the end, add End If.
      That will only save messages.

      Reply
    • Diane Poremsky says

      December 17, 2014 at 9:26 pm

      As an FYI, i updated the macro tonight to check message class.

      Reply
  88. Winfred says

    December 17, 2014 at 3:19 am

    This is good; however, I identified a limitation where it will stop when the quantity of mail is more than 130 or have some calendar invitation...

    Reply
    • Diane Poremsky says

      December 17, 2014 at 8:47 am

      Yeah, invites will stop it unless you use an if statement to skip non-mail items. It should go beyond 130 though. Does it error or just stop?

      Reply
  89. Winfred Tam says

    December 16, 2014 at 4:14 am

    What if I want to add the name sending the email after the date & time at the file name, what can I do?

    Reply
    • Diane Poremsky says

      December 16, 2014 at 8:43 am

      This is what we have now:
      sName = oMail.Subject
      ReplaceCharsForFileName sName, "_"

      dtDate = oMail.ReceivedTime
      sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
      vbUseSystem) & Format(dtDate, "-hhnnss", _
      vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"

      To add the sender name, you need to add
      dim strSender as string ' at top with other dim's
      strSender = omail.sendername

      it will also need invalid filename characters removed - so i'd order it this way:
      sName = oMail.Subject
      strSender = omail.sendername
      dtDate = oMail.ReceivedTime
      sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
      vbUseSystem) & Format(dtDate, "-hhnnss", _
      vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & "-" & strSender & ".msg"
      ReplaceCharsForFileName sName, "_"

      Reply
      • Michelle White says

        June 28, 2016 at 12:39 am

        I am looking for a code to save my email as "date-time-from-to-subject
        I have this but without the From and Received. Are you able to help fix this?

        Option Explicit
        Public Sub SaveMessageAsMsg()
        Dim oMail As Outlook.MailItem
        Dim objItem As Object
        Dim sPath As String
        Dim dtDate As Date
        Dim sName As String
        Dim enviro As String
        enviro = CStr(Environ("USERPROFILE"))
        For Each objItem In ActiveExplorer.Selection
        Set oMail = objItem
        sName = oMail.Subject
        ReplaceCharsForFileName sName, "_"
        dtDate = oMail.ReceivedTime
        sName = Format(dtDate, "yymmdd", vbUseSystemDayOfWeek, _
        vbUseSystem) & Format(dtDate, "-hhnn", _
        vbUseSystemDayOfWeek, vbUseSystem) & "-18259-U200.C.00524-" & sName & ".msg"
        sPath = enviro & "\Documents\001 New Emails to File\"
        Debug.Print sPath & sName
        oMail.SaveAs sPath & sName, olMSG
        Next
        End Sub
        Private Sub ReplaceCharsForFileName(sName As String, _
        sChr As String _
        )
        sName = Replace(sName, "/", sChr)
        sName = Replace(sName, "\", sChr)
        sName = Replace(sName, ":", sChr)
        sName = Replace(sName, "?", sChr)
        sName = Replace(sName, Chr(34), sChr)
        sName = Replace(sName, "", sChr)
        sName = Replace(sName, "|", sChr)
        End Sub

      • Diane Poremsky says

        June 28, 2016 at 12:57 am

        do you want the sender email address or display name? You'd use something like this - .to might not work for incoming mail and could be goofy if there is more than one recipient on the message
        sName = omail.to & "-" & omail.sendername & "-" & oMail.Subject

  90. Jack Hill says

    December 1, 2014 at 5:03 pm

    Disregard my previous comments regarding the problem. I think I finally figured out the problem. Most related to poor transcription from the web page on my part. I am having one issue though. Seems that if there is a meeting notice in the list of emails to copy, the macro fails with a runtime erro = '13'. If I skip those, it seems to run OK. Where can I find a list of the Office object names? I'd like to add From and To fields to the file name format.

    Reply
    • Diane Poremsky says

      December 1, 2014 at 8:50 pm

      if you want to save meetings too, change Dim oMail As Outlook.MailItem to Dim oMail As Object.
      To skip non-mail, use
      For Each objItem In ActiveExplorer.Selection
      If objItem.Class = olMail Then
      Set oMail = objItem
      ' code
      Debug.Print sPath & sName
      oMail.SaveAs sPath & sName, olMSG
      end if
      Next

      Open the object model - F2 while in the vba editor or use the View menu > object model. MSDN has helpful information about objects, once you know the object name.

      from field is sendername, To field is part of the recipients collection and could contain multiple entries. This will get a string containing the sender's display name.
      Dim objVariant As Variant
      sSenderName = objVariant.SentOnBehalfOfName
      If sSenderName = ";" Then
      sSenderName = objVariant.SenderName
      End If

      Reply
  91. Jack Hill says

    December 1, 2014 at 12:21 pm

    Last line of first paragraph should be: I get a compile error: Sub or Funciton not defined.

    Reply
  92. Jack HIll says

    December 1, 2014 at 12:19 pm

    I am new to working with VBA code, but looking for a way of saving to hard disk Outlook 2013 emails in .msg format. This looks great, but I am having difficulty with one line in the example for saving as a .msg file. It is not clear if I put the code in a new Module 1 by right clicking on ThisOutlookSession. On the line ReplaceCharsForFileName sName, "_", I cge ta comple error: Sub or Function not defined.

    My objective is to use the macro against specific folders in Outlook (basically Search Folders with specific date ranges) and export them a folder on an external hard drive for archive purposes. Any assistance would be appreciated.

    Reply
    • Diane Poremsky says

      December 1, 2014 at 8:41 pm

      Although you figured it out before I got to the question, for the benefit of others this: "On the line ReplaceCharsForFileName sName, "_", I get a compile error: Sub or Function not defined."
      Usually means the function is missing.

      Reply
  93. John Durbin says

    September 5, 2014 at 4:43 pm

    Why is the saved .msg file an un-sent .msg file? Is there a way to fix that so that the sent version of the file is saved?

    Reply
    • Diane Poremsky says

      September 6, 2014 at 12:46 am

      The itemsend macro saves before it's sent, so it saves a draft. I'll change it so it watches the sent folder.

      Reply
    • Diane Poremsky says

      September 6, 2014 at 1:11 am

      As an FYI, I updated the macro and changed it to watch the sent folder.

      Reply
  94. dave says

    August 13, 2014 at 2:48 pm

    This is a great tool! Can the saved file name also include sender (from) of the email [and possibly the recipient? or the first named recipient?]. {We are trying to capture- sender, recipient & subject of email in the saved .msg on our network.} If adding sender (and possibly recipient) can be added, where would this additional string of code go in your scrip? Using Outlook 2010. Thanks for any suggestions.

    Reply
    • Diane Poremsky says

      August 13, 2014 at 8:45 pm

      Yes, it can. omail.sendername (or omail.sender if sendername doesn't work with your account type) and omail.to. omail.to gets all of the names in the to field. You can do it something like this:
      sName = oMail.Subject & "-" & oMail.Sender & "-" & oMail.To

      Reply
  95. mike says

    August 1, 2014 at 11:25 am

    need to check for:
    sName = Replace(sName, Chr(39), "")
    sName = Replace(sName, "*", "")

    Reply
  96. James L. says

    July 9, 2014 at 3:09 pm

    This script has totally saved me! Thank you so much!

    Only thing that needs to be changed about it is that it doesn't strip any asterisks from file names, so I had to add that to the code. Otherwise it is perfect!

    Reply
  97. Thomas says

    April 1, 2014 at 9:19 am

    Hi Diane,

    for the normal email (oMail), it works great. I have some problem with the oReps. In Outlook 2003 this was also working fine, but in Outlook 2010 the macro won't save any mail with TypeName(objItem) "MailItem", as msg.

    Reply
    • Diane Poremsky says

      April 5, 2014 at 1:25 am

      It works in 2013, so it should work in 2010. do you get any error messages?

      Reply
  98. Kurt S says

    March 30, 2014 at 9:11 pm

    If I understand the code correctly, I would use the original code to save the email as a .msg file, then open it and apply the properties to it.

    Thank you so much. This will make managing my emails so much easier.

    Reply
    • Diane Poremsky says

      March 30, 2014 at 11:56 pm

      Right, you need to save the msg then update the properties. It can all be in one macro, but it needs to be in that order.

      Reply
  99. Kurt S says

    March 28, 2014 at 4:30 pm

    This is GREAT.

    One thing that would really help me is to populate the file attribute/properties. Like put the subject in the Subject Property, etc. That way I can sort easily in folder view, rather than having to pull it back into Outlook sort and search.

    If that cant be done, can you move the "RE: " from the front of the subject to the end, to sort alphabetically and keep threads together?

    Thanks!!

    Reply
    • Diane Poremsky says

      March 28, 2014 at 8:15 pm

      It can be done using FSO - you might be able to guess at some of the property names but I'll see if i can find a list of them
      Set objFile = CreateObject("DSOFile.OleDocumentProperties")
      objFile.Open("C:\file\my.msg")
      objFile.SummaryProperties.Subject = "This is the subject"
      objFile.Save
      set objFile = Nothing

      Reply
      • anasa says

        February 23, 2016 at 3:24 pm

        Hi Diane - Did you ever find more of the FSO properties? I'm interested in this as well but I don't see any other comments on how to do so (i.e. setting Subject, Sender, etc)

        Also would this (objFile) be in place of the oMail object and instead of
        oMail.SaveAs sPath & sName
        we would just do
        objFile.SaveAs sPath & sName (assuming there is a similar function for that object type)
        Thanks!!

      • Diane Poremsky says

        March 23, 2016 at 12:18 am

        no, i haven't found any - at least not for general windows files. I've worked with file properties in word docs (and set them using word macros).

  100. James Matthew says

    March 27, 2014 at 12:23 pm

    The folder does exist in that path. I finally got it to work using the complete path C:\Users\username\........". Is there a change I can make in the code to include calendar items when they're selected as well? Thanks again.

    Reply
    • Diane Poremsky says

      March 27, 2014 at 9:52 pm

      Hmm. Interesting. It should have worked with enviro. Oh well. If you change Dim oMail As Outlook.MailItem to Dim oMail As Object it should work for any items type.

      Reply
  101. James Matthew says

    March 18, 2014 at 5:34 pm

    Diane - any idea why this works fine on Outlook 2010 and doesn't work for me using Outlook 2007? Both are running Windows 7. With OL 2007, I keep getting the error, "Run-time error '-2147287037 (80030003)': The operation failed.

    When I run Debug, it points to this line: oMail.SaveAs sPath & sName, olMSG.

    My sPath is sPath = enviro & "DesktopOutlook".

    The Immediate window shows DesktopOutlook20140318-164025-RE_ Investigative Report.msg. That turns out to be the first line of the selection but it never copies to the DesktopOutlook folder.

    Thanks so much for your help.

    Reply
    • Diane Poremsky says

      March 18, 2014 at 7:40 pm

      Does that folder exist at that path? Could your antivirus be blocking it from writing to that path? Because it's on the desktop, there may be a security setting that is preventing automation to that folder. Test it to the My Documents folder to verify the code is not being blocked.

      Reply
  102. Stephen says

    March 12, 2014 at 10:50 pm

    Hi,

    Thank you for making this code available, is very good and working well for us.

    Is it possible to add something to the code so that the mail item is permanently deleted rather than moved to the deleted items folder ?

    Regards

    Reply
    • Diane Poremsky says

      March 14, 2014 at 1:51 am

      You'd need to watch the deleted items folder and delete it again, VBA doesn't have a permanently delete option.

      Reply
  103. Harald N says

    March 6, 2014 at 8:35 am

    Hi Diane Poremsky
    I am also beginner at this and hoping very much for your help. I would like to have as Caroline Marie to have "a dialog box [that] appears and prompts the user to choose where to save the email" I have tried to ad the function BrowseForFolder and it prompts okay but does not save the file. I have read the comments but can't make it Work. Can you help is it wrong to implement the function ?
    Hope you will help me, thanks.

    Regards
    Harald

    Reply
    • Diane Poremsky says

      April 14, 2014 at 7:49 am

      Sorry for taking so long to reply, I was swamped and needed some free time to look into it. (And once I made the time, it was a 30 second fix.:( )
      The macro is not adding the last / to the path it's being saved, but in this case, as a file named TestFolder...
      C:\Users\Diane\Documents\TestFolder20140414-025147...

      If you change these lines to include the last slash, it will work.
      Debug.Print sPath & "\" & sName
      oMail.SaveAs sPath & "\" & sName, olMSG

      The Debug.Print line writes the path to the Immediate windows, which you can turn on from the View window or using Ctrl+G.

      Reply
  104. Mark says

    February 22, 2014 at 10:01 am

    Diane, I am trying to use this macro to save files to My Documents on my C: Drive. I added a folder titled MailSave and replaced "\Documents\" with "\My Documents\MailSave\", but it didn't seem to work. Am I missing another change in your awesome macro? Thanks!

    Reply
    • Diane Poremsky says

      February 22, 2014 at 11:02 pm

      Do you get any errors? Add msgbox "working" right after the set omail line and replace debug.print with msgbox - this will kick up a dialog when the macro hits that line. It will tell us if its running. If its not running, did you check your macro security setting?

      Reply
  105. Javier says

    January 19, 2014 at 3:44 pm

    Hi Diane,

    I tried to send a reply in more than three times, and does not work, any reason...?

    regards,
    Javier

    Reply
    • Diane Poremsky says

      January 19, 2014 at 9:32 pm

      A reply here? We were working on a server update. If you mean an outlook message, did you get any error messages?

      Reply
  106. Fred says

    January 17, 2014 at 6:25 am

    Diane,
    Is there a way to have your code run from the rules wizard? I opened VBA from outlook, added a module and pasted your script. When i go to the rules manager i create a new rule and use the "Run a Script" as the action but when the pop up window appears to select the script to run its blank.

    any insight would be appreciated,
    Fred

    Reply
    • Diane Poremsky says

      January 17, 2014 at 8:05 am

      If it's properly formatted for a script, it should work. Try changing
      Public Sub SaveMessageAsMsg()
      Dim oMail As Outlook.MailItem

      to
      Public Sub SaveMessageAsMsg(oMail As Outlook.MailItem)

      and you need to remove the selection bits -
      For Each objItem In ActiveExplorer.Selection
      Set oMail = objItem
      and Next at the end.

      Reply
  107. Caroline Marie says

    January 14, 2014 at 4:19 pm

    Hi Diane,

    It works perfectly, thanks! :)

    However, I forgot to mention something important, when I asked for "a dialog box [that] appears and prompts the user to choose where to save the email".

    My previous VBA code (Windows XP) asked the user where to save the file and we could change the filename before saving it (example: https://i44.tinypic.com/2wpmtqg.jpg).

    We have clients who love (a little too much...) writing long subjects, so saving the whole e-mail subject (as of now) may be a problem (especially because our paths on our network are also awfully long). And my coworkers told me that they often changed the filename before saving their emails with the previous macro.

    Huge thanks in advance!

    Reply
    • Diane Poremsky says

      January 14, 2014 at 5:52 pm

      It can be tweaked to shorten the file name to nn number of characters. :)

      Outlook doesn't have a file dialog so you need to use Word's dialog or the windows common file dialog. I had this code sample handy - https://www.slipstick.com/code-samples/dirty-saveas-dialog.txt. Using word's dialog adds .docx to the filename but the code removes it and saves as msg format - that is why i call it a dirty saveas. :)

      Reply
      • Mike Gorman says

        September 20, 2016 at 5:21 am

        Diane - Love this site. don't suppose there is a way to alter this slightly so you just set the filepath once at the start for all the selected messages? Al though dirty, this saveas dialog is more friendly than the BrowseForFolder function :)

      • Diane Poremsky says

        September 20, 2016 at 8:16 am

        You can add a counter and if statement -
        add your Dim's
        Dim newPath As String
        Dim showDialog As Variant
        Dim lenPath As Long

        after enviro =, add these two lines:
        defaultPath = enviro & "\Documents\"
        showDialog = 1

        replace the block from If dlgSaveAs.InitialFileName to sPath = with this block:

        dlgSaveAs.InitialFileName = defaultPath & sName

        If showDialog = 1 Then
        If dlgSaveAs.Show = -1 Then
        strFolderpath = dlgSaveAs.SelectedItems(1)
        End If
        'remove .docx from file name
        sPath = Left(strFolderpath, Len(strFolderpath) - 5)

        lenPath = InStrRev(strFolderpath, "\")
        newPath = Left(strFolderpath, lenPath)
        Debug.Print lenPath, newPath
        Else
        sPath = newPath & sName
        End If

        then right before Next, add
        showDialog = showDialog + 1

        this brings up the word dialog on the first message and uses that path for the remaining messages in the selection.

      • Mike Gorman says

        October 28, 2016 at 9:52 am

        Thanks again! having some issues with the dialog box appearing behind Outlook, making it look like it has crashed. sometimes i can alt-tab to it but that doesnt always work...any idea how to guarantee it appears on the top?

      • Diane Poremsky says

        October 29, 2016 at 12:33 am

        No, i don't. Does it happen all the time or just sometimes?

      • Mike Gorman says

        October 31, 2016 at 3:52 am

        Just sometimes - i am trying to see if there is a trend but can't figure it out

  108. Caroline Marie says

    January 10, 2014 at 2:56 pm

    Hi Diane,

    Is there a way that, instead of hardcoding the path, a dialog box appears and prompts the user to choose where to save the email?

    I used to have a macro that would do so (using the SAFRCFileDlg.dll), but it doesn't work under Windows 7.

    Thanks!

    Reply
    • Diane Poremsky says

      January 10, 2014 at 4:50 pm

      See How to use Windows filepaths in a macro - you'll need the function from that page and replace spath line with something like this

      strFolderpath = BrowseForFolder("C:\Users\username\documents\")
      sPath = strFolderpath & "\"

      Reply
  109. Javier says

    December 31, 2013 at 3:17 pm

    It is possible a variation of the code to loop through all the sub folders that are in the inbox, and save all messages to local disk with the name of each folder, for example:

    \user\inbox\ ---> all messages that are in my inbox
    \user\inbox\ client 1 ---> all messages that are in my folder client 1 (sub folder of Inbox),
    and so on.

    Also save sent items.

    Any idea how I can modify the code to do this.

    Thanks in advance.

    Best regards,
    Javier

    Reply
    • Diane Poremsky says

      December 31, 2013 at 8:59 pm

      That is possible to do - this macro should do it for you. Saving All Messages to the Hard Drive Using VBA/

      Reply
  110. James Matthews says

    December 20, 2013 at 5:35 pm

    Diane - I keep getting an error message and the debug is showing a problem with the line: oMail.SaveAs sPath & sName, olMSG. When I scroll over "olMSG", I'm seeing olMSG = 3. Also, does it matter if the VBA is in Module1 or in ThisOutlookSession? Thank you.

    Reply
    • Diane Poremsky says

      December 21, 2013 at 11:53 pm

      This macro works in either module1 (well, any module) or in ThisOutlookSession, although a module is recommended.
      olMsg is a constant, value 3 so that is normal too.

      What does the error message say?
      Add
      debug.print sPath & sName
      right about the SaveAs line that fails then show the immediate window (ctrl+g) - is the path correct?

      Reply
  111. Anthony Stedman says

    September 25, 2013 at 12:56 am

    Hi Diane

    Thank you for coming back to me. You are an incredibly generous person with your time and I appreciate that.

    We all use the L drive in the office.

    I will fiddle with this code as per your suggestion.

    Cheers again. I don't know how to thank you for your time running this site. It has been invaluable to me,...

    A

    Reply
  112. Anthony Stedman says

    September 23, 2013 at 7:35 pm

    Hi Diane,

    I have gone with the vanilla approach in the absence of a better understanding of VBA... I will need to spend some more time on this for my sake (And perhaps for yours as well :-)

    I would love to be able to tell Outlook to save this email to a specific location on our server so that we can extend the same code to all 6 machines in the office.

    I saw this code example on one of your pages but have no idea how to insert same into the context of the larger string I was referring to earlier...

    Note: this function will work in any Office application, it is not specific to Outlook. (Actually, it's not specific to Office either, it's a general VB function.)

    Dim strFolderpath as String
    strFolderpath = "C:\OLAttachments\"
    Or use this to save to a folder using the user's profile in the path (example, C:\Users\Diane\)
    Dim enviro As String
    enviro = CStr(Environ("USERPROFILE"))
    strFolderpath = enviro & "\OLAttachments\"

    My file path to the server is L:\Client Filing\Email Filing

    Any assistance on this would be truly appreciated.

    Cheers, Anthony

    Reply
    • Diane Poremsky says

      September 24, 2013 at 7:39 am

      Does everyone use L: for the file share? If not, using the server name \\FileServer\client\filing would be universal.

      The important line is the one that sets the strFolderpath - how you set that path is up to you.

      you can use a hardcoded path:
      strFolderpath = "\\filesserver\path\OLAttachments\"
      or
      strFolderpath = "L:\Client Filing\Email Filing\"

      Reply
  113. Anthony Stedman says

    September 23, 2013 at 4:41 pm

    Hi Diane,
    Thank you for putting this code up. I am a newbie at this and am having some difficulty in running the code...
    I have followed your instructions to the letter but have made a change to the save path. When I run the code, I dont get a result and in fact, get a run error. The run error is runtime error... '-2147286788 (800300fc)':

    I have altered the save path to
    sPath = enviro & "C:\Users\Anthony\Desktop\Email Saved"

    Reply
    • Diane Poremsky says

      September 23, 2013 at 5:47 pm

      enviro gets the user account part of the path (so you can use the same code on different computers)

      Try

      sPath = enviro & "\Desktop\Email Saved\"

      Reply
  114. Maya Headley says

    July 26, 2013 at 8:22 am

    This is an excellent macro and it runs perfectly from VBA when I press F5, but not from Outlook itself. Can you help me troubleshoot? I want to have a button on my ribbon that I could easily press to make changes. I am a beginner, so I can use a lot of help. Thanks!

    Reply
    • Diane Poremsky says

      July 29, 2013 at 7:35 pm

      Do you get any error messages? Does it work if you run it from Developer ribbon > Macros ?

      There isn't any difference with this macro - it should work from either a button or the developer command. If you changed the name of the macro, the button won't work - you might want to remove the button and add it back to make sure the link between the button and macro isn't broken.

      Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Visit Slipstick Forums.
What's New at Slipstick.com

Latest EMO: Vol. 31 Issue 3

Subscribe to Exchange Messaging Outlook






Support Services

Do you need help setting up Outlook, moving your email to a new computer, migrating or configuring Office 365, or just need some one-on-one assistance?

Our Sponsors

CompanionLink
ReliefJet
  • Popular
  • Latest
  • Week Month All
  • Jetpack plugin with Stats module needs to be enabled.
  • Error Opening iCloud Appointments in Classic Outlook
  • Opt out of Microsoft 365 Companion Apps
  • Mail Templates in Outlook for Windows (and Web)
  • Urban legend: Microsoft Deletes Old Outlook.com Messages
  • Buttons in the New Message Notifications
  • Move Deleted Items to Another Folder Automatically
  • Open Outlook Templates using PowerShell
  • Count and List Folders in Classic Outlook
  • Google Workspace and Outlook with POP Mail
  • Import EML Files into New Outlook
Ajax spinner

Recent Bugs List

Microsoft keeps a running list of issues affecting recently released updates at Fixes or workarounds for recent issues in classic Outlook (Windows).

For new Outlook for Windows: Fixes or workarounds for recent issues in new Outlook for Windows .

Outlook for Mac Recent issues: Fixes or workarounds for recent issues in Outlook for Mac

Outlook.com Recent issues: Fixes or workarounds for recent issues on Outlook.com

Office Update History

Update history for supported Office versions is at Update history for Office

Outlook Suggestions and Feedback

Outlook Feedback covers Outlook as an email client, including Outlook Android, iOS, Mac, and Windows clients, as well as the browser extension (PWA) and Outlook on the web.

Outlook (new) Feedback. Use this for feedback and suggestions for Outlook (new).

Use Outlook.com Feedback for suggestions or feedback about Outlook.com accounts.

Other Microsoft 365 applications and services




New Outlook Articles

Error Opening iCloud Appointments in Classic Outlook

Opt out of Microsoft 365 Companion Apps

Mail Templates in Outlook for Windows (and Web)

Urban legend: Microsoft Deletes Old Outlook.com Messages

Buttons in the New Message Notifications

Move Deleted Items to Another Folder Automatically

Open Outlook Templates using PowerShell

Count and List Folders in Classic Outlook

Google Workspace and Outlook with POP Mail

Import EML Files into New Outlook

Newest Code Samples

Open Outlook Templates using PowerShell

Count and List Folders in Classic Outlook

Insert Word Document into Email using VBA

Warn Before Deleting a Contact

Use PowerShell to Delete Attachments

Remove RE:, FWD:, and Other Prefixes from Subject Line

Change the Mailing Address Using PowerShell

Categorize @Mentioned Messages

Send an Email When You Open Outlook

Delete Old Calendar Events using VBA

VBA Basics

How to use the VBA Editor

Work with open item or selected item

Working with All Items in a Folder or Selected Items

VBA and non-default Outlook Folders

Backup and save your Outlook VBA macros

Get text using Left, Right, Mid, Len, InStr

Using Arrays in Outlook macros

Use RegEx to extract message text

Paste clipboard contents

Windows Folder Picker

Custom Forms

Designing Microsoft Outlook Forms

Set a custom form as default

Developer Resources

Developer Resources

Developer Tools

VBOffice.net samples

SlovakTech.com

Outlook MVP David Lee

Repair PST

Convert an OST to PST

Repair damaged PST file

Repair large PST File

Remove password from PST

Merge Two Data Files

Sync & Share Outlook Data

  • Share Calendar & Contacts
  • Synchronize two computers
  • Sync Calendar and Contacts Using Outlook.com
  • Sync Outlook & Android Devices
  • Sync Google Calendar with Outlook
  • Access Folders in Other Users Mailboxes

Diane Poremsky [Outlook MVP]

Make a donation

Mail Tools

Sending and Retrieval Tools

Mass Mail Tools

Compose Tools

Duplicate Remover Tools

Mail Tools for Outlook

Online Services

Calendar Tools

Schedule Management

Calendar Printing Tools

Calendar Reminder Tools

Calendar Dates & Data

Time and Billing Tools

Meeting Productivity Tools

Duplicate Remover Tools

Productivity

Productivity Tools

Automatic Message Processing Tools

Special Function Automatic Processing Tools

Housekeeping and Message Management

Task Tools

Project and Business Management Tools

Choosing the Folder to Save a Sent Message In

Run Rules on messages after reading

Help & Suggestions

Submit Outlook Feature Requests

Slipstick Support Services

Buy Microsoft 365 Office Software and Services

Visit Slipstick Forums.

What's New at Slipstick.com

Home | Outlook User | Exchange Administrator | Office 365 | Outlook.com | Outlook Developer
Outlook for Mac | Common Problems | Utilities & Addins | Tutorials
Outlook & iCloud Issues | Outlook Apps
EMO Archives | About Slipstick | Slipstick Forums
Submit New or Updated Outlook and Exchange Server Utilities

Send comments using our Feedback page
Copyright © 2026 Slipstick Systems. All rights reserved.
Slipstick Systems is not affiliated with Microsoft Corporation.