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

Save and Delete Attachments from Outlook messages

Slipstick Systems

› Developer › Code Samples › Save and Delete Attachments from Outlook messages

Last reviewed on July 18, 2018     126 Comments

The following is the Save Attachment code sample from Teach Yourself Outlook 2003 in 24 Hours. (It works in current versions.)

Frank modified the code to break it into a single call for each mail item so you can use it with a rule to filter incoming mail. Augusto modified Frank's code "in order to avoid file overwriting when the attachment name is the same as an existing one (i.e. details.txt on a return receipt email). Now, the attachments are saved in the format “SenderName.ReceivedDate.filename.ext” and then the attachment is deleted from the original email." Augusto's code modification. There is also a version that deletes all attachments in the selected folder.

To use, first create a folder under your My Documents named OLAttachments. Then select one or more messages and run the macro to save and remove the attachments. (May wish to comment out the line that deletes the attachment before testing). Remove or comment out the MsgBox lines after testing.

To delete the attachments without saving them, leave just these lines between the If... and End if. (The macro can also be edited to remove the statements above the If command that are no longer needed.)

If lngCount > 0 Then
 For i = lngCountb To 1 Step -1
 
 ' Delete the attachment.
 objAttachments.Item(i).Delete
 
 Next i
 objMsg.Save
 
 End If

Copy and paste the code from this page into your ThisOutlookSession project. To do this, you can either move your mouse to the right of the first line and click the Copy button (or view source code button then select all, copy and paste). Or copy it from this text file: Save and Delete Attachments. After pasting the code into the VB Editor, it should be colored similar to the code below. A Red line indicates problems with the line.

In Outlook, press Alt+F11 to open the VBA editor and expand Microsoft Outlook Objects then double click on ThisOutlookSession to open it in the editing pane and Ctrl+V to paste the code.

Public Sub SaveAttachments()
 Dim objOL As Outlook.Application
 Dim objMsg As Outlook.MailItem 'Object
 Dim objAttachments As Outlook.Attachments
 Dim objSelection As Outlook.Selection
 Dim i As Long
 Dim lngCount As Long
 Dim strFile As String
 Dim strFolderpath As String
 Dim strDeletedFiles As String

    ' Get the path to your My Documents folder
    strFolderpath = CreateObject("WScript.Shell").SpecialFolders(16)
    On Error Resume Next

     ' Instantiate an Outlook Application object.
     Set objOL = CreateObject("Outlook.Application")

     ' Get the collection of selected objects.
     Set objSelection = objOL.ActiveExplorer.Selection

     ' Set the Attachment folder.
     strFolderpath = strFolderpath & "OLAttachments"

     'Use the MsgBox command to troubleshoot. Remove it from the final code.
     MsgBox strFolderpath
 
     ' Check each selected item for attachments. If attachments exist,
     ' save them to the Temp folder and strip them from the item.
     For Each objMsg In objSelection

     ' This code only strips attachments from mail items.
     ' If objMsg.class=olMail Then
     ' Get the Attachments collection of the item.
     Set objAttachments = objMsg.Attachments
     lngCount = objAttachments.Count

     'Use the MsgBox command to troubleshoot. Remove it from the final code.
     MsgBox objAttachments.Count

     If lngCount > 0 Then

     ' We need to use a count down loop for removing items
     ' from a collection. Otherwise, the loop counter gets
     ' confused and only every other item is removed.
     
     For i = lngCount To 1 Step -1
     
     ' Save attachment before deleting from item.
     ' Get the file name.
     strFile = objAttachments.Item(i).FileName
     
     ' Combine with the path to the Temp folder.
     strFile = strFolderpath & strFile
     
     ' Save the attachment as a file.
     objAttachments.Item(i).SaveAsFile strFile
     
     ' Delete the attachment.
     objAttachments.Item(i).Delete
     
     'write the save as path to a string to add to the message
     'check for html and use html tags in link
     If objMsg.BodyFormat <> olFormatHTML Then
         strDeletedFiles = strDeletedFiles & vbCrLf & ""
         Else
         strDeletedFiles = strDeletedFiles & "
" & "" & strFile & "" End If 'Use the MsgBox command to troubleshoot. Remove it from the final code. MsgBox strDeletedFiles Next i 'End If ' Adds the filename string to the message body and save it ' Check for HTML body If objMsg.BodyFormat <> olFormatHTML Then objMsg.Body = objMsg.Body & vbCrLf & _ "The file(s) were saved to " & strDeletedFiles Else objMsg.HTMLBody = objMsg.HTMLBody & "

" & _ "The file(s) were saved to " & strDeletedFiles & "

" End If objMsg.Save 'sets the attachment path to nothing before it moves on to the next message. strDeletedFiles = "" End If Next ExitSub: Set objAttachments = Nothing Set objMsg = Nothing Set objSelection = Nothing Set objOL = Nothing End Sub

Frank's Modification

Frank modified the structure to break the code into a single call for each mail item. This way, the code can be used for all items selected, but at the same time a RULE can invoke the code also when incoming mail hits the box. here’s the modification.

Public Sub SaveAttachments()
    Dim objOL As Outlook.Application
    Dim pobjMsg As Outlook.MailItem 'Object
    Dim objSelection As Outlook.Selection

    ' Get the path to your My Documents folder
    strFolderpath = CreateObject("WScript.Shell").SpecialFolders(16)
    On Error Resume Next

    ' Instantiate an Outlook Application object.
    Set objOL = CreateObject("Outlook.Application")

    ' Get the collection of selected objects.
    Set objSelection = objOL.ActiveExplorer.Selection

    For Each pobjMsg In objSelection
        SaveAttachments_Parameter pobjMsg
    Next

ExitSub:

    Set pobjMsg = Nothing
    Set objSelection = Nothing
    Set objOL = Nothing
End Sub

Public Sub SaveAttachments_Parameter(objMsg As MailItem)
    Dim objAttachments As Outlook.Attachments
    Dim i As Long
    Dim lngCount As Long
    Dim strFile As String
    Dim strFolderpath As String
    Dim strDeletedFiles As String

    ' Get the path to your My Documents folder
    strFolderpath = CreateObject("WScript.Shell").SpecialFolders(16)
    On Error Resume Next

    ' Set the Attachment folder.
    strFolderpath = strFolderpath & "OLAttachments"

        ' Get the Attachments collection of the item.
        Set objAttachments = objMsg.Attachments
        lngCount = objAttachments.Count

        If lngCount > 0 Then

            ' We need to use a count down loop for removing items
            ' from a collection. Otherwise, the loop counter gets
            ' confused and only every other item is removed.
            For i = lngCount To 1 Step -1

                ' Save attachment before deleting from item.
                ' Get the file name.
                strFile = objAttachments.Item(i).FileName

                ' Combine with the path to the Temp folder.
                strFile = strFolderpath & strFile

                ' Save the attachment as a file.
                objAttachments.Item(i).SaveAsFile strFile

                ' Delete the attachment.
                'objAttachments.Item(i).Delete

                'write the save as path to a string to add to the message
                'check for html and use html tags in link
                If objMsg.BodyFormat  olFormatHTML Then
                   strDeletedFiles = strDeletedFiles & "
" & "" & strFile & "" Else strDeletedFiles = strDeletedFiles & vbCrLf & "" End If Next i End If ' Adds the filename string to the message body and save it [COMMENTED AS THIS FUNCTION WAS NOT DESIRED] ' Check for HTML body ' If objMsg.BodyFormat olFormatHTML Then ' objMsg.Body = objMsg.Body & vbCrLf & _ ' "The file(s) were saved to " & strDeletedFiles ' Else ' objMsg.HTMLBody = objMsg.HTMLBody & "" & _ ' "The file(s) were saved to " & strDeletedFiles & "" ' End If objMsg.Save ExitSub: Set objAttachments = Nothing Set objMsg = Nothing Set objOL = Nothing End Sub

Augusto's Modification


Augusto
made some modifications on Frank’s code, in order to avoid file overwriting when the attachment name is the same as an existing one (i.e. details.txt on a return receipt email). Now, the attachments are saved in the format “SenderName.ReceivedDate.filename.ext” and then the attachment is deleted from the original email.

Here is Augusto's code:

Public Sub SaveAttachments()
Dim objOL As Outlook.Application
Dim pobjMsg As Outlook.MailItem 'Object
Dim objSelection As Outlook.Selection
 
' Get the path to your My Documents folder
strFolderpath = CreateObject("WScript.Shell").SpecialFolders(16)
On Error Resume Next
 
' Instantiate an Outlook Application object.
Set objOL = CreateObject("Outlook.Application")
 
' Get the collection of selected objects.
Set objSelection = objOL.ActiveExplorer.Selection
 
For Each pobjMsg In objSelection
SaveAttachments_Parameter pobjMsg
Next
 
ExitSub:
 
Set pobjMsg = Nothing
Set objSelection = Nothing
Set objOL = Nothing
End Sub
 
Public Sub SaveAttachments_Parameter(objMsg As MailItem)
Dim objAttachments As Outlook.Attachments
Dim i As Long
Dim lngCount As Long
Dim strFile As String
Dim strFolderpath As String
Dim strDeletedFiles As String
 
' Get the path to your My Documents folder
strFolderpath = CreateObject("WScript.Shell").SpecialFolders(16)
On Error Resume Next
 
' Set the Attachment folder.
strFolderpath = strFolderpath & "\OLAttachments\"
 
' Get the Attachments collection of the item.
Set objAttachments = objMsg.Attachments
lngCount = objAttachments.Count
 
If lngCount > 0 Then
 
' We need to use a count down loop for removing items
' from a collection. Otherwise, the loop counter gets
' confused and only every other item is removed.
For i = lngCount To 1 Step -1
 
' Save attachment before deleting from item.
' Get the file name.
strFile = objAttachments.Item(i).FileName
 
' Combine with the path to the Temp folder.
strFile = strFolderpath & objMsg.SenderName & "." & Format(objMsg.ReceivedTime, "yyyy-MM-dd h-mm-ss") & "." & strFile
 
' Save the attachment as a file.
objAttachments.Item(i).SaveAsFile strFile
 
' Delete the attachment.
objAttachments.Item(i).Delete
 
'write the save as path to a string to add to the message
'check for html and use html tags in link
If objMsg.BodyFormat olFormatHTML Then
                   strDeletedFiles = strDeletedFiles & "
" & "" & strFile & "" Else strDeletedFiles = strDeletedFiles & vbCrLf & "" End If Next i End If ' Adds the filename string to the message body and save it ' Check for HTML body If objMsg.BodyFormat olFormatHTML Then objMsg.Body = objMsg.Body & vbCrLf & _ "The file(s) were saved to " & strDeletedFiles Else objMsg.HTMLBody = objMsg.HTMLBody & "" & _ "The file(s) were saved to " & strDeletedFiles & "" End If objMsg.Save ExitSub: Set objAttachments = Nothing Set objMsg = Nothing Set objOL = Nothing End Sub

Delete all attachments in the selected folder

Select a folder and run this code to process all messages in the current folder. The "magic" in this code is using the CurrentFolder object: Set Mail = objOL.ActiveExplorer.CurrentFolder instead of the Selection object.

Public Sub SaveDeleteAttachments()
 
Dim objOL As Outlook.Application
Dim objMsg As Outlook.MailItem 'Object
Dim objAttachments As Outlook.Attachments
Dim i As Long
Dim lngCount As Long
Dim strFile As String
Dim strFolderpath As String
Dim strDeletedFiles As String

    strFolderpath = CreateObject("WScript.Shell").SpecialFolders(16)
    On Error Resume Next
    strFolderpath = strFolderpath & "OLAttachments"

    Set objOL = CreateObject("Outlook.Application")
    Set Mail = objOL.ActiveExplorer.CurrentFolder
	
    For Each objMsg In Mail.Items

    Set objAttachments = objMsg.Attachments
    lngCount = objAttachments.Count

    If lngCount > 0 Then

    For i = lngCount To 1 Step -1

    strFile = objAttachments.Item(i).FileName
    strFile = strFolderpath & strFile

    objAttachments.Item(i).SaveAsFile strFile
    objAttachments.Item(i).Delete

    If objMsg.BodyFormat <> olFormatHTML Then
        strDeletedFiles = strDeletedFiles & vbCrLf & ""
        Else
        strDeletedFiles = strDeletedFiles & "
" & "" & strFile & "" End If Next i 'End If If objMsg.BodyFormat <> olFormatHTML Then objMsg.Body = objMsg.Body & vbCrLf & _ "The file(s) were saved to " & strDeletedFiles Else objMsg.HTMLBody = objMsg.HTMLBody & "

" & _ "The file(s) were saved to " & strDeletedFiles & "

" End If objMsg.Save strDeletedFiles = "" End If Next ExitSub: Set objAttachments = Nothing Set objMsg = Nothing Set objOL = Nothing End Sub
Save and Delete Attachments from Outlook messages was last modified: July 18th, 2018 by Diane Poremsky
Post Views: 88

Related Posts:

  • Save Messages and Attachments to a New Folder
  • Browseforfolder_2
    How to use Windows File Paths in a Macro
  • Save and Open an Attachment using VBA
  • Save Attachments to the Hard Drive

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. Andy M says

    December 16, 2021 at 1:53 pm

    Do you have a solution for preserving links to folders with spaces in their names? I tried to bracket the link with "<" and ">" like I would if I were writing an email, but it ends up erasing the link altogether...

    Reply
    • Diane Poremsky says

      December 16, 2021 at 10:56 pm

      Try replacing the spaces with %20. Yes, its ugly, but should definitely work if brackets and quotes around the folder name doesn't work.

      Reply
  2. Claudia says

    January 13, 2021 at 11:20 am

    ok, I have found a way to avoid that embedded signature pictures (mostly png) are getting deleted. There was a hint far down in the comments: only save/delete certain file types:
    look for the line strFile = objAttachments.Item(i).FileName
    Add this under

    sFileType = LCase$(Right$(strFile, 4))

       Select Case sFileType
           Case ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".zip"
       ' only if the file types are found - you can add more

    Now look for the line 'write the save as path to a string to add to the message
    Add this behind the first End If


    End Select
    ' end selection file types are found

    This works very good ;-)

    Reply
  3. Claudia says

    January 5, 2021 at 11:23 am

    Hi, these macro codes are really helpfull, I use a mix especially with augustos code : delete attachments from selected mails one without saving, one with and deletion info at top of the mail without links only text,
    but one thing is still missing and wasn't asked yet:

    • how can I change the code to only delete attachments which are NOT Embedded "hidden" like signature pictures?

    Is there a way to exclude those?

    Thanks in Advance ;-)

    Reply
  4. Richard says

    October 22, 2020 at 12:02 pm

    A user has sent out 150+ individual emails with an attached word doc containing un-compressed images (so the word doc is 8.8Mb) but there are other attachments to each email we need to retain.

    So if anyone can provide a script to remove just a specific attachment e.g letter.docx from all emails in the Sent Item folder, it would be a huge help.

    Reply
  5. Sos says

    September 5, 2020 at 3:54 am

    HI im not a programmer, so i dont undetrstand much of what you are saying could you give me a script for deleting inbox attachments with file type??

    Reply
  6. Patrick Tingen says

    July 1, 2020 at 5:47 am

    I receive emails with email inside. I need the attachments that are inside that embedded email. What should I change to get this to work?

    Reply
  7. Ben says

    June 18, 2020 at 1:59 am

    Is it possible to have the file path links posted in the email thread appear at the very top instead of at the bottom?

    Reply
    • Diane Poremsky says

      June 18, 2020 at 4:42 pm

      Sure. Just change the order in the code:

      If objMsg.BodyFormat <> olFormatHTML Then
      objMsg.Body = objMsg.Body & vbCrLf & _
      "The file(s) were saved to " & strDeletedFiles
      Else
      objMsg.HTMLBody = objMsg.HTMLBody & "

      " & _
      "The file(s) were saved to " & strDeletedFiles & "

      "
      End If

      If objMsg.BodyFormat <> olFormatHTML Then
      objMsg.Body = "The file(s) were saved to " & strDeletedFiles & vbCrLf & _
      objMsg.Body
      Else
      ' i think this is right - i did not test. The html p's add a little complexity.
      objMsg.HTMLBody = "

      The file(s) were saved to " & strDeletedFiles" & _
      "

      " & objMsg.HTMLBody
      End If

      Reply
      • Ben says

        June 18, 2020 at 4:53 pm

        It worked flawlessly. Thank you very much for this. What an incredibly powerful tool!

  8. Paul says

    May 28, 2020 at 5:01 pm

    I'm using the Selected Folder code but am getting the following error when stepping through the code. "objMsg.Body = " Application-defined or object-defined error
    and nothing is being written to the email body. Email is in Text format (objMsg.BodyFormat =1).
    Thanks.

    Reply
  9. Max says

    May 4, 2020 at 6:10 am

    Hi Diane,

    So I have created a folder named "OLAttachments" in my My Documents folder. I have pasted the following code attached in VB under ThisOutlookSession. I have created a Rule with the following parameters:

    (doesn't include ")

    Apply this rule after the message arrives
    from "larry.jones31@live.com.au"
    and with "Bonus" in the subject
    and which has an attachment
    and on this computer only
    run "Project1.ThisOutlookSession.SaveAttachments Parameter

    When an e-mail hits the account I get the New Mail Alerts with the e-mail received details an 3 options:

    Edit Rule
    Open Item
    Close

    I'm not sure where I'm going wrong if you could please help.

    Reply
    • Diane Poremsky says

      July 1, 2020 at 10:05 am

      That is the new mail alert dialog. Do you have a rule that has that set as the action? If you add stop processing rules to this rule, does the dialog still come up?

      Reply
  10. Ram says

    April 23, 2020 at 9:21 am

    Good script - Hope you can help me - I need to save the attachment from INBOX to C:\Temp folder and delete the email from INBOX. How can, I achieve this? Appreciate your help.

    Reply
    • Diane Poremsky says

      April 23, 2020 at 10:08 am

      Change the path where it sets the special folders:
      strFolderpath = "C:\Temp\"
      or later in the code where it adds the attachment folder - if you aren't using a subfolder, use just c:\temp here -
      strFolderpath = "C:\Temp\OLAttachments"

      After it is saved, use this to delete the message.
      objMsg.Delete

      Reply
      • Ram says

        April 24, 2020 at 11:01 am

        Which code should, I use (Frank or Augusto)? I have created a folder called OLAttachments within Documents folder. No need to use C:\Temp.

        Where exactly, I should use objMsg.Delete -is at the end of Frank or Augusto code?

      • Ram says

        April 24, 2020 at 11:09 am

        Is this code correct for usage - I can test this after your confirmation. Appreciate your help,

  11. Christian says

    December 15, 2019 at 10:16 am

    Great resource. Thank you.

    Reply
  12. Bill says

    November 25, 2019 at 5:36 pm

    Would it be possible highlight or put in quotes the parts of your code that need to be customized? For example, I am not sure where in your code I need to update with my folder path and/or file names? This would be great to see in your code that auto-saves files as they are received (when new files are received in my subfolder, wanting these saved over an existing file on my C drive)

    Reply
    • Diane Poremsky says

      November 25, 2019 at 10:08 pm

      Because of the way the code is formatted, i can't highlight lines that needed edited, but I usually have a comment at the lines that need changed. Plus, as much as possible, I try to use default paths so the macros "just work"

      This is where the folder path is - it uses the documents folder.
      strFolderpath = strFolderpath & "OLAttachments"
      to use a different folder path, use
      strFolderpath = "C:\My New Folder\Attachments"

      Reply
  13. Ned says

    October 8, 2019 at 11:45 pm

    Can somebody please change this code so is save attachment in next format :
    "subject line"+"_"Date,time".pdf :

    Public Sub SaveAutoAttach(item As Outlook.MailItem)
    Dim object_attachment As Outlook.Attachment
    Dim saveFolder As String
    ' Folder location when I want to save my file
    saveFolder = "D:\Data\Archive"

    For Each object_attachment In item.Attachments
    ' Criteria to save .pdf files only
    If InStr(object_attachment.DisplayName, ".pdf") Then

    object_attachment.SaveAsFile saveFolder & "\" & object_attachment.DisplayName

    End If

    Next

    End Sub

    THANKS

    Reply
  14. Lee says

    August 21, 2019 at 8:06 am

    Just to say Augusto's modification of this did exactly what I wanted - thank you! There were a couple of equals = missing from If objMsg.BodyFormat = olFormatHTML - but after adding them it worked a treat :)

    Reply
  15. Brad Walters says

    August 12, 2018 at 1:24 am

    Keep getting Compile Error on the following line:
    If objMsg.BodyFormat olFormatHTML Then

    Exact compile error is: "Expected: Then or GoTo"
    And the olFormatHTML is highlighted. I am assuming that is the cause of the error but I don't know what the fix it.

    I am using Outlook 2010.

    Reply
  16. Margaret says

    June 26, 2017 at 11:01 am

    I modified Augusto's code to:
    1. Allow the user (me) to choose which folder to save the attachments to at run time and also to offer a default folder.
    2. Optionally allow the user to chose different folders for different emails (but this needs work as right now the user does not get to see each subject line before choosing a folder, so I recommend either removing this option or improving it).
    3. Add a new category, "Attachment," to all the emails for which attachments are removed.
    4. Add some constants at the top to make future changes easier.

    My code does not all fit in this comments box. Here is the first part:

    Public Sub SaveAttachments()
    ' Saves attachments in current folder. See https://www.slipstick.com/developer/code-samples/save-and-delete-attachments/#Augusto
    ' Modified by Margaret Blauvelt, mendoclick.com, 6/26/2017
    Const cstrDefaultAttachmentsSubfolder = "DataOutlookExtractionsAttachments"
    Const cintMyDocuments = 16
    Const cstrAttachCategory = "Attachment"
    Dim objOL As Outlook.Application
    Dim pobjMsg As Outlook.MailItem 'Object
    Dim objSelection As Outlook.Selection
    Dim strMyDocs As String
    Dim strFolderPath As String
    Dim strAlternateAttachmentsFolder As String
    Dim booSaveMultiplePlaces As Boolean
    Dim strCats As String

    ' We will add a category to each email for which attachment(s) were saved and deleted.
    ' Also make sure that category already exists in Outlook's categories collection.
    Call AddCategoryToCategories(cstrAttachCategory)

    ' Get the path to your My Documents folder
    strMyDocs = CreateObject("WScript.Shell").SpecialFolders(cintMyDocuments)
    On Error Resume Next

    ' Ask user if wants to save the attachments all to the same folder.
    Select Case MsgBox("Do you want to save to more than one folder", vbYesNoCancel, "Multiple Folders or Just One?")
    Case vbCancel
    Exit Sub
    Case vbYes
    booSaveMultiplePlaces = True
    Case Else
    booSaveMultiplePlaces = False
    End Select

    Reply
    • Parker says

      October 23, 2017 at 6:30 pm

      Hi Margaret,
      you said your code does not all fit in the comments box. Is the rest of this code somewhere? It looks really good.

      Reply
  17. Dan E says

    May 10, 2017 at 4:17 pm

    Disregard my previous question, I figured out how to change the path of the folder the file saves at. My new question is how can I make the folder path a clickable hyperlink?

    Reply
    • Diane Poremsky says

      May 11, 2017 at 12:02 am

      For HTML, you'd use this url format: file://server/folder/file.ext

      to hyperlink html, use
      strDeletedFiles = strDeletedFiles & "
      " & "" & strFile & ""

      Reply
      • Kent S says

        July 17, 2018 at 6:03 pm

        This code is great and will save me a lot of time. Could you expand on your hyperlinking reply; I don't quite follow on what needs to change in Augusto's version. Thank you!

      • Diane Poremsky says

        July 18, 2018 at 1:43 am

        You'll need to build the link - and uncomment the code that writes it to the message body.

        hmm. It looks like the code is messed up -
        This would create the html link:
        strDeletedFiles = strDeletedFiles & "
        " & "" & strFile & ""

        (I fixed the code. )

  18. Dan E says

    May 10, 2017 at 12:30 pm

    Hi Diane,

    I am trying to use the Augusto's Modification but am having an issue. I plan on using this code to run on a public folder that my office uses, so the files need to be accessible for the entire office. I need to modify the code so I can save the attachments automatically on the shared drive instead of in My Documents. The path location will not change so I do not want to have to select a folder every time, I just want to be able to set a direct path inside the code itself. Any assistance with doing this would be greatly appreciated!

    Reply
    • Diane Poremsky says

      May 24, 2017 at 11:25 pm

      It might work best if the drive is mapped so you can use a drive letter because outlook can be slow saving to a network location, but all you need to do is change the path here:
      strFolderpath = strFolderpath & "\OLAttachments\"
      use strFolderpath = "H:\folder\subfolder\" or strFolderpath = "\\servernamae\folder\"

      Reply
  19. Max says

    March 7, 2017 at 5:34 pm

    Hi,
    I have "Compile error: Syntax error" once I click Run. I have Windows 10 Pro and Outlook 2016. I enabled all macros and created OLAttachments folder. After pasting the code into VB editor I have multiple red lines as I understand implying the problem.
    Please help me to solve the issue.
    Thank you.
    -Max

    Reply
    • Diane Poremsky says

      March 10, 2017 at 1:02 am

      The problem is with the red lines - red = bad. Either the code picked up something goofy in the copy and paste or it's in the wrong place in the module. This isn't an auto-macro, so it's more likely the copy and paste.

      Which of the macros are you using?

      Reply
  20. Jay says

    February 17, 2017 at 4:38 pm

    Very useful!

    Had to fix a few things:
    - the 'specialfolders' path didn't work (Win 7) - probably because it is a protected folder. Instead I hard-coded the folderpath (only in the second sub - it is not needed in the first sub (which calls the 2nd one)
    - strDeletedFiles was not filled, so no string was added to the message

    You can find the updated code here (I commented out the original lines - just in case): https://codepaste.net/xynarh

    Reply
    • Diane Poremsky says

      February 22, 2017 at 9:51 pm

      Specialfolders should definitely work with Windows 7 - it's supported in all versions.

      Reply
  21. Martin says

    January 30, 2017 at 10:43 am

    Hi, great code. I am a novice in VBA.. I need some help.
    What I want to add / change to your code: save all attachments from specific folder (like Inboxtest ) only with extension ".gpg"
    Can you help me?

    Thank You.
    Martin

    Reply
    • Diane Poremsky says

      January 30, 2017 at 12:20 pm

      You need to add an if statment.
      For i = lngCount To 1 Step -1
      strFile = objAttachments.Item(i).FileName
      ' This code looks at the last 4 characters in a filename
      sFileType = LCase$(Right$(strFile, 4))
      if sFileType = ".gpg" then
      ' Combine with the path to the Temp folder.
      strFile = strFolderpath & strFile
      -- snip--

      Reply
      • Martin says

        January 31, 2017 at 3:08 am

        Thank you for reply but can you explaine how to add this "if statement" (i have compile errors) to your code?
        Another question: where is defined path to the subfolder in Inbox where is emails with specific extensions? I have a rule that move every email with extension .gpg to this subfolder.
        Thank you again!
        Martin

      • Diane Poremsky says

        February 9, 2017 at 4:16 pm

        the code replaces the block that begins and ends with these lines:
        For i = lngCount To 1 Step -1

        strFile = strFolderpath & strFile

      • Martin says

        February 1, 2017 at 10:46 am

        How can i add an if statement to you code? i have some compile errors... i am new in VBA..
        i need define subfolder in Inbox from where all attachements have been saved (only with extension .gpg)
        Thank you.
        Martin

      • Diane Poremsky says

        February 9, 2017 at 4:15 pm

        The macro as written works on any folder - you just need to select the messages. It can be converted to run on all messages in a selected folder or on all messages in a specific folder - these are the lines that tell it what folder and messages to use:
        Set objSelection = objOL.ActiveExplorer.Selection
        For Each objMsg In objSelection

        You'd use this for all items in a specific folder
        Dim objFolder As Outlook.MAPIFolder
        Dim objItems As Outlook.Items
        Set objFolder = Session.GetDefaultFolder(olFolderInbox).Folders("foldername")
        Set objItems = objFolder.Items
        For Each objMsg In objItems
        more info at https://www.slipstick.com/developer/code-samples/working-items-folder-selected-items/

      • Martin says

        February 15, 2017 at 8:37 am

        Thank You,
        but where in the code is defined specific folder from where i need save all ".gpg" attachements? I have one subfolder in Inbox where is the messages with this extension..

      • Diane Poremsky says

        March 10, 2017 at 1:47 am

        This: For Each objMsg In objSelection tells it to work off the selected message. The last macro on page 3 works on all messages in the selected folder. It's also possible to hard code a specific folder - Set objFolder = Session.GetDefaultFolder(olFolderInbox).Folders("subfolder") would apply to message in a subfolder named 'subfolder' of the inbox.
        https://www.slipstick.com/developer/working-vba-nondefault-outlook-folders/ has more information.

      • Martin says

        February 15, 2017 at 10:18 am

        I have now this:
        DIM***

        ' Get the path to your My Documents folder
        strFolderpath = "C:*****"
        On Error Resume Next
        ' Instantiate an Outlook Application object.
        Set objOL = CreateObject("Outlook.Application")
        ' Get the collection of selected objects.
        Set objSelection = objOL.ActiveExplorer.Selection
        ' Set the Attachment folder.
        strFolderpath = strFolderpath
        'Use the MsgBox command to troubleshoot. Remove it from the final code.
        MsgBox strFolderpath
        ' Check each selected item for attachments. If attachments exist,
        ' save them to the Temp folder and strip them from the item.
        For Each objMsg In objSelection
        ' This code only strips attachments from mail items.
        ' If objMsg.class=olMail Then
        ' Get the Attachments collection of the item.
        Set objAttachments = objMsg.Attachments
        lngCount = objAttachments.Count

        'Use the MsgBox command to troubleshoot. Remove it from the final code.
        MsgBox objAttachments.Count

        If lngCount > 0 Then

        ' We need to use a count down loop for removing items
        ' from a collection. Otherwise, the loop counter gets
        ' confused and only every other item is removed.

        For i = lngCount To 1 Step -1

        ' Save attachment before deleting from item.
        ' Get the file name.
        strFile = objAttachments.Item(i).FileName
        sFileType = LCase$(Right$(strFile, 4))
        If sFileType = ".gpg" Then

        ' Combine with the path to the Temp folder.
        strFile = strFolderpath & objMsg.SenderName & "." & Format(objMsg.ReceivedTime, "yyyy-MM-dd h-mm-ss") & "." & strFile

        End If
        ' Save the attachment as a file.
        objAttachments.Item(i).SaveAsFile strFile

        ' Delete the attachment.
        objAttachments.Item(i).Delete
        'write the save as path to a string to add to the message
        'check for html and use html tags in link
        If objMsg.BodyFormat olFormatHTML Then
        strDeletedFiles = strDeletedFiles & vbCrLf & ""
        Else
        strDeletedFiles = strDeletedFiles & "" & "<a href='file://" & _

        but this macro save all attachements.. not only with .gpg extension...

      • Diane Poremsky says

        March 29, 2017 at 9:02 am

        Sorry I missed this earlier. You have the Save outside of the If block - anything you need to do to the message identified by the If needs to be inside the IF -
        If sFileType = ".gpg" Then
        ' Combine with the path to the Temp folder.
        strFile = strFolderpath & objMsg.SenderName & "." & Format(objMsg.ReceivedTime, "yyyy-MM-dd h-mm-ss") & "." & strFile
        objAttachments.Item(i).SaveAsFile strFile
        ' Delete the attachment.
        objAttachments.Item(i).Delete
        End If

  22. Nick from London says

    June 24, 2016 at 5:16 am

    Just wanted to thank you for the code. Very useful. Adjusted it to leave original message unaltered. I use Windows Folder Browser to set save location, as we save attachments by project.

    Reply
  23. D Poremsky says

    October 16, 2015 at 10:51 pm

    BReight before that line add either
    debug.print strFile
    or
    msgbox strfile

    The first writes the path to the immediate window, the second pops up a dialog containing the file path. Either way, verify the path it is trying to use exists.

    Reply
  24. Robert Haages says

    May 8, 2015 at 5:40 am

    Hi Diane, using Augusto's code, how would i add the functionality to check for a filesize of say greater than >5 or 10KB and then save all those items? I've seen an example in one of your earlier posts, but i'm unsure of where to put it in the code. My earlier attempts have resulted in a failure. Thanks ahead!

    Reply
  25. D Poremsky says

    March 10, 2015 at 6:07 pm

    Which code sample are you using? I tested it with the first code and its working correctly here - the files are saves as msg files.

    What version of Windows do you use? Are you showing file extensions?

    Reply
  26. D Poremsky says

    March 10, 2015 at 5:59 pm

    You'll need to check for mailitem type and skip if not mail items.
    Although not the best solution, you could change this
    Dim objMsg As Outlook.MailItem 'Object

    to
    Dim objMsg As Object

    the correct solution is to check for the item type - this is one way to do that;

    If TypeOf objMsg Is Outlook.MailItem Then
    ' continue with the macro
    End If

    Reply
  27. D Poremsky says

    February 11, 2015 at 8:21 am

    The last macro on page 3: http://www.outlook-tips.net/code-samples/save-and-delete-attachments/3/

    Deletes all attachments on messages in the selected folder. Select the Sent folder and run it.

    Reply
  28. Ve Kris says

    February 6, 2015 at 3:59 am

    Dear All,
    Thanks for this script but i am facing a issue using this script where i would need your help.
    Attached this script Run as script rule and the rule is created as Client only rule. Which is supposed to run on a specific email id when the email arrives.But i see this script is not getting executed via the rule when email reaches the mailbox. Any help is appreciated.

    Reply
    • D Poremsky says

      February 9, 2015 at 9:35 am

      What changes did you make when you converted it to work in a run-a-script rule? At minimum you need to remove the loop - For Each objMsg In Mail.Items and Next lines need to go.

      Reply
      • Ve Kris says

        February 12, 2015 at 10:03 pm

        Hello Poremsky,
        Thanks for responding.
        I managed to fix the issue and it seems due to the fact the changes i made was not saved properly.

  29. wschloss says

    October 25, 2014 at 12:47 am

    This is WAY cool. I downloaded it, tweaked, tested (step mode), and ran against 9 years of email, all in about an hour, and I can barely program! Thank you SO much!

    Reply
  30. Jason Levine says

    October 2, 2013 at 1:38 pm

    I have a script that moves any message with an attachment to a user-selected folder, and the script moves not only attachments listed on the attachment line but also embedded or inline attachments, like signatures, or pasted in graphics. I would like to be able to eliminate these embedded attachments and only move the messages with the traditional attachments. I'm using Outlook 2010 and haven't found a good way to do this yet and any advice or direction would be appreciated.

    Reply
    • Diane Poremsky says

      October 2, 2013 at 3:05 pm

      Short version: you didn't find a way because their is no way to differentiate because attachments and embedded. However, there are two things you might be able to do: check attachment size and only move larger attachments. If the attachments you need to move are large this will work great - typical signature graphics are under 5 or 10 KB. Use a value high enough to get your attachments and skip most other attachments. Other option is to look at filename. If you only need to move pdf, you can see if the attachment filename ends in pdf.

      check attachment names
      check attachment size example

      Reply
  31. steve tatum says

    August 19, 2013 at 6:31 am

    Thank you so much Diane! The changes you made work as expected...

    Reply
  32. steve tatum says

    August 8, 2013 at 6:32 am

    Hey Diane, have you had a chance to look at this yet?

    Reply
    • Diane Poremsky says

      August 8, 2013 at 9:29 pm

      I added a new version to page 3 - it will work on the selected folder.

      Reply
  33. steve says

    July 24, 2013 at 5:35 am

    Thanks Diane, sorry to bother you on your vacation. I did try the site you mentioned and found some code that will save outlook messages in a folder on the hard drive. This seems close to what I need but not quite. I only want to move the attachments of each message, not the entire message itself. Still, this may work with some tweaking. Maybe you could look at it to see what you think? I found it under "save all messages to hard drive using vba".

    Reply
    • Diane Poremsky says

      July 24, 2013 at 9:50 am

      I'll take a look at it and see what needs changed.

      Reply
  34. steve says

    July 19, 2013 at 9:15 am

    Hello, first off...love this code! Thanks for posting. My issue is probably a simple one but I am not familar with Outlook coding enough to figure it out. I would like to modify this line "Set objSelection = objOL.ActiveExplorer.Selection" of the code so that I do not actually have to select all of the messages in a folder. I would like for the code to select all of the messages in a folder that I have selected and then proceed with moving the attachments.

    Reply
    • Diane Poremsky says

      July 20, 2013 at 2:25 pm

      That's not hard to do - i might have a sample at slipstick.com that does that, if not I will update this code so it does. I'm on vacation right now, so give me a few days and don't hesitate to remind me if I don't post something early next week.

      Reply
  35. Deepak says

    June 23, 2013 at 5:19 am

    This is a brilliant script - I used it with Outlook 2013 - no issues

    Reply
  36. Safwat Ammar says

    May 13, 2013 at 2:32 am

    Thank you so much, it is very helpful

    Reply
  37. Johan AAnscharius says

    May 9, 2013 at 10:27 am

    Hi Kirk, Before deleting the attachment file, there should be the following check:

    Set FS = CreateObject("Scripting.FileSystemObject")
    if not FS.fileexists (strfile) then msgbox("OOps, could not save the file"): end

    That way you are sure the file is saved before deleting it.

    Reply
  38. Kirk says

    April 18, 2013 at 6:41 pm

    p.s. the brackets (greater-than, less-than) have been stripped from comment input form

    Reply
    • Diane Poremsky says

      April 18, 2013 at 11:28 pm

      That's a wordpress bug (wordpress says its a feature)- wordpress thinks the brackets are for html. Hopefully it will be easier to read as code - i had to comment mark the blank lines to make it work for the entire code. :(

      I did a quickie scan and don't see any obvious missing brackets. Let me know if they are any that need fixed.

      Reply
  39. Kirk says

    April 18, 2013 at 6:39 pm

    Well I used this code from page 3 along with code from http://social.msdn.microsoft.com/Forums/en-US/isvvba/thread/bbe6e55c-c52b-482b-8d99-14e080bbcdd5/ to save attachments I get and unzip them using an Outlook Rule trigger...


    Public Sub SaveAttachments()
    Dim objOL As Outlook.Application
    Dim pobjMsg As Outlook.MailItem 'Object
    Dim objSelection As Outlook.Selection
    '
    ' Get the path to your My Documents folder
    strFolderpath = CreateObject("WScript.Shell").SpecialFolders(16)
    On Error Resume Next
    '
    ' Instantiate an Outlook Application object.
    Set objOL = CreateObject("Outlook.Application")
    '
    ' Get the collection of selected objects.
    Set objSelection = objOL.ActiveExplorer.Selection
    '
    For Each pobjMsg In objSelection
    SaveAttachments_Parameter pobjMsg
    Next
    '
    ExitSub:
    '
    Set pobjMsg = Nothing
    Set objSelection = Nothing
    Set objOL = Nothing
    End Sub
    '
    Public Sub SaveAttachments_Parameter(objMsg As MailItem)
    Dim objAttachments As Outlook.Attachments
    Dim i As Long
    Dim lngCount As Long
    Dim strFile As String
    Dim strFolderpath As String
    Dim strDeletedFiles As String
    '
    Dim FSO As Object 'variables for unzipping
    Dim oApp As Object
    Dim strFileZ As Variant
    Dim StrFolderpathZ As Variant
    '
    ' Get the path to your My Documents folder
    strFolderpath = CreateObject("WScript.Shell").SpecialFolders(16)
    '
    On Error Resume Next
    '
    ' Set the Attachment folder.
    strFolderpath = strFolderpath & "pcap"
    StrFolderpathZ = strFolderpath 'pass it to unzip object variable
    '
    ' Get the Attachments collection of the item.
    Set objAttachments = objMsg.Attachments
    lngCount = objAttachments.Count
    '
    If lngCount > 0 Then
    '
    ' We need to use a count down loop for removing items
    ' from a collection. Otherwise, the loop counter gets
    ' confused and only every other item is removed.
    For i = lngCount To 1 Step -1
    '
    ' Save attachment before deleting from item.
    ' Get the file name.
    strFile = objAttachments.Item(i).FileName
    '
    ' Combine with the path to the Temp folder.
    strFile = strFolderpath & Format(objMsg.ReceivedTime, "yyyy-MM-dd h-mm-ss") & "." & strFile
    '
    ' Save the attachment as a file.
    objAttachments.Item(i).SaveAsFile strFile
    strFileZ = strFile 'pass it on to the unzip variable
    '
    ' Delete the attachment.
    ' objAttachments.Item(i).Delete
    '
    'write the save as path to a string to add to the message
    'check for html and use html tags in link
    If objMsg.BodyFormat olFormatHTML Then
    strDeletedFiles = strDeletedFiles & vbCrLf & "" & strFile & ""
    Else
    strDeletedFiles = strDeletedFiles & "" & "" & strFile & ""
    End If
    Next i
    End If
    '
    ' Adds the filename string to the message body and save it
    ' Check for HTML body
    If objMsg.BodyFormat olFormatHTML Then
    objMsg.Body = objMsg.Body & vbCrLf & _
    "The file(s) were saved to " & strDeletedFiles
    Else
    objMsg.HTMLBody = objMsg.HTMLBody & "" & _
    "The file(s) were saved to " & strDeletedFiles & ""
    End If
    '
    objMsg.Save
    '
    ' Unzip the attachment if it is compressed as zip file
    If (Right(strFile, 3) = "zip") Then
    Set oApp = CreateObject("Shell.Application")
    oApp.NameSpace(StrFolderpathZ).CopyHere oApp.NameSpace(strFileZ).Items
    On Error Resume Next
    Set FSO = CreateObject("scripting.filesystemobject")
    End If
    '
    ExitSub:
    '
    Set objAttachments = Nothing
    Set objMsg = Nothing
    Set objOL = Nothing
    End Sub

    Reply
  40. Ford says

    February 4, 2013 at 2:50 pm

    Thank you for the great and very useful example. With a little effort, it does a great job and has taught me a great deal about macros and VBA within Outlook.

    On the question (and suggestion) for skipping embedded images (as in company logos), I thought of a couple of other methods, but am not adept enough to make it work. Is there perhaps a way to examine a property of the attachment to determine it is embedded within the body?

    Another thought for me was to examine the attachment file size and skip it if it was less than,,, say, 15KB.

    And yet another thought was to check the file extension for being a .png or .jpg. I have seen these embedded logos with various names, so checking for a specific name as you suggested is not effective in all cases.

    Thank you again for the really great lessons.

    Reply
    • Diane Poremsky says

      February 4, 2013 at 6:25 pm

      Checking for the file extension is probably the best option. I didn't suggest it because if you get jpg or png you want saved, it won't work.

      Reply
  41. Andy says

    January 30, 2013 at 9:47 am

    also, how do I change the path so saves to eg "C:Attachments" (substituting that into the code doesnt seem to have worked)

    thanks

    Reply
    • Diane Poremsky says

      January 30, 2013 at 4:39 pm

      Where did you stick it in?

      This line uses one of the special windows folders (My Docs):
      strFolderpath = CreateObject("WScript.Shell").SpecialFolders(16)

      And this sets the subfolder.
      strFolderpath = strFolderpath & "OLAttachments"

      Remove the first strFolderpath line and replace with second with this and it should work.
      strFolderpath = "C:Attachments"

      Reply
  42. Andy says

    January 30, 2013 at 3:33 am

    Thanks Diane, I get an error when I add 'Set objSelection = objOL.ActiveExplorer.Selection ' into the code...where should this go?

    Reply
    • Diane Poremsky says

      January 30, 2013 at 4:43 pm

      It's already in the code - you don't need to add it. It's the 3rd line in the code.

      Reply
  43. Andy says

    January 29, 2013 at 9:58 am

    hello, thanks for the code...can this work on specific folders rather than all folders/inbox

    Reply
    • Diane Poremsky says

      January 29, 2013 at 2:06 pm

      Yes, This line: Set objSelection = objOL.ActiveExplorer.Selection tells it to work with the selected messages. They can be in any folder.

      Reply
  44. Anthony Shelton says

    January 11, 2013 at 1:13 pm

    I love this script, however I am running into one major issue.

    My companies signature uses .png and .jpeg images. These objects are recognized as "attachments" by this script, and are stripped and stored with the legitimate attachments.

    Is there any way I could alter this script to ignore these signature elements, and only apply to mail message attachments directly under the Sent: and To: columns?

    Reply
    • Diane Poremsky says

      January 11, 2013 at 6:02 pm

      You can't tell it to skip signatures - it doesn't identify an attachment as part of a signature.

      If the attachment name is always the same "company-logo.png" you can could use an If statement to skip them. If you want to skip all png or jpg attachments, you could do that too. '

      It would be something like this:

      strFile = objAttachments.Item(i).FileName

      If strfile <> "company-logo.png" then
      strFile = strFolderpath & strFile
      objAttachments.Item(i).SaveAsFile strFile
      else
      strfile = ""
      End if

      objAttachments.Item(i).Delete

      Reply
  45. asdfasdfasdf says

    October 17, 2012 at 10:57 am

    dont use this script as it will overwrite any attachments with the same name and then delete them making them unrecoverable. Very embarassing situation for me thanks to this.

    Reply
    • Diane Poremsky says

      October 17, 2012 at 11:27 am

      Did you read the note in the yellow block at the top? Augusto shared code with us that saves the items with a name format of SenderName.ReceivedDate.filename.ext to prevent this problem.

      Reply
  46. Aaron says

    September 13, 2012 at 8:28 am

    I can't win. Oh well... I'm building a file tag around strFile so Outlook will link it even in a text message.

    Reply
  47. Aaron says

    September 13, 2012 at 8:27 am

    Haha, even my explanation didn't work properly. To be clear it's:
    strDeletedFiles = strDeletedFiles & vbCrLf & "" & strFile & ""

    Reply
  48. Aaron says

    September 13, 2012 at 8:24 am

    Thank you for the code example! I think I've worked through the difficulties presented by the website here not displaying all of the actual code correctly and am down to one problem with building strDeletedFiles for non-HTML messages. For some reason it ignores vbCrLf and just smushes all my links together in a single line.

    This is what I have:
    strDeletedFiles = strDeletedFiles & vbCrLf & ""
    (not sure the end of this will display properly but basically I am adding on a

    I've tried vbNewLine as well, and have tried just inserting Chr(10) & Chr (13). Any ideas?

    Interestingly, when I build objMsg.Body and use vbCrLf it works fine

    Reply
  49. Jen says

    September 12, 2012 at 9:11 am

    Me again. It didn't paste the second line that is giving me an error:
    strFile & "'>" & strFile & ""

    Reply
  50. Jen says

    September 12, 2012 at 9:09 am

    Hello, all.
    I'm having trouble with the following two lines. VBA wants an expression, but in all of my searching, I have not found a fix. Any help is appreciated!

    strDeletedFiles = strDeletedFiles & "" & "" & strFile & ""

    Reply
    • Diane Poremsky says

      September 12, 2012 at 9:21 am

      Make sure the quotes are not "smart quotes" - it pasted fine for me just now so that should be ok for you.

      Backspace that line to make one line with the previous line - so instead of
      [stuff] & _
      strFile [stuff]

      it will be [stuff] & strFile [stuff]

      Reply
  51. Pedro M. Lledó says

    May 11, 2012 at 8:21 am

    Hi all,
    I'm trying to modify Augusto's script in order to be able to select a folder to save the attachments, instead of saving it to the My DocumentsOLAttachments.
    I'm trying the FolderBrowserDialog object, but I got an error about user-defined type not defined, when compiling the visualbasic code. I'm trying to link the right Library in Tools-->References, but no success.

    I'm using Outlook 2007 on Win7
    What I'm missing?

    Please advice and thanks a lot for your help in advance.
    Kindest,
    Pedro

    Reply
    • Diane Poremsky says

      May 11, 2012 at 1:13 pm

      Which library are you referencing?

      Reply
  52. Diane Poremsky says

    May 9, 2012 at 11:44 am

    @nick what happens when you try? Because the code adds file names to strFolderpath, it might work better to make a new string variable that is used only for the folder path:

    dim strFolderOnlypath as string
    strFolderOnlypath = strFolderpath & "OLAttachments"

    If objMsg.BodyFormat <> olFormatHTML Then
    objMsg.Body = objMsg.Body & vbCrLf & _
    "The file(s) were saved to " & strFolderOnlypath
    Else
    objMsg.HTMLBody = objMsg.HTMLBody & "

    " & _
    "The file(s) were saved to " & strFolderOnlypath & "

    "
    End If

    Reply
  53. Nick says

    May 9, 2012 at 9:09 am

    This macro is great! It is a feature that should be built-in! Especially useful for those of us who have limits on mailbag size.

    I'd like to add a link to the OLAttachments folder in the message.
    I can make it work with Rich Text but not with HTML messages.

    I just replace the "strDeletedFiles" with "strFolderpath" but it doesn't work.

    Reply
  54. Ray says

    April 8, 2012 at 12:52 pm

    Forgot to include that i use Outlook 2003 on Win XP.

    Reply
  55. Ray says

    April 8, 2012 at 12:24 pm

    Hello,
    I receive emails that contain .pdf, .txt., .doc and other types of attachments. I would be very grateful if someone could show me how to modify the above code so that I can remove and save all attachments but leave any pdf files in the emails if they exist.

    Reply
  56. Nick says

    February 16, 2012 at 3:59 pm

    Hi - thanks for all the work on this, it's just great. However, I would prefer to replace the attachments with a text file indicating the location of the saved attachments, rather than adding text to the end of the message body. Does anyone know how to do this?

    Reply
  57. Nick says

    February 16, 2012 at 1:25 pm

    Hello again - figured that out by reviewing other code online - seems it just needed a not equals sign, to read “If objMsg.BodyFormat olFormatHTML Then”. I wonder why it works without for some people.

    Reply
  58. Nick says

    February 16, 2012 at 8:18 am

    Hi, this looks great - thanks. Unfortunately, I get a Compile error: Syntax error when I try to run it. The code breaks at "If objMsg.BodyFormat olFormatHTML Then" - it seems to want a Then or GoTo immedaiately after "If objMsg.BodyFormat". Any thoughts?

    As a possible enhancement, would it be straightforward to remove the attachments and instead of adding text to the email, replace the attachments with a text file listing the attachments and their new locations or even a file with active links to the removed files?

    Reply
  59. Tony says

    February 13, 2012 at 7:29 am

    Thanks for the interesting information. However, I was wondering if anyone knows how to alter the Attachment Drag & Drop functionality with resepct to copying an attached file from Outlook to a Windows Explorer folder.

    When I drag an attachment to an Explorer folder, the date modified date/timestamp becomes "now" (current time), not the original attachement's date modified. Is there a way to preserve the original timestamp when dragging attachements out of Outlook?

    Thanks in advance.

    Reply
    • Diane Poremsky says

      February 13, 2012 at 8:15 am

      To the best of my knowledge, no you can't change the behavior. It's always been a bit goofy, with the Window Explorer date taking Outlook's time stamps if the message was received within a certain time period (approx 2 weeks prior). Augusto's code sample will add the received to the filename field - not quite the same, but it can help. I'll see if i can put together some VBA that will set the Windows time stamp using the received time.

      Reply
  60. Augusto Papagno says

    January 26, 2012 at 11:09 am

    Hello:
    I did some modifications on Frank's code, in order to avoid file overwritting when the attachment name is the same as an existing one (i.e. details.txt on a return receipt email). Now, the attachemnts are saved in the format "SenderName.ReceivedDate.filename.ext" and then the attachment is deleted from the orinal email.

    Here is the code:

    Public Sub SaveAttachments()
    Dim objOL As Outlook.Application
    Dim pobjMsg As Outlook.MailItem 'Object
    Dim objSelection As Outlook.Selection

    ' Get the path to your My Documents folder
    strFolderpath = CreateObject("WScript.Shell").SpecialFolders(16)
    On Error Resume Next

    ' Instantiate an Outlook Application object.
    Set objOL = CreateObject("Outlook.Application")

    ' Get the collection of selected objects.
    Set objSelection = objOL.ActiveExplorer.Selection

    For Each pobjMsg In objSelection
    SaveAttachments_Parameter pobjMsg
    Next

    ExitSub:

    Set pobjMsg = Nothing
    Set objSelection = Nothing
    Set objOL = Nothing
    End Sub

    Public Sub SaveAttachments_Parameter(objMsg As MailItem)
    Dim objAttachments As Outlook.Attachments
    Dim i As Long
    Dim lngCount As Long
    Dim strFile As String
    Dim strFolderpath As String
    Dim strDeletedFiles As String

    ' Get the path to your My Documents folder
    strFolderpath = CreateObject("WScript.Shell").SpecialFolders(16)
    On Error Resume Next

    ' Set the Attachment folder.
    strFolderpath = strFolderpath & "OLAttachments"

    ' Get the Attachments collection of the item.
    Set objAttachments = objMsg.Attachments
    lngCount = objAttachments.Count

    If lngCount > 0 Then

    ' We need to use a count down loop for removing items
    ' from a collection. Otherwise, the loop counter gets
    ' confused and only every other item is removed.
    For i = lngCount To 1 Step -1

    ' Save attachment before deleting from item.
    ' Get the file name.
    strFile = objAttachments.Item(i).FileName

    ' Combine with the path to the Temp folder.
    strFile = strFolderpath & objMsg.SenderName & "." & Format(objMsg.ReceivedTime, "yyyy-MM-dd h-mm-ss") & "." & strFile

    ' Save the attachment as a file.
    objAttachments.Item(i).SaveAsFile strFile

    ' Delete the attachment.
    objAttachments.Item(i).Delete

    'write the save as path to a string to add to the message
    'check for html and use html tags in link
    If objMsg.BodyFormat olFormatHTML Then
    strDeletedFiles = strDeletedFiles & vbCrLf & ""
    Else
    strDeletedFiles = strDeletedFiles & "" & "" & strFile & ""
    End If
    Next i
    End If

    ' Adds the filename string to the message body and save it
    ' Check for HTML body
    If objMsg.BodyFormat olFormatHTML Then
    objMsg.Body = objMsg.Body & vbCrLf & _
    "The file(s) were saved to " & strDeletedFiles
    Else
    objMsg.HTMLBody = objMsg.HTMLBody & "" & _
    "The file(s) were saved to " & strDeletedFiles & ""
    End If
    objMsg.Save
    ExitSub:

    Set objAttachments = Nothing
    Set objMsg = Nothing
    Set objOL = Nothing
    End Sub

    Reply
  61. Chris says

    January 19, 2012 at 9:17 am

    I wanted to add to my above question # 2 that I used Frank's modified code that is supposed to break it into a single call for each mail item so you can use it with a rule to filter incoming mail but still did not understand how to get the rules to work with that code modification.

    Reply
  62. Chris says

    January 19, 2012 at 9:13 am

    I have two questions:

    Question 1 -
    This code worked great, How would I modify this code so that it would save the email message to disk in an outlook message file format. The email messages that I am wanting to process do not have attachments and would like to know how to modify this code to save it to disk. Now I have to manually do a "File Save AS" and know I can get VB to do it for me automatically.

    This code worked so well for attachments that I know it would work good for just saving the msg to file.

    Question 2 -
    I am trying to make a "rule" in my outlook to process incoming emails with a certain subject line and then call the SaveAttachments VB code to run. I cant find a way to call this vb code macro. I can run the macro manually on an email message and it works just fine but can't see how to have a rule call this macro and run it automatically.

    Reply
  63. rakesh seebaruth says

    November 26, 2011 at 1:37 am

    Hi ,

    i have a master copy file named(master copy.xls).whatever name is given in cell "e5" is saved as by that name.(e.g if cell e5 is tom) then the file will be saved as tom.xls. My master copy file will remained unchanged. My problem is that when i attached the tom.xls file thru outlook .the latter does not send the file tom.xls but it send the master copy.xls file .Plz help My VBA Codes are below

    Sub save()
    mydrive = "C:"
    mydir = "excel"
    myname = Sheets("sheet1").Range("e5")
    Application.DisplayAlerts = False
    ThisWorkbook.saveas Filename:=mydrive & "" & mydir & "" & myname & ".xls"
    Application.DisplayAlerts = True
    End Sub

    Sub Mail_Workbook_1()
    Dim OutApp As Object
    Dim OutMail As Object

    Set OutApp = CreateObject("Outlook.Application")
    Set OutMail = OutApp.CreateItem(0)

    On Error Resume Next
    With OutMail
    .To = " aa@yahoo.com"
    .CC = ""
    .BCC = ""
    .Subject = Range("e5")
    .Attachments.Add ActiveWorkbook.FullName
    .Send
    End With
    On Error GoTo 0

    Set OutMail = Nothing
    Set OutApp = Nothing
    End Sub
    rakesh seebaruth is offline Reply With Quote

    Reply
  64. John Fitzgerald says

    November 4, 2011 at 10:52 am

    Awesome! Thanks. Anyone know how to keep the paperclip icon?

    Also, I had to comment out the last End If for some reason.

    Reply
    • Diane Poremsky says

      November 5, 2011 at 8:44 pm

      You can't keep the paperclip unless there is an attachment - you can remove the line from the code that deletes the attachment or rework it to add a small attachment to the message.

      Reply
  65. Rob says

    November 3, 2011 at 12:46 pm

    Wow this is great, thanks! Clear, well commented and well thought out. You're very good

    Reply
  66. Christopher W. Brown says

    October 31, 2011 at 9:48 am

    Thanks for the code. I tried using it a few months ago but got syntax error messages. Not a VBS guy and this is the first time I've attempted programming outlook so I put it off. I revisited it today when I had some time. Anyway, I am using Outlook 2007 on Windows 7 Pro and I had to replace all of the '&' with just the '&' and the '>' and '<' with actual > and < signs. Now it works as advertised.

    The msg box didn't really look correct either. It was displaying the html text in the box. But I was able to know what it was telling me and now I've debugged and deleted the MsgBox stuff so I'm good. Thanks again for the code. Just wanted to inform those who may get the syntax error using the '&' type commands.

    (Also had to Ctrl-V to paste code not Ctrl-P.)

    Reply
    • Diane Poremsky says

      October 31, 2011 at 10:33 am

      Thanks for bringing the problems to my attention. I'll fix the code... again. (Code samples are the one big failing with WordPress.)

      Reply
  67. Nick says

    October 26, 2011 at 4:06 pm

    Hi, thanks for publishing this. It would really help if the macro were able to create a subfolder for each email's attachments, labelled with the Subject of the email (truncated and cleaned of unusable characters if needed) with a _YYYY MM DD_hh mm ss suffix for date and time received. Does anyone know how to add this easily?

    Thanks again.

    Reply
  68. Frank Bello says

    October 5, 2011 at 12:29 pm

    Thanks so much for compiling this code. Quite of some help!
    I modified the structure to break the code into a single call for each mail item. THis way, the code can be used for all items selected, but at the same time a RULE can invoke the code also when incoming mail hits the box. here's the modification.

    [admin note: click the link to view Frank's code or open the text file linked near the top of this page.]

    [code lang="vb" collapse="1"]
    Public Sub SaveAttachments()
    Dim objOL As Outlook.Application
    Dim pobjMsg As Outlook.MailItem 'Object
    Dim objSelection As Outlook.Selection

    ' Get the path to your My Documents folder
    strFolderpath = CreateObject(&quot;WScript.Shell&quot;).SpecialFolders(16)
    On Error Resume Next

    ' Instantiate an Outlook Application object.
    Set objOL = CreateObject(&quot;Outlook.Application&quot;)

    ' Get the collection of selected objects.
    Set objSelection = objOL.ActiveExplorer.Selection

    For Each pobjMsg In objSelection
    SaveAttachments_Parameter pobjMsg
    Next

    ExitSub:

    Set pobjMsg = Nothing
    Set objSelection = Nothing
    Set objOL = Nothing
    End Sub

    Public Sub SaveAttachments_Parameter(objMsg As MailItem)
    Dim objAttachments As Outlook.Attachments
    Dim i As Long
    Dim lngCount As Long
    Dim strFile As String
    Dim strFolderpath As String
    Dim strDeletedFiles As String

    ' Get the path to your My Documents folder
    strFolderpath = CreateObject(&quot;WScript.Shell&quot;).SpecialFolders(16)
    On Error Resume Next

    ' Set the Attachment folder.
    strFolderpath = strFolderpath &amp; &quot;OLAttachments&quot;

    ' Get the Attachments collection of the item.
    Set objAttachments = objMsg.Attachments
    lngCount = objAttachments.Count

    If lngCount &gt; 0 Then

    ' We need to use a count down loop for removing items
    ' from a collection. Otherwise, the loop counter gets
    ' confused and only every other item is removed.
    For i = lngCount To 1 Step -1

    ' Save attachment before deleting from item.
    ' Get the file name.
    strFile = objAttachments.Item(i).FileName

    ' Combine with the path to the Temp folder.
    strFile = strFolderpath &amp; strFile

    ' Save the attachment as a file.
    objAttachments.Item(i).SaveAsFile strFile

    ' Delete the attachment.
    'objAttachments.Item(i).Delete

    'write the save as path to a string to add to the message
    'check for html and use html tags in link
    If objMsg.BodyFormat olFormatHTML Then
    strDeletedFiles = strDeletedFiles &amp; vbCrLf &amp; &quot;&quot;
    Else
    strDeletedFiles = strDeletedFiles &amp; &quot;&quot; &amp; &quot;&lt;a href='//&quot; &amp; _
    strFile &amp; &quot;'&gt;&quot; &amp; strFile &amp; &quot;&lt;/a&gt;&quot;
    End If
    Next i
    End If

    ' Adds the filename string to the message body and save it [COMMENTED AS THIS FUNCTION WAS NOT DESIRED]
    ' Check for HTML body
    ' If objMsg.BodyFormat olFormatHTML Then
    ' objMsg.Body = objMsg.Body &amp; vbCrLf &amp; _
    ' &quot;The file(s) were saved to &quot; &amp; strDeletedFiles
    ' Else
    ' objMsg.HTMLBody = objMsg.HTMLBody &amp; &quot;&quot; &amp; _
    ' &quot;The file(s) were saved to &quot; &amp; strDeletedFiles &amp; &quot;&quot;
    ' End If
    objMsg.Save
    ExitSub:

    Set objAttachments = Nothing
    Set objMsg = Nothing
    Set objOL = Nothing
    End Sub
    [/code]

    Reply
  69. kavsoo says

    October 5, 2011 at 8:28 am

    This code works only when the outlook is opened by the user, is there a way to make it work automatically (assuming the inbox never gets opened, and all the attachments coming to this inbox should get stored in a folder). Appreciate inputs.

    Reply
    • Diane Poremsky says

      October 5, 2011 at 9:30 am

      The only way to run code on a mailbox that is never opened, is to do it on the server. Outlook (or any mail client) needs to check for new mail and download it before it can process it.

      Is this an exchange mailbox? If so, a server-side event sink or, if you open the mailbox as a secondary mailbox, tweaking the macro should work.

      Reply
      • kavsoo says

        October 21, 2011 at 8:27 am

        Thank you Diane for your response;

        Here's my situation, this is an exchange mailbox. I'm afraid that the IT admin will allow me to set up a server-side event for a small task, so this is out of the question.

        So can you explain more about "opening the mailbox as secondary and tweaking the macro"?

        thanks again

      • James says

        November 23, 2011 at 2:46 am

        I have the same situation. Have you found a solution yet?

  70. Darryl Gittins says

    September 21, 2011 at 7:27 am

    Lookks nice but the script fails for me with a run-time error'9', subscript out of range:

    strFolderpath = CreateObject("WScript.Shell").SpecialFolders(16)

    Reply
    • Diane Poremsky says

      September 21, 2011 at 8:03 am

      I can't repro that error - I thought maybe it was because you didn't create the olattachments folder under My Documents - but the code runs error free, it just doesn't actually save the attachments. (I am getting a block-end if error, not sure why since no one else complained.)

      What version of Windows? Is Windows Scripting installed/enabled?

      Reply
  71. Mohan says

    September 14, 2011 at 7:03 am

    I would like to keep attachment file names in the email message whenever I remove/delete attachments from the email. This feature was there in Lotus Notes. How to get this feature in Outlook?

    Thanks
    Mohan

    Reply
    • Diane Poremsky says

      September 15, 2011 at 9:40 am

      You need to use an addin or VBA - the code on this page does it with this line: strDeletedFiles = strDeletedFiles & "" & "" & strFile & ""
      if you want just the file name and not the save path, you can edit the code to remove the parts that remember the path.
      See https://www.slipstick.com/addins/attachment-management-tools-for-outlook/ for addins that will do this for you.

      Reply
  72. JonasL says

    August 5, 2011 at 2:57 am

    Great script, however when I mark several messages the text in each e-mail that tells you were the files were saved contains ALL files that were saved and removed, i.e. not only the attachements that were removed from that specific e-mail. Anyone else that experience this problem? Suggestions for fixing it?

    Thanks!

    Reply
    • Diane Poremsky says

      August 5, 2011 at 4:44 am

      It's been a long time since I wrote the code, but I think its meant for single message use. For multiple messages you need to do a loop and clear the values before moving to the next message.

      With just looking at it here quickly, so I could be wrong, it might work to reset the strAttachments value or objAttachments before looping.

      Reply
      • JonasL says

        August 5, 2011 at 5:51 am

        Perfect, I just resetted the strDeletedFiles after each loop and now it works like a charm.

        Thanks!

      • Diane Poremsky says

        August 5, 2011 at 5:53 am

        Cool. Thanks for sharing.

  73. Diane says

    July 8, 2011 at 7:19 am

    Security prompts or the message boxes telling you want is happening?

    The lines of code beginning with MsgBox can be deleted - they are just there so you can see what is happening. They can be very useful for troubleshooting.

    Either delete or add a ' in front of each msgbox to disable it - like this:

    ' MsgBox strDeletedFiles

    Reply
  74. JRM says

    July 8, 2011 at 7:04 am

    Any chance the code can run without prompts of any kind?

    Reply
  75. outlooktips says

    June 24, 2011 at 1:51 pm

    Alt+F11 works with Outlook 2010 - why it didn't for you is a mystery. (Sometimes other apps interfere and hijack the shortcuts.)

    Reply
  76. Josh says

    June 24, 2011 at 5:41 am

    Brilliant code!!! Exactly what I was looking for. And thanks for the super easy instructions to follow. The only difference I found was that in Outlook 2010 Alt+F11 didn't work, so I just had to turn the developer toolbar on.

    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 7

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
  • Use Classic Outlook, not New Outlook
  • How to Remove the Primary Account from Outlook
  • Reset the New Outlook Profile
  • How to Hide or Delete Outlook's Default Folders
  • Disable "Always ask before opening" Dialog
  • Change Outlook's Programmatic Access Options
  • Removing Suggested Accounts in New Outlook
  • Understanding Outlook's Calendar patchwork colors
  • This operation has been cancelled due to restrictions
  • Shared Mailboxes and the Default 'Send From' Account
  • Sync Issues and Errors with Gmail and Yahoo accounts
  • 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
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

Sync Issues and Errors with Gmail and Yahoo accounts

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

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.