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
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
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
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
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
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
GoTo ErrorHandle
End If
End If

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

If MsgBox("You forgot your signature!" & vbCr & _
"Do you want to add it first?", vbYesNo _
+ vbExclamation) = vbYes Then
Cancel = True
GoTo ErrorHandle
End If
End If

End If

Set Msg = Nothing
Set objNS = Nothing
Set objFolder = Nothing
Set olApp = Nothing

End Sub


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…

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...
Northern_Dragon 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 to
Pick the virtual directory you want to redirect. e.g. Click HTTP Redirect under IIS in the IIS management console.In the HTTP Redirect Dialog:
Check Redirect requests to this destinationEnter your new path ending with $V$Q.  e.g.$V$QCounter-intuitively check Redirect all request to exact destination (instead of relative destination)Choose the appropriate Status Code (Permanent or Temporary)Apply Changes and Test

Maintaining Cross-Database Referential Integrity

It is often convenient to house your master tables in a separate database from application specific databases so that primary keys are copasetic and multiple databases have access to the same lookups.

Common examples would include employees, counties, regions and other lookup tables.

Once these tables are in a separate database however it is no longer possible to simply drag-and-drop a relationship between them to maintain referential integrity.

Here's a Solution
For this example we'll use an Observation table, tied to a master list of Sex, that's right, Sex (we could call it Gender to be all PC, but these are animals, not Pat in the Personnel Department.)

Step 1:
We create a new view called PIC_Sex in our Application Database by querying the table PIC_Sex in our Master Database:

CREATE VIEW dbo.PIC_Sex AS SELECT SexID, Sex, Rank FROM Master.dbo.PIC_Sex ORDER BY Rank
Yes, that's right, Male and Female! Slugs are awesome.

Step 2:
We create a new user-defined function xdf_Val…

Serving up KML in IIS 6

To serve up KML in IIS 6, you have to add a few MIME Types. The easiest way to do this is to apply new MIME Type settings globally by changing the properties on your server's "Web Sites" folder in IIS.

Google Earth reads KML and KMZ files. The MIME type for KML files is

* application/

The MIME type for KMZ files is

* application/

Source: Google KML Tutorial

To add a MIME type to a Web site or directory

1. In IIS Manager, right-click the Web site or Web site directory for which you want to add a MIME type, and click Properties.

2. Click the HTTP Headers tab.

3. Click MIME Types.

4. Click New.

5. In the Extension box, type the file name extension.

6. In the MIME type box, type a valid MIME type. If you define a MIME type that has already been defined at a higher level, you are prompted to select the level where the MIME type should reside.

To create a MIME type for an undefined MIME type, type an asterisk (*) in the Extension box, an…