Update: Feb. 28, 2007: Due to numerous requests I’ve created a branch of this macro that saves attachments for all messages / calendar items, selected or not. To see it, please see my post http://arcanecode.wordpress.com/2007/02/28/saving-all-attachments-in-outlook/ or http://shrinkster.com/mhn. There I have uploaded a new file with both the macro below and the new one that saves all items, selected or not.
Yesterday I blogged about a macro I wrote for my wife to allow her to save attachments for multiple messages in Outlook. After using it today she asked for a few enhancements. First, she wanted to be able to select the directory to save the attachments to. Second, she wanted the macro to detect that a file already existed, and allow her to rename the new file or skip it.
To accomplish the first item, I found a handy routine in a google groups thread. I’ll let you read it for yourself, the code is about half way down in a message by Joe Earnest, and can be found at http://shrinkster.com/l0v. I took Joe’s code and created a function out of it called GetOutputDirectory. I made one enhancement, at the end I make sure the output directory ends in a backslash.
For the second enhancement I used the good old scripting runtime library. Use the Tools, References menu in the VBScript editor and set a reference to the “Microsoft Scripting Runtime”, scrrun.dll. Rather than reposting all the code I’ve put the entire macro in a txt file you can download here: http://arcanecode.files.wordpress.com/2007/01/saveattachments2.txt
Here is the heart of the code
fileExists = fso.fileExists(outputDir + outputFile)
Do While fileExists = True
outputFile = InputBox(“The file ” + outputFile _
+ ” already exists in the destination directory of ” _
+ outputDir + “. Please enter a new name, or hit cancel to skip this one file.”, “File Exists”, outputFile)
‘If user hit cancel
If outputFile = “” Then
‘Exit leaving fileexists true. That will be a flag not to write the file
Exit Do
End If
fileExists = fso.fileExists(outputDir + outputFile)
Loop
‘Save it to disk
If fileExists = False Then
att.SaveAsFile (outputDir + outputFile)
AttTotal = AttTotal + 1
End If
As you can see, I check to see if the file exists and store that in a variable. I then enter a loop if the file exists, ask for a new name, then check to see if the new name exists. I stay in the loop as long as it does.
Should the user click the cancel button on the input box, I exit the loop prematurely and use the fileexists as a flag to write or not write the file.
There you go, an enhanced version of the SaveAttachments macro. Take a look at the full file I’ve uploaded, and leave a comment with any questions.


January 9, 2007 at 7:48 am
Wonderful script! One question though, I am attempting to use this to clear the attachments from my calendar. It seems to only work on the days I highlight. Is there a way to get it to remove all attachments in the calendar just by selecting the calendar in the folder view? Again, it seems I have to select each day individually.
January 10, 2007 at 10:45 pm
Instead of cycling through the collection of selected items (the for cnt = 1 to Sel.Count area) you’ll want to cycle through the calendar folder. I’ll have to dig a bit to get the exact code, meanwhile you could always just do a Ctrl+A (Edit, Select All on the menu) to select all the items then run the script.
I wrote the macro as a Christmas present to my wife, who wanted to save only messages she had selected, hence the way it was written.
January 14, 2007 at 8:04 pm
Thank you for your time with this, I really appreciate it.
Unfortunatelly, CTRL+A doesnt work in the calendar. (I actually tried all variations prior to bugging you!)
Dont kill yourself, but if you could come up with something it would be wonderful.
Thanks Again!
February 21, 2007 at 12:00 pm
Just wanted to thank you for an extremely useful piece of code. I get dozens of attachments from many of my writers every day, and having to save each message’s attachments individually has been time-consuming. One program I found did work well, but of course, was not free. Your macro works great. Thanks!
Julie
February 28, 2007 at 9:04 pm
[...] Posted by arcanecode in Outlook, VBScript, Development. trackback Back on January 3’rd, 2007 (http://arcanecode.wordpress.com/2007/01/03/enhancing-the-save-attachments-outlook-macro/ or http://shrinkster.com/mhm) I posted a useful macro that would save attachments on the selected [...]
May 18, 2007 at 4:12 am
This is a brilliant bit of code. so useful i get loads of attachments which i want to save.
I have messsages with attachments which have been forwarded, some times the file i want is 4 or more messages in. it saves the .msg file and not the jpg file i want. if there anyway aound this ?
June 7, 2007 at 1:52 am
Hi There
Thanks for the brilliant piece of code!.
I have however one question as I would like to save the attachments to a network share, but if I change the destination folder to \\server\sharename then it says unable to save attachments even though everyone can save to the folder. Any ideas please?
September 29, 2007 at 11:35 pm
Great bit of code – thanks!
Just a thought – I edited it to prefix the attachment with the subject of the email so that attachments will get similar names. I also had to filter out invalid characters.
November 27, 2007 at 4:28 pm
Helpful site – thanks.
I don’t supposed there’s a way to append the attachment to the existing file? after you checked if file already exists.
Any suggestion would be greatly appreciated.
January 25, 2008 at 4:46 am
Just the code I have been looking for – thanks!
Unfortunately, I get an error when running the macro: “Compile error: User-defined type not defined” when the code reaches “Dim fso As FileSystemObject”
Any idea why?
Thanks in advance!
February 21, 2008 at 10:35 am
@ Kenneth:
In the VB editor in Outlook, under the ‘extra’ menu, there should be something like a ‘references’ option.
Scroll through the list until you find “Microsoft Scripting Runtime”.
December 28, 2009 at 9:43 pm
In Office 07 (Professional?) the ‘References…’ otion is in the ‘Tools’ menu, for those who can’t find the ‘extra’ menu.
Great Code!
May 4, 2008 at 7:49 am
From a salesguy with no coding experience. Can some one please post step by step Install or Implementation instructions? Thanks for your help this looks like what I need. I have 400+ emails with .jpg atttachments that I need to extract and post on my website. Any reco’s are appreciated.
Thanks!
May 7, 2008 at 7:28 am
Very nice script! Thanks for making it available
Sam, to install this macro open Outlook, click Tools – Macro – Visual Basic Editor. From there, click Insert New Module. Copy and Paste the script into the blank module that opens. Then click Tools – References and choose Microsoft Windows Scripting. Finally, click save.
To run it click Tools – Macro – Macros, or hit Alt-F8 to bring up the macros window.
May 23, 2008 at 2:04 am
If i can get this to work it will save me about an hour every day, but I get the
“Compile error: User-defined type not defined” when the code reaches “Dim fso As FileSystemObject” problem.
When i go to the references menu on the vb editor there isn’t a microsoft scripting runtime or a microsoft windows scripting option.
I’m using outlook 2003 with no disabled items.
May 23, 2008 at 5:51 am
Simon: Check the paragraph right before the code. You will need to set a reference to the scripting runtime library, which is likely why you are getting the error.
May 25, 2008 at 5:34 pm
Thanks for sharing!
One question: I would like to use the macro to detach the images my webcam sends to my email adress every 10 minutes. The webcam always uses the same file name, and I would like to use the date/time of the image as (part of) the new file name.
Is there any way I can get hold of those properties of the attached image file? Or any other way that would make the images distinguishable?
Suggestions greatly appreciated!
June 11, 2008 at 12:31 am
Cheers for the great script.
WOuld like to know how to change the email folder if you don’t want the Inbox as the default folder to get the attachments from eg i have a rule to place orders from the inbox into the orders folder in outlook. Tried and failed to get it to work.
August 4, 2008 at 1:07 pm
Like to know the coding for if we forgot to Mention Cc some one? Please advise or mail me to sandeep_goyal01@infosys.com
September 2, 2008 at 5:08 am
Thank you for the script, it was exactly what I needed.
September 26, 2008 at 12:50 pm
Thanks to you and your dad (for buying the TRS-80).
Code worked for me on the first try. You rock!
November 18, 2008 at 5:41 am
Thanks a million, have been looking for this for days!
January 12, 2009 at 2:08 pm
Wonderful macro; extremely helpful. I’m not a VBA coder, but I would like to save my attachments with the date/time stamp of the message. For example, if the message containing the attachments was received on 01/12/2009 at 10:00 am, I would like each attachment’s filename to appear as follows: FILENAME_20080112.1000.EXT.
Would you be able to help me with the necessary code to implement this change to the macro? Thanks very much.
June 22, 2009 at 8:09 am
BTD,
Did you get a response or figure out how to incorporate the date/time stamp when saving the attachments? I am in need of the same modification as I receive system generated reports only distinguished by the time stamp.
GIB
January 20, 2009 at 7:24 am
I love the code. I wrote something similar. What I am trying to get mine to do is print the attachments (I’d like it to convert all files to .pdf, and the only way I know how is to print them using a convert to .pdf printer).
Do you know how to tell VB to open, print, and close any file in that order?
January 20, 2009 at 7:25 am
Oh, almost forgot…
Thanks!
February 8, 2009 at 7:27 am
Hello,
I need help if anyone knows how to accomplish this. I receive an email which contains two attachments. Each attachment has the name of a city in it (88552_virginia.pdf) and (77558_calhoun.pdf). I need to rename & save each of the attachments into their own folder. Some how the script would need look for the name in the attachment then save to a folder based on the name of the attachment. I need to rename each file as ad.pdf and place them in two separate folders. Then I have an ftp program that automatically uploads the file to a website from that point.
Summary:
2 email attachments in one email (88552_virginia.pdf) and (77558_calhoun.pdf).
The script needs to pick out the name of the attachment by looking for “virginia” or “calhoun” and save each to their own folder with a rename to ad.pdf
My folders would be
/virginia/ads/
/calhoun/ads/
I greatly appreciate any help. Thanks!
March 27, 2009 at 7:22 pm
Wonerful! Thank you very much!
April 3, 2009 at 8:03 am
Great script, perfect, just what i need!
Thank you.
April 15, 2009 at 6:40 am
This is very hot info. I think I’ll share it on Digg.
May 6, 2009 at 9:49 am
Works great. This is awesome. Thanks for sharing.
May 7, 2009 at 12:44 pm
You rock man, thanks it really helped me a lot.
May 8, 2009 at 1:07 am
Brilliant!
June 18, 2009 at 5:00 pm
[...] [...]
July 27, 2009 at 5:47 am
To all that want to save files in a non-standard way (example: with date stamping, in special dirs etc).
You need to change the outputFile, possibly the outputDir in the line
outputFile = att.FileName
Example: if outputFile = “attach01.jpg” and you want “attach01_2007-03-19_02-24-25.jpg”, all you need to do is some string manipulation.
If you define a new variable as “MailItem” you can use
set mailitemvar = sel.item(cnt)
Then it’s easy to access the properties for sel.item(cnt). Example: ReceivedTime. You can format as per standard VBA using format().
July 27, 2009 at 6:44 am
you may want to include the “MakeDirStructure” function found at http://www.visualbasic.happycodings.com/Files_Directories_Drives/code13.html
That way it’s quite simple to save in a structured way, example
outdir\sender\date\filename.ext
or
outdir\yyyy\mm\dd\filename.ext
just include makedir(outdir+ yoursubstructure) somewhere.
August 13, 2009 at 9:41 am
Great script! Thanks for sharing.
December 9, 2009 at 3:27 am
Exactly what I needed. Worked perfectly.
Would have been nice if it remembered the last directory I saved the files to, but other than that it’s excellent. Great work!
December 30, 2009 at 8:33 am
i used u work in my plugin to extract email attachments
fnx
March 5, 2010 at 3:08 pm
Awesome, can’t even tell you how great this is. Where’s the PayPal icon, you deserve some coin!
March 25, 2010 at 2:24 am
The site this is on is blocked for me… is it possible for somebody to email me the text file?!
Shawie3k@gmail.com
April 30, 2010 at 2:29 am
Thanks for a very handy script, saves me lots of time – you’re a star!
July 12, 2010 at 2:08 am
Great script, thanks. I had no idea that you could have macros in outlook
Just a quick question: Why not just use the “Dir” function in the macro to find out if the file exists rather than using the FileSystemObject?
fileExists = Not Dir(outputDir + outputFile) = vbNullString
July 12, 2010 at 6:45 am
Thank-you very much. I’ve been trying to teach myself enough VB to write this for myself, and it hasn’t been going well.
September 13, 2010 at 8:09 am
Love this macro! I scan a lot of docs to PDF in bulk (receipts, bills, etc) and love being able to extract them all so quickly and efficiently.
My prob is that when I scan a ton of documents at once, they all have the same name (i.e. “scan.pdf”) and having to rename each of them manually is time-consuming even with the input box. I tried to play around with the macro to automatically number each document based on the message number and it worked (i.e. “scan1.pdf”, “scan2.pdf”, etc) but it keeps crashing at 100. Ugh. I tried to troubleshoot as best as I could but haven’t nailed it yet.
REQUEST: any chance of a version of this that would do exactly that – i.e. rather than manually renaming, check for a document with the same filename and then just append the next in a sequential list of numbers to the document filename?
Regardless, great macro! Thanks!
September 13, 2010 at 1:54 pm
Maybe I’m not crazy, after all.
Tested the original macro with 100+ messages and it stopped/crashed after the 100th message/attachment. Any idea what it could be?
Thanks again!
September 16, 2010 at 7:44 am
The script opens up the message (and keeps them open) as it iterates over the messages and saves the attachments. I edited the script so that it processes a subset of the messages at a time and this issue went away.
I have attached the code below but am not sure how to format it correctly (so apologies for formatting of code).
September 14, 2010 at 6:35 pm
Jeremy,
Would you mind posting up the code that you altered to append a 1, 2, 3, etc… to the end of the filenames? I am also trying to find a way to append sequential numbers to the end of the filenames, as I may have thousands of attachments to save…!
But indeed, a great macro all up.
Cheers
September 16, 2010 at 7:29 am
I added this function to get a unique filename:
‘ If the filename already exists, add a counter to the filename (before the extension)
Public Function GetUniqueFilename(directory As String, filename As String) As String
Dim uniqueFilename As String
Dim index As Integer
uniqueFilename = filename
index = 1
Do While Not Dir(directory + uniqueFilename) = vbNullString
uniqueFilename = FileNameNoExtension(filename) + “_” + Format(index, “000″) + “.” + FileNameExtensionOnly(filename)
index = index + 1
Loop
GetUniqueFilename = uniqueFilename
End Function
September 16, 2010 at 8:29 am
My apologies – I don’t know VB so I just read other syntax and hacked this version together. It was only suited for my purposes where I knew that the filename would be four characters long. I modified (with humble apologies for the format) only one section of the original arcanecode macro:
* * * *
‘Loop thru each selected item in the Inbox
For cnt = 1 To Sel.Count
‘If the email message has attachments …
If Sel.Item(cnt).Attachments.Count > 0 Then
MsgTotal = MsgTotal + 1
‘For each attachment on the message …
For AttachmentCnt = 1 To Sel.Item(cnt).Attachments.Count
‘Get the attachment
Dim att As Attachment
Set att = Sel.Item(cnt).Attachments.Item(AttachmentCnt)
If MsgTotal < 10 Then
outputFile = Left(att.filename, 4) + "00" + CStr(MsgTotal) + ".pdf"
ElseIf MsgTotal < 100 Then
outputFile = Left(att.filename, 4) + "0" + CStr(MsgTotal) + ".pdf"
Else
outputFile = Left(att.filename, 4) + CStr(MsgTotal) + ".pdf"
End If
att.SaveAsFile (outputDir + outputFile)
AttTotal = AttTotal + 1
Next
End If
Next
* * * *
Again, it works for me in that it extracts all the attachments and appends a number to the filename but for some reason (with this code and with the original code) it crashes after 100 messages/attachments. Still haven't figured that part out yet, tho'.
Cheers,
Jeremy
September 21, 2010 at 12:06 am
Thanks for the quick responses guys! Could someone please tell me where in the original Arcane code you are meant to insert the Function code that Josh posted…? Unfortunately I only have a basic VB understanding.
Cheers again
Mike
December 28, 2010 at 10:28 pm
Thanks, I was searching long time for such piece of great code.
June 2, 2011 at 8:58 am
Was trying to get the txt file for this code and simply cannot. I even started a blog account I will never use to get it and still not being granted access.
July 13, 2011 at 6:19 pm
Same here. Would love to get this code but the link seems no longer valid. Can anyone help with a new link?
July 16, 2011 at 4:26 pm
Not sure why you would have a problem with the link as it seemed to work OK for me, but I just reposted the entire source file on my blog. There is also the non-shortened link to the original code I mentioned embedded in the source. You can find it at: http://arcanecode.com/2011/07/16/revisting-the-outlook-save-all-attachments-macro/
July 17, 2011 at 4:40 pm
Thanks for your quick response and thank you very much for the code. It is very helpful.
October 4, 2011 at 10:23 am
I keep getting a Compile error: Syntax error on “outputFile = InputBox(“The file ” + outputFile _”
Can anyone offer assistance on what I might be doing wrong. Thanks
October 7, 2011 at 4:17 pm
Wow, thanks so much! Amazing. Good input and help from those who got it working. All the answers are there. The only problem I had was with the reposted code. Use the direct txt link post if possible.
October 13, 2011 at 6:59 pm
Thanks for posting – using this script this will save me hours!
November 21, 2011 at 4:20 am
Thanks a lot for this script
December 7, 2011 at 1:58 pm
Link dead to the full code? 403 error – so may just be permissions..
December 22, 2011 at 5:32 am
Hi,
I can’t download the script, is there any posibility to get it?.
thanks.
January 11, 2012 at 7:56 am
i also can’t download – is it possible to upload it somewhere?
May 10, 2012 at 3:05 pm
Hi alll…. i was wondering after seeing all your msgs that whether this macro could help me in my work. if not Pls help me in puting a macro for the following work that we carry on.
Overview of the process that we do.
Customer applies for a product online, the details/data comes to the Manager as mails. he then saves those mails as .txt to a common drive, from which we take those cases and proceeds with our work… there would be above 1500cases a day. and its very tough to keep saving each mail that comes in outlook, it takes very long time. while saving a mail we mention the number as well, the file name would be for example:- 1.pepsi,2.pepsi,3.coke….. like wise for each file we add the seriel number to identify the number of cases that comes a day…
Kindly help me in creating a macro from the outlook to solve this issue, it would be a great help if i could get this done…
THANKS IN ADVANCE..