Handy Outlook Attachment Reminder Macro
Have you ever had one of those “oh shit” moments where two seconds after sending an email you realized something was missing? And you know, by using the Outlook “Recall Message” feature, you’re just going to draw even more attention to your mistake. It’s like a highway accident… people will open recalled messages before anything else in their Inbox just to see what you might have screwed up.
Here’s one easy way to prevent that from happening: use this Outlook VBA macro to automatically scan your outgoing messages and stop incomplete emails & invites before they get sent. This macro will check for missing attachments on messages & meeting invites where you probably meant to attach something. It will also check for blank subject lines, as well as blank locations in meeting invites.
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
'Attachment Reminder Macro
'Carl C, 17-Sep-08
'http://manage-this.com
'
'Paste this macro into your "ThisOutlookSession" module.
'DISCLAIMER: This was only tested on Outlook 2003
'
'ADDITIONAL CREDITS:
'This macro was created by modifying Mark Bird's original code which
'can be found here: http://mark.bird.googlepages.com/, fixing some
'issues related to search strings on replies/forwards, and also
'merging in additional features/checks taken from examples on Sue
'Mosher's OutlookCode.com. See examples here:
'http://www.outlookcode.com/codedetail.aspx?id=539 and here:
'http://www.outlookcode.com/codedetail.aspx?id=1278 Thanks to Mark
'Bird, Jeremy Gollehon, Steve Bateman, and of course, Sue Mosher
'
Dim m As Variant
Dim strBody As String
Dim intIn, intLength As Long
Dim intAttachCount As Integer, intStandardAttachCount As Integer
'
On Error GoTo ErrorHandler
'
'You may have a picture or vCard in your email signature that you
'don't want to be counted when checking for attachments. If so, then
'edit the following line to make intStandardAttachCount equal the
'number of files attached in your signature.
intStandardAttachCount = 0
'
'CHECK #1: Check for a blank subject line
If Item.Subject = "" Then
'Extra spaces added to the messages just to
'keep them centered and pretty
m = MsgBox("The subject line is blank... " & _
vbNewLine & vbNewLine & _
"Do you still want to send this message? ", _
vbYesNo + vbDefaultButton2 + vbExclamation + vbMsgBoxSetForeground, "Blank Subject")
If m = vbNo Then
Cancel = True
GoTo ExitSub
End If
End If
'
'CHECK #2: Check for a missing attachment
intIn = 0
strBody = LCase(Item.Subject) & LCase(Item.Body)
'If the message is a reply or forward, then the macro will
'not search for the strings in the original message. Anything
'below the "from:" line is ignored
intLength = InStr(1, strBody, "from:")
If intLength = 0 Then intLength = Len(strBody)
'
'Add lines for every string you want to check, including other
'languages, etc. Partial strings are fine. For example, "attach"
'will match "attached" & "attachment"
If intIn = 0 Then intIn = InStr(1, Left(strBody, intLength), "attach")
If intIn = 0 Then intIn = InStr(1, Left(strBody, intLength), "file")
If intIn = 0 Then intIn = InStr(1, Left(strBody, intLength), "enclosed")
'
intAttachCount = Item.Attachments.Count
If intIn > 0 And intAttachCount <= intStandardAttachCount Then
m = MsgBox("It looks like you forgot to attach a file... " _
& vbNewLine & vbNewLine & _
"Do you still want to send this message? ", _
vbYesNo + vbDefaultButton2 + vbExclamation + vbMsgBoxSetForeground, "Attachment Missing?")
If m = vbNo Then
Cancel = True
GoTo ExitSub
End If
End If
'
'CHECK #3: Check for meeting requests with no location
If Item.Class = olMeetingRequest Then
If InStr(1, Item.Body, "Where:", vbTextCompare) = 0 Then
m = MsgBox("The meeting location is blank... " _
& vbNewLine & vbNewLine & _
"Do you still want to send this meeting invite? ", _
vbYesNo + vbDefaultButton2 + vbExclamation + vbMsgBoxSetForeground, "Blank Location")
If m = vbNo Then
Cancel = True
GoTo ExitSub
End If
End If
End If
'
ExitSub:
Set Item = Nothing
strBody = ""
Exit Sub
'
ErrorHandler:
MsgBox "Send Checker" & vbCrLf & vbCrLf _
& "Error Code: " & Err.Number & vbCrLf & Err.Description
Err.Clear
GoTo ExitSub
End Sub
I know there are probably 100 variations of this sort of macro floating out on the web, but I’ve customized this one quite a bit and it really works well for me. Hopefully you can make some use of it too.
Another good way to prevent an “oh shit” moment is by delaying your outgoing messages by a few minutes, as described here and here. A nice twist to this if you want to send a particular message immediately is to add an exception to the Outlook rule, such as if the subject line contains two underscores “__”, or if the importance is set to high.
Good luck!
Carl



September 18, 2008 - 11:37 pm
do you know what will be timestamp of the recalled message?
September 19, 2008 - 7:30 am
Vixmus -
The macro above does not recall messages or use the Outlook recall message feature. It stops messages before they are sent in case you want to correct any of the missing items. The time stamp will still be whatever time you finally send the message.
Does that answer your question?
-Carl
September 29, 2008 - 10:43 am
Here’s one variation that includes some other features as well:
Outlook Etiquette Check VBA Code
November 24, 2008 - 12:05 pm
I’ve tried several different versions of the above code from around the net, but seemingly all of them have the same problem. When I send the email the box that asks whether I want to send the email or not pops up underneath the email itself, to wherever my inbox is. Is there a way to change this? Thanks!
November 25, 2008 - 1:13 pm
Matt – I have never experienced the issue you described. There are a few things you could try to force the window to the top. The properties of VBA message box are determined by a series of constants that get summed together. Each constant represents a different attribute. Look for the sections in the code that state something like “vbYesNo + vbExclamation”. Try adding either “vbMsgBoxSetForeground” or “vbSystemModal”. These are both valid attributes for the MsgBox command. For example, the line
vbYesNo + vbExclamation, “Attachment Missing?”)
Would be changed to
vbYesNo + vbExclamation + vbMsgBoxSetForeground, “Attachment Missing?”)
Please post a comment back here and let me know if it helped. Good luck!
-Carl
November 26, 2008 - 10:14 am
It worked, but strangely instead of just pulling up the option window it pulls up the entire inbox and the window. It’s not a big deal, you’re not searching for the box anymore; but I figured from a developers standpoint you might be interested to know that.
November 26, 2008 - 10:20 am
O and thanks a lot btw! This is a really helpful piece of code… I’ve gotten in trouble like 3 times at work for absent minded email omissions. They’re really anal about that in my office. Very helpful for avoiding that problem again. Thanks!
November 26, 2008 - 11:21 pm
Matt – Thanks for the feedback, glad to hear it helped.
-Carl
February 18, 2009 - 7:37 am
This is great but doesn’t check the subject line, if i send an email file 3 of 4 in subject line and nothing else. Is there a way this is possible? Thanks Ed.
February 22, 2009 - 3:10 pm
Ed – Good suggestion, I already updated the code above to include the subject line. It required changing just a single line in Check #2.
strBody = LCase(Item.Subject) & LCase(Item.Body)
Thanks!
-Carl
April 2, 2009 - 9:15 am
Macro has stopped working. Any updates as to why?
April 4, 2009 - 5:28 pm
Larry – You’ll have to give me a little more to go on. Are you launching the macro from a toolbar button? Do you get any error messages or pop-ups? What OS and what version of Outlook are you using? Do you have other macros that are working?
-Carl
May 18, 2009 - 4:35 pm
Outlook 2007 checks for no location on appointments by default so the macro is redundant. Since the code is well annotated the section can be deleted.
May 18, 2009 - 4:57 pm
Tammy – Good point, thanks for the comment. If you have OL2007, you can just delete the “CHECK #3″ section, everything before the “ExitSub:” line.
-Carl
May 20, 2009 - 4:58 pm
Hi Carl,
I have tried your macro with Outlook 2007 SP2 and it only worked once. After rebooting the PC, the macro stopped working.
I can make the macro work again by deleting the VbaProject.OTM at %appdata%\Microsoft\Outlook and make again the macro, but after rebooting it won’t work any more .
It is only working on the current session. If I restart the PC the macro does not work.
Any idea what’s happening?
Thank you.
May 20, 2009 - 9:04 pm
José – I’m not sure what would cause that, but I don’t have OL2007 so I’m not able to try it. Are you maybe having the issue that Matt described above where the pop-up message is hidden behind other windows?
When you say the macro stopped working, what do you mean exactly? Do you see error messages, or does it just let all messages pass without warning? Do you have other macros that are working, or do all of your macros stop working?
-Carl
May 21, 2009 - 2:35 am
Hi Marc,
No I don’t see any error messages. All messages pass without warnings. I have tried to change the code using the “vbMsgBoxSetForeground” or “vbSystemModal” options but the behaviour is the same.
And no, I don’t have any other macros.
I even have try this on other computer with Outlook 2007 and the behaviour is exactly the same. All messages pass without warnings after rebooting.
Thank for your help.
May 21, 2009 - 7:32 am
Sorry for misspelling your name… not Mark but Carl
May 21, 2009 - 9:03 pm
José -
No problem, people have called me much worse things! A few more things you can try:
[1] It might be related to your macro security setting. Try moving down to medium to see if it fixes the issue. I think that is in “Tools > Trust Center” for OL2007. You have to *completely* shut down Outlook and restart it after changing the security level for it to stay.
If you don’t want to leave the setting at medium, there are instructions here, here, and elsewhere online that show you how to certify your macro so it will run even when the security level is high.
[2] Try running some very basic macros and launching them manually (not automatically). Here is an example:
Sub HelloWorld()
MsgBox “Hola mundo”
End Sub
[3] If that works manually, now try getting it to trigger from the message send event. Note that you can only have one macro with this title in your “ThisOutlookSession” module, so you will have to remove the other one before testing this one:
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
MsgBox “Hola mundo”
End Sub
[4] It shouldn’t matter, but try deleting the “Private” qualifier on the first line of the macro.
Good luck, please post a note here if you figure it out.
-Carl
May 22, 2009 - 7:21 am
Thank you Carl,
You were right! The problem was related to macro security settings.
I have disabled the security selecting the option “No security check for all macros” and it worked.
Then, I have certificate the macro and selected the option “Warnings for signed macros; all unsigned macros disable”. At first Outlook run and first macro warning I choose to trust all macros signed by me. And that’s it, macro is working and no more security warnings.
Thank you for your help.
Regards,
José
June 10, 2009 - 4:40 am
Hi Carl,
Thanks for compiling all of them together in this one.
This looks great.
Suggestions:-
1.Please add ‘ + vbMsgBoxSetForeground’ in your code itself, so that we’ll get the prompt in the foregroud.
2.Please add the steps for signing a macro with selfsign utility.This will avoid the macro security issue.
http://msdn.microsoft.com/en-us/library/aa155754(office.10).aspx
June 14, 2009 - 9:48 pm
Mankidavu – Thanks for your comments… Very good point on signing the macro. I do this on my machine as well to be able to leave the security level in place without getting a bunch of warnings. I recommend that people follow the MSDN link in your comment above and use the instructions there.
Regarding the +vbMsgBoxSetForeground setting, I just updated it for the three checks in the macro. This is based on my comment above from 25 Nov 08, but now it is in the base code. Thanks for the suggestion!
-Carl
July 16, 2009 - 10:56 am
Hey Carl.
Awesome macro, thanks! One issue, it works fine during my session. But when I close Outlook and reopen it, the macro doesn’t work until I actually go into VB and look at it, then it starts working again.
Do you have any idea why this would be?
Thanks in advance.
July 17, 2009 - 1:00 pm
Al – Sounds like it might be related to your macro security settings. See my comment from May 21st, 2009 above and try some of the suggestions there.
-Carl
November 12, 2009 - 5:01 am
I’ve been using this script for some time now. Seems to be working ok, except for one thing: my outlook warns me everytime I send an e-mail that a script is trying to read the e-mailaddresses involved.
I’ve tried the self-signing above; but no improvement there.
Any ideas?
November 12, 2009 - 9:28 pm
Michiel – Assuming the signing of the macro is working, it sounds like it might be an issue with your security level settings. See the comments above on 21-May-09 and 22-May-09. Also see discussion on signing in comments from June 10th & June 14th above.
-Carl