Skip to main content

Attachment Reminder - and more for MS Outlook

I just did it again. We don't like to admit it, but we all have. You write a long letter describing the attachment, press send and then 10 seconds later remember you didn't actually attach the message.

I finally decided to do something about it.

Turns out it isn't too hard. Chiefly because Jimmy Peña at Code for Excel and Outlook already did all the hard work of writing up an excellent MS Outlook Etiquette Check Macro that does all the dirty work for you.

What's left for you to do?
  1. In MS Outlook go to Tools > Macros > Visual Basic Editor
  2. Under the Project Panel (far left) Browse to Project1 > Microsoft Office Outlook Objects > ThisOutlookSession
  3. Double-click ThisOutlookSesson to Open (if you haven't been here before this will be a big blank canvas)
  4. Visit Code for Excel and Outlook Etiquette Check Code and select "Copy to Clipboard" at the top of the code. Or you can also copy from the code I've modified below if you prefer.
  5. Go back to Visual Basic Editor and paste the Code into ThisOutlookSesson
  6. Save and Close
  7. UPDATE Apr 24, 2009 3:56PM: Check your macro security settings:
    • In Outlook 2000 to 2003, choose Tools | Macro | Security and set security to Medium. In Outlook 2007, the macro security settings are in the Tools | Trust Center dialog. Set macro security to Warn on all macros.
    • Restart Outlook.
    • When Outlook re-opens you will see a security warning dialog. Choose "Enable Macros"
    • There is a hack around this we'll leave that for another post

Now just try to be rude. Open a new email message and don't bother with a subject. Press send.


Add "Check out this attachment it'll change your world" to the body and spank send.


Ain't that all kinds of slick? It also will remind you if of missing recipients, blank bodies, signatureless messages, large attachments and too many attachments.

Thanks Jimmy you made my day.

VBA Code
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
'
' code to manipulate emails after hitting 'Send', but just before they are
' actually sent
'

If TypeName(Item) = "MailItem" Then

' we only want to work on messages, not contacts/notes etc

Dim olApp As Outlook.Application
Dim objNS As Outlook.NameSpace
Dim objFolder As Outlook.MAPIFolder
Dim Msg As Outlook.MailItem
Dim sRecip As Outlook.Recipient

Set olApp = Application
Set objNS = olApp.GetNamespace("MAPI")
' set object reference to item passed byval so we can manipulate

Set Msg = Item

' test for missing recipients

If Msg.Recipients.Count = 0 Then
Cancel = True
MsgBox "There are no recipients." & vbCr & _
vbCr & "Please select a recipient and re-send your message.", vbCritical
Msg.Display
GoTo ErrorHandle
End If

' test for invalid subject lines & empty body
Select Case Msg.Subject
Case "", "Re:", "RE:", "FW:"
Cancel = True
MsgBox "You are sending a message without a subject." & vbCr & _
vbCr & "Please correct before sending.", vbCritical
Msg.Display
GoTo ErrorHandle
End Select

If Len(Msg.Body) < 2 Then
Cancel = True
MsgBox "You are sending a message without any body text." & vbCr & _
vbCr & "Please correct before sending.", vbCritical
Msg.Display
GoTo ErrorHandle
End If

' check for too many attachments (or too large), it's rude

If Msg.Attachments.Count > 2 Then
If MsgBox("You are sending more than 2 attachments." & _
"Some people might consider this rude. Continue?", _
vbYesNo + vbInformation) = vbNo Then
Cancel = True
Msg.Display
GoTo ErrorHandle
End If
End If

If (Msg.Attachments.Count > 0) And (Msg.Size > 100000) Then
If MsgBox("Your email is pretty big, do you want to stop " & _
"and zip the attachment(s)?", vbYesNo + vbExclamation) _
= vbYes Then
Cancel = True
Msg.Display
GoTo ErrorHandle
End If
End If

' check for missing attachments

If InStr(LCase(Msg.Body), "attach") And (Msg.Attachments.Count = 0) Then
If MsgBox("An attachment was mentioned, but there is no " & _
"attachment to this email. Send anyway?" _
, vbYesNo + vbExclamation + vbDefaultButton1) = vbNo Then
Cancel = True
Msg.Display
GoTo ErrorHandle
End If
End If

' check for missing signature, it's rude, but allow send anyway

If InStr(Msg.Body, "ENTER PART OF YOUR SIGNATURE HERE") = 0 Then
If MsgBox("You forgot your signature!" & vbCr & _
"Do you want to add it first?", vbYesNo _
+ vbExclamation) = vbYes Then
Cancel = True
Msg.Display
GoTo ErrorHandle
End If
End If

End If

ErrorHandle:
Set Msg = Nothing
Set objNS = Nothing
Set objFolder = Nothing
Set olApp = Nothing

End Sub






Comments

JP said…
Works great doesn't it?
Brent said…
It's something I've ranted about for years, but was never quite important enough to research. Two googles and I had your solution which is all kinds of awesome. Thanks for sharing.
JP said…
Brent,

I've made corrections to the code which I believe address all of your concerns. Let me know if it is correct.
Alex said…
Couple days ago I was at the Inet and saw there countless tools, but one of them attracted my attention, but I couldn't download it. This morning I opened my MS Outlook and was unpleasantly shocked, because my emails had been lost. Luckily for me I remembered about this tool - unable to view all emails in outlook 2003. It assisted me within the scope of minutes and for free...
Unknown said…
I've been using a slightly tweaked version of this for over a year now (thanks!), but bizarrely from this morning it has stopped checking for attachments. Everything else works fine, it just this one vital piece that's broken. Any ideas?

Popular posts from this blog

Simple HTTP Redirect with Querystring in IIS7

HTTP Redirect seems simple enough. Always was in IIS6 and in IIS7 there's even a button labeled HTTP Redirect that promises relative redirects.  It looks like it'll be as easy Apache finally.  That is until you try to redirect a querystring.  Then everything bombs. Turns out it still is relatively easy, except you have to know that Microsoft changed $S$Q to $V$Q. Why? $Ss and $Gs I suspect. And How. In our example we'll redirect all pages under http://olddomain.com/content to http://mydomain.com/content. Pick the virtual directory you want to redirect. e.g. http://olddomain.com/content Click HTTP Redirect under IIS in the IIS management console. In the HTTP Redirect Dialog: Check Redirect requests to this destination Enter your new path ending with $V$Q.  e.g. http://mydomain.com$V$Q Counter-intuitively check Redirect all request to exact destination (instead of relative destination) Choose the appropriate Status Code (Permanent or Temp...

ArcGIS One-to-Many Labeling

ArcGIS is just plain lousy at dealing with any relationship that isn't one-to-one. We all have a slew of hacks just to deal with this limitation. I for one regularly am creating temporary cross-tab queries so I can represent multiple sample results at a collection point, fish surveyed at a cross-section and a host of other relationships. The classic example for mapping comes from the cadastral community and condominium lots. It's an odd situation where more than one person has title to the same piece of ground. How do you represent this? I've got a new trick thanks to Mohammed Hoque's article in ArcUser Magazine. We're going to do a database query inside a label expression, loop through the results and output the entire list to label. For our example we'll use Outfitting Areas in Idaho and we'll label them with the Outfitters and Guide License Numbers and Outfitter Names. 1.) Open ArcGIS and add your spatial layer with the unique identifier shared with...