A visitor wanted to know how to save attachments and then open them without opening Windows Explorer to find the attachment. This VBA code is based on the code sample at our Outlook-Tips site: Save and Delete Attachments. We removed the lines that delete the attachment from the message and added the file path to the message body, using the file path to open the message using Window's ShellExecute command.
The macro at Save Attachments to the hard drive is the original macro this code was built from. It saves attachments on the selected messages but does not open them.
Save and Open Attachments VBA Sample
To use this code sample, open the VBA editor by pressing Alt+F11 keys. Paste the code into the ThisOutlookSession module. If it does not exist, create the directory path on your hard drive then update the code with the path.
Select one or more attachments and run the macro.
For more information, see How to use VBA Editor
Private Declare Function ShellExecute Lib "shell32.dll" Alias _
"ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, _
ByVal lpFile As String, ByVal lpParameters As String, _
ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Public Sub SaveandOpenAttachments()
Dim objOL As Outlook.Application
Dim objMsg As Outlook.MailItem
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 strExePath As String
' Get the path to your My Documents folder
strFolderpath = CreateObject("WScript.Shell").SpecialFolders(16)
On Error Resume Next
Set objOL = CreateObject("Outlook.Application")
Set objSelection = objOL.ActiveExplorer.Selection
' Set the Attachment folder. (Folder must exist.)
strFolderpath = strFolderpath & "\OLAttachments\"
For Each objMsg In objSelection
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
'use ShellExecute to open the file
'this may not work with zip extension if you use Compressed folders
ShellExecute 0, "open", strFile, vbNullString, vbNullString, 0
Next
End If
Next
ExitSub:
Set objAttachments = Nothing
Set objMsg = Nothing
Set objSelection = Nothing
Set objOL = Nothing
End Sub
Use with 64-bit Outlook
To use this with 64-bit Outlook, replace the Declare line with this:
Private Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias _ "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, _ ByVal lpFile As String, ByVal lpParameters As String, _ ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Open hidden attachments on Outlook.com items
To use this to open hidden attachments on Outlook.com items, change the objMsg line to this:
Dim objMsg as Object
Use the Temp folder instead of My Documents, delete
strFolderpath = CreateObject("WScript.Shell").SpecialFolders(16)
and replace
strFolderpath = strFolderpath & "\OLAttachments\" with this:
strFolderpath = VBA.Environ$("Tmp") & "\"
Open ICS attachments and save to Calendar
This version of the macro is a run a script macro. It saves the attachment to the hard drive, open it (hidden), then saves it to the calendar and deletes it from the hard drive.
Public Sub SaveandOpenAttachments(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 oAppt As Object
' Get the path to your My Documents folder
strFolderpath = CreateObject("WScript.Shell").SpecialFolders(16)
On Error Resume Next
' Set the Attachment folder. (Folder must exist.)
strFolderpath = strFolderpath & "\Att temp\"
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
Debug.Print strFile
objAttachments.item(i).SaveAsFile strFile
Set oAppt = Session.OpenSharedItem(strFile)
oAppt.Close olSave
' should delete strfile too
SetAttr strFile, vbNormal
Kill strFile
Next
End If
ExitSub:
Set objAttachments = Nothing
End Sub
To test the run a script macro without sending yourself messages, use this stub macro. Select a message then run the macro. It calls the run a script macro, just as a rule would. You can also use this macro to run the script "manually".
Sub RunScript() Dim objApp As Outlook.Application Dim objItem As mailitem Set objApp = Application Set objItem = objApp.ActiveExplorer.Selection.item(1) 'macro name you want to run goes here SaveandOpenAttachments objItem End Sub
How to use the Macro
First: You will need macro security set to low during testing.
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, it’s at Tools, Macro Security. If Outlook tells you it needs to be restarted, close and reopen Outlook. Note: after you test the macro and see that it works, you can either leave macro security set to low or sign the macro.
Now open the VBA Editor by pressing Alt+F11 on your keyboard.
To put the code in a module:
- Right click on Project1 and choose Insert > Module
- Copy and paste the macro into the new module.
More information as well as screenshots are at How to use the VBA Editor.
More Information
To save and open specific attachment types (for example, only open doc and xls files) as the messages arrive, see Attachment: Print received attachments immediately. Change "print" to "open" in the ShellExecute line of that code:
ShellExecute 0, "print", sFile, vbNullString, vbNullString, 0
to
ShellExecute 0, "open", sFile, vbNullString, vbNullString, 0
Davinder Singh says
Thanks Diane. Can you please give some advise on how to automatically open a pdf attachment when it arrives from a specific sender? The pdf has a password (which is always the same and I can hard code that in the script). Thanks
Leonardo Buitrago says
Thanks Diane, please can you give me some advice, how can I modify the SaveandOpenAttachments() macro in order to work with the ActiveInspector Method?. I want to work with an Outlook item that is open an has focus. I read this https://www.slipstick.com/developer/outlook-vba-work-with-open-item-or-select-item/...but i´m so confused..help please.
Jaime Alegria says
Thanks a lot for sharing the code, It is amazing. I was able to use it and it is really fantastic!
Badan says
Hi Diane and thank you for this excellent work! I have a problem opening accented characters of txt files in Excel. I think the issue is that the file is saved with utf-8 encoding. Is there a function in vba that upon saving of the txt file also changes its encoding to ansi or unicode? Thank you very much in advance!
David says
Not to worry, it worked perfectly. I guess the ActiveExplorer object saved the day.
David says
You are awesome, Diane. Thanks for this solution.
(Save Attachments with VBA)
My first implementation is a macro in OL launched using Developer.
Next, will be a macro in XL
Since my Spreadsheet has all the brains;
I'm worried since I'll have to CreateObject from XL, it won't know which item is selected.
Anyway, I'm on my way.
Hope you are well
Erik says
Hello and thanks for the code.
Is it possible to save the edited file back to the mail programmatically?
I want to do the following:
select a task -> open the linked .msg-file -> make mail editable -> open the attached word-file -> ! from here on manually ! -> edit the doc -> save back to mail (on closing/automatically)
With your solution i'm able to open the word file, but if i close the file it won't save back to the mail automatically.
(It does, if i open it manually. So i guess Outlook itself opens it another way and i'd like to use this way..)
Do you have a hint for me?
Tony says
Very Nice!
I'm interested in saving an attachment based on the name in the subject line.
Do you have any links that I could use to find a method I could use?
Diane Poremsky says
You'd use objMsg.Subject in the string that creates the file name.
noi says
Hello,
it is not possible to save the attachments from selected RSS Feed objects.
Would it be possible?
greetings
noi
RB says
doesnt' work. runs but files don't show up in folder. nice idea anyway.
Diane Poremsky says
What version of Outlook?
add msgbox strFolderpath and msgbox strFile to the code, just after each string is created. This will help you see if the path is correct.
Jimi says
I'm the one asking about such a feature, and it's really great of you to help out like this. Although I'm not sure how often I will use this macro, because of two things:
1. I really would want a "Save as" dialog, where I can choose the directory and file name, and get a warning if the file already exists.
2. I would like to have this option available in the right click context menu, as "Save as and open..." or something like that.
But I guess I can't have everything. Just to bad that the Microsoft team didn't think about this feature. The web client (ie Outlook Web Access) has this feature (after the save as dialog, I get the option to open the file), so I find it strange that the standalone client doesn't.
Diane Poremsky says
It was more to show visitors what can be done, plus it was a fairly easy change to make and I expect users will eventually post useful variations of it.
#1 is doable, #2 is less doable - I'll have to double check, but i think it needs to be a com addin to add a context menu. I would add it as a ribbon/quick access toolbar, or toolbar button so it's handy and you can use a keyboard shortcut to run it.