Strip Outlook Attachments and Replace with Links
UPDATE OCT 2009: Reader jumpjack has created a Google Code project for this macro. You can download the latest source code on the project page.
_________________________________________
There are many good reasons to strip attachments from your email messages. The main reason for me is that I often embed email messages into my Outlook tasks for quick reference. Since some tasks have multiple emails (each with multiple attached files), I need a way to keep the task size manageable. So, I simply strip the attachments before embedding the email into the task. Another reason to strip attachments is to improve Outlook performance. Smaller PST files are less likely to be corrupted and are faster to search and index.
The Outlook VBA macro below is one easy way to strip attachments from your messages. Simply select one or more messages in the Outlook explorer window, then activate the macro. The result is shown in the screen shot below. As you can see, all of the attachments throughout the email are numbered and replaced with links at the top of the message. There is even a hyperlink to the folder containing the attachments. The macro also saves a text copy of the original email message along with the attachments for future reference.
You’ll notice that there is still one small attachment remaining called “Attachments Removed”. This is added so that the paperclip icon in Outlook is still active, which indicates that the message has (or had) attachments.
The attachments archive folder is organized with one folder per email, as shown below. The folders are named using the date of the message, the sender name, and the subject line. At the end of the year, you can grab the whole collection and zip it up for archive purposes. Since the links are hard coded into the emails, you’ll want to be consistent with your folder locations. That is why I simply use “C:\Outlook Attachments\” along with the year. If I ever want to restore some old messages and be able to browse the file attachments, I know exactly where to put them.
Ok, so here is an excerpt of the code. Download the full version (link to zip file below). Unzip and place the “Outlook Attachments” folder at your C:\ root. This will give you a copy of the 0 kb “Attachments Removed” file in the right location for the macro to use. Next, paste the code from the text file into any module in your Visual Basic Editor.
Public Sub StripAttachments_Explorer()
'This VBA Macro removes attachments from whatever emails are selected
'in the Outlook explorer window and stores them on the hard drive. Links
'to the stored files are added to the email. Note that RTF and PlainText
'messages are converted to HTML. The hooks are still below if you want to
'uncomment those line and handle text messages separately.
'Tested with Outlook 2003 only.
'v1.3, Carl C, 22-Feb-09
'http://manage-this.com
'
On Error GoTo ErrorHandler
'
'Edit this path to point to the root for your archive. This
'folder must already exist before for you start using this tool.
'Choose a root folder that is easy to remember for restoring
'message attachments later since the message bodies will be
'written with hard links to this location.
Const RootFolder = "C:\\Outlook Attachments\\2009\\"
'
'Threshold message size (in kilobytes) - Messages smaller than this get skipped.
Const THRESH As Long = 100 'kb
'
Dim olns As Outlook.NameSpace
Dim objMsg As Object
Dim objAttachments As Outlook.Attachments
Dim objSelectedItems As Outlook.Selection
Dim i, J, Counter As Integer
Dim msgFormat As Long
Dim Header, FileList, Footer As String
Dim attPath, attFileName, msgFolder, msgSender, msgSubject, yearFolder, temp As String
Dim oleFound, dropSubject As Boolean
'
Set olns = Application.GetNamespace("MAPI")
'
Set objSelectedItems = olns.Application.ActiveExplorer.Selection
'
'Make sure base path exists
If Dir(RootFolder, vbDirectory) = "" Then
MsgBox "Root Folder Not Found!" & vbCrLf & _
"Please create the following folder first: " & vbCrLf & RootFolder
GoTo ExitSub
End If
'
For Each objMsg In objSelectedItems
'
' Skip anything that's not a mail message (calendar items, tasks, etc.)
If objMsg.Class = olMail Then
'
Set objAttachments = objMsg.Attachments
Counter = objAttachments.Count
'
'Only execute if there is at least one attachment in the message
If Counter > 0 Then
'
'Check if the attachments have already been removed - if so, don't do it again
If objAttachments.Item(1).Type <> olOLE Then
If (objAttachments.Item(1).FileName = "Attachments Removed") _
And (Counter = 1) Then
GoTo TheNextMessage
End If
End If
'
'If the current message is fairly small, then skip it. It likely containts only
'tiny pics in the signature or a background image. No point in stripping those.
'Note - It would be better to check the size of each attachment, but there is no
'clean way to do this in Outlook 2003. Would require PR_ATTACH_SIZE (0x0E200003)
'property of the attachment... See http://www.cdolive.com/cdo10.htm
If (objMsg.Size < (1024 * THRESH)) Then
GoTo TheNextMessage
End If
'
'Check to see if any of the attachments are OLE format. If so, skip the
'entire message since stripping these is messy
oleFound = False
For i = objAttachments.Count To 1 Step -1
If objAttachments.Item(i).Type = olOLE Then
oleFound = True
Exit For
End If
Next i
If oleFound Then GoTo TheNextMessage
'
'Note - I disabled the year folder since it had to be checked for every
'message. Added it to the Root Path definition instead.
'
'Create the year folder if it doesn't already exist
'yearFolder = RootFolder & Strings.Format(objMsg.ReceivedTime, "yyyy") & "\\"
'If Dir(yearFolder, vbDirectory) = "" Then
' MkDir (yearFolder)
'End If
'
'Some of the dual-byte (DBCS) chars cause problems since the subject line is
'used in the file path name. If the message format does not belong to one of
'the formats below, then don't use the subject line in the path or file name.
dropSubject = False
msgFormat = objMsg.InternetCodepage
If ((msgFormat = 28592) Or (msgFormat = 1250) Or (msgFormat = 20127) _
Or (msgFormat = 28591) Or (msgFormat = 1252)) Then
msgSubject = objMsg.Subject
Else
msgSubject = "message"
dropSubject = True
End If
'
'Strip illegal chars from msgSubject
invalidChars = Array("\", "/", ":", "*", "?", """", "<", ">", "|", "…")
For J = LBound(invalidChars) To UBound(invalidChars)
temp = Replace(msgSubject, invalidChars(J), " ")
msgSubject = temp
Next J
msgSubject = Replace(msgSubject, "RE ", "")
msgSubject = Replace(msgSubject, "FW ", "")
'
'
'CODE CONTINUES FOR MANY MORE LINES...
'CLICK LINK BELOW TO DOWNLOAD FULL VERSION...
DOWNLOAD THE CODE: Email Attachments Stripper v1.3
NOTE: Version 1.3 will remain hosted here, but the source is being moved to Google Code as of Oct 2009. The latest version will be available on the project page here.
Note that this has only been tested with Outlook 2003 and Windows XP. If you have a different system configuration, it may require some tweaks. Thanks especially to Sue Mosher and her outstanding web site, OutlookCode.com. Many examples scattered throughout her site were used to create this tool.
To make this tool easier to use, I would also recommend adding a shortcut button to one of your Outlook menu bars. I like to use the little disk icon with the down arrow (shown below).

Yes, there are some other super-secret icons on that menu bar that will be revealed in future posts. In the mean time, have fun stripping!
-Carl



March 17, 2009 - 10:45 am
Carl,
This is exactly what I have been looking for to manage the size of my Outlook PST. Our company limits the PST file size to 200MB. As soon as you are over the limit, you can no longer send emails until you reduce the size.
The only problem I have is that I keep getting an error message each time I execute the macro. Even though I get the error message, the attachments are stripped, put into the C:\drive, the links are created in the email, and the *.txt file of the message is created. Just seems odd that I get the error message each time.
Is there something I missed in the setup?
RemoveAttachments() Subroutine
Error Code: -2044264445 (code varies each time I execute)
Path does not exist. Make sure the path is correct.
March 17, 2009 - 12:37 pm
Ok. I found by reading the code that I needed to some additional setup. I needed to create a folder called “Config” under the root directory, the path looks like this “C:\Outlook Attachments\2009\Config” and place a zero byte file called “Attachments Removed” in that folder. After doing both of these, no more errors.
I do have a followup question though. Is it possible to change the script to prompt the user for an existing folder path to store the attachment? For example, I have a folder called “Projects” in My Documents with various Sub-folders representing the separate projects. I would like to detach the attachments to particular folders instead of always saving to the same file path. What would I need to do to change the code to prompt for a folder to save the file(s)?
March 19, 2009 - 8:19 am
Hi Bobby… You are correct on the config path. I wanted to make sure that the zero byte file could be easily found by the script. Without that file, you loose the paperclip icon. Not terrible, but it’s nice to be able to filter on that column or even search for emails with attachments even after they are stripped. It sounds like you have that part configured correctly now.
Regarding a prompt for the user to select a path, that is definitely possible. First, you would need to prompt the user using something like this example. You may find additional examples on Sue Mosher’s site. Then, you store that response in a variable.
In the macro, the “msgFolder” variable is used as the save path. Just delete or comment out all of the lines in the macro that build the message folder path and instead use the path that the user provided via the dialog box. You may have to clean up the user response a little bit. For a first test, I would use the MsgBox command to display the contents of the msgFolder variable before trying to use it to write files.
Hope that helps, good luck!
-Carl
March 19, 2009 - 9:33 pm
Bobby – Now that I think about it, you may want to leave the msgFolder variable as-is and instead change “RootFolder”. That way, if the user is stripping attachments from multiple emails at once, the files from each email will still be grouped inside their individual message folders. You could have the RootFolder path defined by the user each time via the browse dialog. Just a thought. It depends on what behavior you want.
-Carl
May 4, 2009 - 9:49 am
Carl,
Nice code! This is similar to what I have been looking for, would appreciate your help with the following.
Does your code require the outlook client to be open? Is there a way to run this at the server level?
We’re trying to build something to automatically detach .TXT files as they arrive, and save them to the appropriate folder, based on the inbound email address.
Emails to blue@test.com should have their .txt attachments saved to the BLUE_inbound folder; emails to red@test.com should have their .txt attachments saved to the RED_inbound folder;
Obviously, I don’t want to have to have outlook clients ‘open’ for this to run correctly.
My goal is to copy the .txt attachments, and place them somewhere where they can be processed on some regular basis. As such, I actually don’t want to strip them from the email; would rather copy the attachment out, and then move the email to a ‘processed’ subfolder.
Any suggestions would be appreciated. Best, Karen
May 4, 2009 - 9:42 pm
Hi Karen -
The code is a VBA macro the runs on the client side, so yes, it requires an Outlook client to be open. There may be options to do something similar with server-side scripting, but I have no experience there. One thing you can easily do is create a client rule that passes each incoming message to the macro for immediate processing. That would still require a client PC, but would be more automated.
Regarding your other question, it is definitely possible to have the macro copy the attachment without removing it from the message. Simply find this line in the code: “objAttachments.Item(i).Delete” and comment it out by placing a single quote ‘ in front of the line.
Hope that helps.
-Carl
May 19, 2009 - 12:22 am
Great idea but I can get it to work for a short while, then it stops working – no error messages, just doesn’t work. I’m using Outlook 2007.
May 19, 2009 - 12:53 am
OK, forget previous comment. I was testing the macro on very small attachments. Now I’ve skimmed through your code and can see that it skips the smaller attachments!
Great work, thanks….
May 19, 2009 - 10:59 am
Alastair – I think you got it now. As indicated in the comments, you can change this behavior by changing this line:
Const THRESH As Long = 100 ‘kb
For example, if you want to strip anything larger than 50kb, use:
Const THRESH As Long = 50 ‘kb
-Carl
June 18, 2009 - 12:53 am
Hi Carl,
very nice code. It works without problems.
One Question: Is it posibble to start the macro automaticly for every incoming mail? I think it must replace the “objSelectedItems As Outlook.Selection” with an other construction?
Greats
praetor
June 21, 2009 - 11:42 pm
Praetor – Yes, that’s defintely possible. I have done similar things with other macros. First, you have to re-structure the macro a bit. You don’t need to loop through multiple items in a selection since you will only be passing it one message at a time via an Outlook rule. You also have to change the first line to accept a passed object. Something like: Sub StripAttachments(objMsg As Outlook.MailItem). Not sure, but you might have to also move the macro to the “ThisOutlookSession” page if it doesn’t fire from the rule.
Once the macro is modified, you would create an Outlook rule that fired on each message and ran the macro on that message. To prevent the macro from running all the time, you can build the logic into the Outlook rule to only trigger when a message contains attachments and is larger than a certain size.
Good luck!
-Carl
June 25, 2009 - 8:49 am
Hey Carl,
Great code, but I’m having some difficulties with the “Attachments Removed” file in the config folder. I’m not quite sure how to get the file in the folder. I tried extracting it from the “Email Attachments Stripper v1.3″ link you have above but when I extract it, it creates new folders. I tried creating a new txt document but that was also unsuccessful. Also, I’m not seeing any links to the files in my email. I think it’s because my emails are in plain text but I’m not sure and I don’t know how to get them into html.
June 26, 2009 - 9:55 am
I am trying to use this code on Outlook 2003, Windows XP. It does work, however it always comes back with an error saying the path does not exist and it only strips out one attachment each time the code is run. Can you help? Thanks
June 28, 2009 - 12:08 pm
Matt -
Depending on which tool you use to extract the zip file, it may try to create the folders for you. Basically, you have to have the “Attachments Removed” file in the “config” folder underneath whatever path you define in this line:
Const RootFolder = “C:\\Outlook Attachments\\2009\\”
Also note that the file has to have the name “Attachments Removed” with no .txt or other extension.
This should work on most messages. The message size has to be greater than the threshold you set, and it will skip messages with OLE attachments (usually RTF messages). For other formats, it will convert the message to HTML format and include the links.
Hope that helps.
-Carl
June 28, 2009 - 12:13 pm
Steven -
Nobody has reported this issue in the past, so not sure what might be causing it. It might be something with the new folder (path) it is creating for each message. Do you have any strange characters in the subject line that would not be valid in a folder name? I would recommend adding a few “MsgBox” commands at various points in the code so you can see how far it is getting before it exits. You can also comment out the “On Error GoTo ErrorHandler” line so that the VBA Macro debugger can take you to the exact line of the code when it stops.
Let me know what you find out from that, and I can probably provide some better suggestions.
-Carl
July 5, 2009 - 3:45 am
This is exactly what I have been looking for. I am running it on Outlook 2007 and overall it works fine. Sometimes however I’m getting an error RemoveAttachments() Subroutine Error Code: -2147467259 The operation failed.
This seems to be related to specific messages and if I skip these ones its works fine. I can’t seem to find what the error is. Any ideas?
Colin
July 5, 2009 - 5:52 pm
Thanks!
I addd the “File Removed” attachment process to a VBA macro I developed for atachment processing. I outlook 2007 it shows as a 6 kb file and addes to the size of the message (5 or 6 kb) Is this your experiance?
I am trying to update my VBA routine to skip embeded images, etc. As you say, they are generally logos, etc that should stay in the message. For me the actual attachments are job related materials that need to be saved in job folders, regardless of size. It seems to me that for smaller files I will need to step through and prompt as to wheteher to save or not. Any thoughts? generally the
July 7, 2009 - 8:19 am
Can I strip the attachment from a sender that the subject line’s first 15 characters are always the same and save the file to whatever location with a same file name overwriting previous files?
July 8, 2009 - 1:06 pm
Colin - Not sure what could be causing that. Sometimes non-standard characters in either the message subject or attachment file name can cause errors, although most of those are already stripped out by the macro. I would recommend adding a few “MsgBox” commands at various points in the code so you can see how far it is getting before it exits. You can also comment out the “On Error GoTo ErrorHandler” line so that the VBA Macro debugger can take you to the exact line of the code when it stops.
cHRISrs - Yes, the “Attachments Removed” file is not zero bytes. For messages with stripped attachments, I wanted the paperclip icon to still show up in Outlook for sorting & filtering. Adding a very small attachment was the only reliable way to preserve that. The attachment was created by making a zero-character file in note pad and naming it “Attachments Removed” without the .txt extension. Having this attachment also allows you to still search on messages with attachments in WDS or GDS. To answer your second question about skipping smaller files, the macro does this automatically now and you can set the threshold to whatever you like. My thinking is that a prompt on every message could get to be annoying after a while.
Ken - You could definitely modify the macro to do that. The subject is in objMsg.Subject. You could wrap the macro in an If statement and use some string functions to compare only the first (leftmost) 15 characters of the subject with your desired string. Alternatively, you could check the subject via an Outlook rule, then use the rule to run the macro on incoming messages (see comments above from 21-Jun-09). When the SaveAsFile command launches, it will overwrite the previous files if the pathname and filename are the same. The macro appends a date stamp to the pathname to prevent this from happening, so just remove that portion from the code above if you want files to be overwritten.
-Carl
July 15, 2009 - 6:53 am
Hi Carl,
This is a fantastic script !
However i noticed that every now and again the script would give a
” RemoveAttachment() Subroutine Error Code:
-2147467259 The operation failed”
error on certain emails with attachments.
After a lot of testing i’ve found that the problem occurs when the email subject title goes over 90characters. Below 90 and all is fine. Above 90 and you get the error stated above. Is there some way to either extend this character limit or if not – check for the subject title length and if over 90chars – chop a little off ?
all the very best
July 17, 2009 - 2:41 pm
Andy – Good catch! I’m not seeing the same error message you describe, but I am having path names get cut off unexpectedly on test messages with extremely long subjects. I believe the WinXP limit is 256 chars, so I’m not sure why the path names are being truncated. Could be some limitation in Outlook’s VBA.
Anyway, I’ll post an updated macro when I get a chance. In the mean time, you can insert the following line right after the “msgSubject = Trim(msgSubject)” line:
msgSubject = Left(msgSubject, 60)
This will limit the subject length to the first 60 chars. Since the sender name as well as the date also ends up in the path name, I picked 60 chars in order to keep the whole thing under 90.
Hope that helps!
-Carl
July 20, 2009 - 2:28 pm
Hi – I’m not a programmer, so I’m hoping you can help me out. Our company just switched from Lotus Notes to Outlook, and I have a user asking whether one feature in Notes can be replicated in Outlook. This feature is that when an email containing an attachment has been forwarded or replied to *without* the attachment, a notice appears at the bottom of the email noting that “attachment [filename] was removed by [username].” This lets future readers know an attachment was originally part of the email, and what it was called, so they can go back and locate it. Since Outlook defaults to replying without the attachment, my user really misses this feature. Any chance your code above could be modified to perform this function? And if so, could you please also post instructions on how to incorporate the code into Outlook? Thank you very much in advance!
July 20, 2009 - 10:55 pm
Mary -
What you are describing can probably be done, but it is something different than what this macro is intended to do. In your case you would probably need to replace the “Reply” button in the explorer toolbar and on the message toolbar with your own homemade reply function that retrieves the attachment names in the current message and appends them to the reply.
Otherwise, your user can select Forward instead, then manually paste names into the TO: and CC: fields and manually change the subject prefix from “FW” to “RE”.
-Carl
July 27, 2009 - 11:56 am
Is there a way for this to be run on several messages at the same time? I’m trying to go back and clean out my old emails before I reformat and reinstall XP and everything else. I’d like my .pst file to be small and clean when I do that, and this is rather time consuming as I have several years of emails I’m cleaning up.
Thanks!
July 27, 2009 - 12:01 pm
Sorry for multiple comments…I keep getting an error that says the path does not exist, but it is removing the attachments and saving them. When I click away and back to the message it shows the attachement was removed.
July 29, 2009 - 9:03 pm
Mark -
To answer your first question: Yes, just select multiple messages before launching the macro and it will step through each one stripping the attachments and inserting links. After that, you’ll want to select Properties for your PST file, go to Advanced, click the “Compact Now” button, then go out and get a coffee while it crunches on the file.
On your second question, this error may be causing the macro to stop after the first message is processed. Look at the message after processing… Does it now have an attachment named “Attachments Removed” or are there no attachments at all?
-Carl
August 6, 2009 - 2:30 pm
Is there a way to run the macro against the whole mailbox or multiple folders\subfolders at once without going through each folder and selecting the items manually?
August 8, 2009 - 9:08 am
Russ – To run the macro against the whole Inbox, select all (CTRL-A) and let ‘er rip. It could also be made to run recursively through a set of sub folders, but that would require a fair amount of additional code. There may be some examples on Sue Mosher’s site, but it would be a significant re-write.
-Carl
August 10, 2009 - 1:13 am
Great macro!
I noticed that this was said before, but it can happen sometimes that the macro runs into an error like Path not found or something like that due to the path name limitation to 256 chars. Therefore I made some changes to my local copy.
First, I replaced
attFileName = objAttachments.Item(i).FileName
attPath = msgFolder & "\\" & attFileName
by
Dim dotPos As Integer
attFileName = objAttachments.Item(i).FileName
Do
attPath = msgFolder & "\\" & attFileName
If Len(attPath) > 256 Then
dotPos = InStrRev(attFileName, ".")
If dotPos = 0 Then
attFileName = Left(attFileName, Len(attFileName) - 1)
Else
attFileName = Left(attFileName, dotPos - 2) & "." & Mid(attFileName, dotPos + 1)
End If
Else
Exit Do
End If
Loop
and then
msgFolder = RootFolder & msgFolder & "\\"
by
msgFolder = Left(RootFolder & msgFolder & "\\", 150)
Next, i noticed that someone sent me an email with a TAB character in the subject, which also caused an error. To catch this, I inserted this character in the invalid character list, so I exchanged
invalidChars = Array("\", "/", ":", "*", "?", """", "", "|", "…")
by
invalidChars = Array("\", "/", ":", "*", "?", """", "", "|", "…", Chr(9))
-Michael
August 11, 2009 - 4:39 pm
Michael -
Thanks for the detailed suggestions! I’ll check them out and probably fold them into the original code. One comment on this line:
msgFolder = Left(RootFolder & msgFolder & "\\", 150)If the “\\” is really needed, it might get truncated. I’ll have to check that… Maybe instead something like this to preserve the ending:msgFolder = Left(RootFolder & msgFolder, 148) & "\\"Anyway, thanks again for the suggestions!
-Carl
August 18, 2009 - 5:44 pm
Hi Carl, fantastic and useful tool! I just installed it in VISTA 64x, by the very same method you described in the post. Works like a charm! Thank you!
August 18, 2009 - 5:48 pm
By the way, I use Office 2007.
Thanks again!
August 18, 2009 - 10:54 pm
Mariane – Thanks for your comments, glad to hear that it worked!
August 26, 2009 - 8:24 am
This macro works well for me but I can’t get it to work on calendar items. For our use, that is most important.
We have storage quotas on our exchange server. Normal mail items I can easily move off to a PST file but it is very helpful to keep the calendar entirely on the exchange server. Attachments to calendar items eats up that quota very quickly.
Any ideas?
August 26, 2009 - 11:23 am
Well I have enough hacks in to provide basic support for Appointment items. I need to clean things up (big time) but I made the following changes:
- I replaced “If objMsg.Class = olMail Then” by “If 1 Then” to let all objects through
- For non-MailItem objects, I set msgSender to “” since the SenderName doesn’t exist for some of those other objects (such as AppoitmentItem objects)
- I Used CreationTime instead of ReceivedTime (which doesn’t exist for AppointmentItem objects)
- I utilized objMsg.HTMLBody only for MailItem objects. The other objects will use Obj.Body
August 26, 2009 - 9:08 pm
Dennis -
Sounds like you got it. That is pretty much what I would have recommended, and I wouldn’t have thought of the HTMLBody change without trying it. Nice work.
I would say that even with attachment stripping, eventually your calendar will still need to be cleaned out. You *can* archive calendar items in your PST along side your mail items. Here are the steps I follow (about once every 3 months). These are for OL2003, so there may be slight differences in OL2007….
(1) Create a new folder in your PST and select “Calendar Items” instead of “Mail and Post Items” during the creation process. You can name it something like “Calendar Archive 2009″
(2) Go to your main calendar, then select View > Arrange By > Current View > Events. This should give you a list of calendar items instead of the calendar view.
(3) Sort by “Recurrence Range End” with the oldest items at the top. If Recurrence Range End is not a column, you will need to add it via the Field Chooser. This sort allows you to select meetings which are no longer needed without having to worry about losing recurring meetings.
(4) Select any meetings that have a Recurrence Range End that is more than a month old and drag them to the PST folder you created. For meeting you created, you may get a warning that says meeting responses will no longer be tracker. Just keep click OK until all the items are moved. If you are viewing the calendar items in groups, you will have to repeat this for each group.
(5) Reset your view back to Day/Week/Month (or whatever you prefer).
That’s it. I like to keep about 1 month of history in the main calendar. The other nice thing is that calendar items in the archive folder are still indexed by desktop search (WDS or GDS), so they turn up in your search results just like always.
It wouldn’t be hard to create a macro that selects any calendar items with Recurrence Range End older than N days and moves them to the Calendar Archive folder. That one is on my to-do list, I just haven’t gotten around to it yet
-Carl
August 27, 2009 - 5:00 pm
Hmm, so what is the use case for stripping attachments out? To cut down on PST size? How does PST size affect Outlook performance?
August 27, 2009 - 8:43 pm
Dennis -
There are several use cases, depending on how you prefer to work. With the modifications you made, you can strip attachments from your calendar items and probably go a year or more without having to clean anything out.
Also, as you mentioned, there is a performance hit from large fragmented PST files. It is a database, after all. Even though the PST size limit was significantly increased starting in OL2003, many people still recommend keeping your PST files below 2GB. There is some information on allowable PST sizes here, and some nice recommendations on how to speed up Outlook performance in general here.
Another use case is for messages in the Inbox. If you have a message with a large attachment but aren’t ready to move it offline yet, you can convert the attachment to a link. Also, if you are going to convert an email into a task, it’s a good idea to strip the attachments first since the task will likely take up space on your central server.
-Carl
September 12, 2009 - 12:18 pm
Carl,
fantastic macro..does exactly what I used to be able to with lotus notes, the only problem I keep running into is that when modifying the threshold for the message size..no matter what I seem to specify, it is still archiving smaller attachments.
right now it is set to: Const THRESH As Long = 5 ‘kb but seems to do the same no matter what I change it to
September 13, 2009 - 10:05 pm
Dan -
I’m not sure why you are seeing this behavior. I’m able to adjust the THRESH constant and the macro skips messages smaller than that value. Maybe you could try hard-coding a threshold instead of using the constant. To do this, modify this line:
If (objMsg.Size < (1024 * THRESH)) Then-Carl
September 14, 2009 - 1:54 am
Fantastic macro! I have been looking for it (and trying to write it by myself…) for months!
(just to keeptrack of changes made to original project).
You saved me a lot of work, thank you very much.
I think project is mature enough to pass to googlecode for proper versioning, now…
Apart from this, I think it could be useful to get the macro creating separate folders for inbox and outbox. To keep compatibility with current version, it could just create a separate folder for outbox, keeping inbox attachment in main folder.
September 14, 2009 - 2:52 am
My idea for progress gauge:
[...]
For Each objMsg In objSelectedItems
‘ Code for progress gauge related to messages count:
Partial = Partial + 1
ProgressGauge = Int(100 * Partial / Total)
frmProgress.lblMsgGauge.Width = ProgressGauge
frmProgress.lblMsgPerc.Caption = Str$(ProgressGauge) & ” %”
frmProgress.lblMsgPerc.Left = ProgressGauge + 20
‘ Reset attachments gauge
frmProgress.lblAttGauge.Width = 0
frmProgress.lblAttPerc = 0
frmProgress.lblAttPerc.Left = 10
DoEvents ‘ Update form
[...]
[...]
For i = objAttachments.Count To 1 Step -1
PartialAtt = PartialAtt + 1
ProgressGaugeAtt = Int(100 * PartialAtt / TotalAtt)
frmProgress.lblAttGauge.Width = ProgressGaugeAtt
frmProgress.lblAttPerc.Caption = Str$(ProgressGaugeAtt) & ” %”
frmProgress.lblAttPerc.Left = ProgressGaugeAtt + 20
DoEvents
[...]
You’ll need a form named frmProgress containing 4 labels (2 for messages and 2 for attachments)
And to distinguish inbox from outbox:
If InStr(UCase$(olns.Application.ActiveExplorer.CurrentFolder.Name), “INVIATA”) > 0 Then
msgFolder = RootFolder & “@inviata\\” & msgFolder & “\\”
Else
msgFolder = RootFolder & msgFolder & “\\”
End If
(but this is not portable fordifferenet languages, you must specify proper name for your outbox)
I put the “@” in front of folder name to have it always as first item listed in alphabetical order.
September 14, 2009 - 8:44 pm
jumpjack -
Thanks for your suggestions! The progress bar sounds interesting. I’m not sure if I understand why you would want to add an “inbox” folder to the save path… Is that to separate attachments that you send from attachments that other people send to you? Sometimes I run this macro on a message after I have already moved it out of the inbox, so I’m not sure this modification would work for me.
-Carl
September 15, 2009 - 2:36 am
yes, I prefer separating sent from received attachments. I think it’s just a matter of personal “orientation”.
September 16, 2009 - 10:09 pm
jumpjack – That makes sense. It might be better, then, to separate the attachments using the sender address. All emails sent from yourself could have attachments put in one folder, and all other emails could have the attachments put in a separate folder.
Sometimes emails that I sent myself end up in my Inbox. Also, once emails are moved to the archive, they could be mixed together. That would make it hard to separate them using “.CurrentFolder.Name”, but the sender name will be the same even if the email is moved. Just an idea!
-Carl
September 17, 2009 - 5:02 am
Genius tool. One issue/question…
Outlook seems to be creating numbered copies of the “Attachments Removed” file in C:\Documents and Settings\\Local Settings\Temporary Internet Files\OLK
It can only handle up to 99 such files, hence unless I manually delete the files it creates as it’s running – it fails after 100 replacements. Any ideas on a correct fix?
September 17, 2009 - 5:46 am
It seems to be a garbage collection issue, since once the macro terminates, all the temporary files are removed… I tried adding:
TheNextMessage:
Set objAttachments = Nothing
Set objMsg = Nothing
Next objMsg
But that doesn’t seem to be enough. — Antony
September 17, 2009 - 12:27 pm
Antony – That’s strange, I’ve never encountered this behavior before, but I just tried to force it and I saw the same issue you mentioned. The error message is “Error Code: -1179631611 Can’t create file: Attachments Removed. Right-click the folder you want to create the file in, and then click Properties on the shortcut menu to check your permissions for the folder.” This is a generic error message from Outlook, not from the macro itself.
To force this error to happen, I had to select 100 or more messages that actually had attachments larger than the threshold. In my case, this meant selecting about 500 messages at once, since many of my messages either had smaller attachments or none at all. Everything does get cleaned up when the macro exists, so you can run it over and over again without any problems, as long as you select about 100 messages at a time. As a side note, I think Outlook is storing the temp files in a different location on my machine. I’ll have to look into what’s causing this.
Thanks for bringing this up!
-Carl
September 28, 2009 - 3:49 am
Super macro! i’ve been using it and tweaking it to only copy out attachments and pasting them into one single folder.
question: an error occurs when i run the macro on too many emails i get the following error
“error code: -2147467259
Method ‘Attachments’ of object ‘MailItem’ failed”
any idea how i can run it for a folder of more than 3000+ emails?
thanks!
October 1, 2009 - 6:21 am
Sam, I think it’s not a matter of number, but of type: maybe you selected also “messages” which are not actually mail messages: maybe they are schedule proposals, or return receipts, and so on, which cannot have attachments.
Does your version of the macro contain this line?
If objMsg.Class = olMail Then
If yes, try clicking on DEBUG button upon enconutering the error you mentioned, and try determining WHICH message exactly is raising the error: it should have “something strange”…
Use:
print objmsg.senton
it should print date of creation/receipt of the messagem thus allowing you to easily find it.
————-
Apart from this, how can I fix the messages processed with previous version of macro which had the “too long folder” issue preventing from opening the attachments with a click?
(see comment July 17th, 2009 at 2:41 pm )