While a warning dialog is built into Outlook 2013 and above, you need to use VBA or an add-in with older versions of Outlook to check for keywords which may indicate you planned to include an attachment.
For warnings before sending a message with a blank subject, see the following articles:
Outlook 2007 and earlier Outlook 2010 and above
Outlook 2013 and above
An attachment warning feature is built into Outlook, beginning with Outlook 2013. If you don't want the warning, you can disable it by checking the "Do not show... " box in the warning.
If you change your mind, you can turn it back on in File, Options, Mail. The option to warn before sending a message that may be missing an attachment is in the Send Messages section about halfway down.
VBA for Outlook 2010 and older
When you use Outlook 2010 and older, you need to use VBA or an add-in to warn about missing attachments.
The following macro needs to go in ThisOutlookSession and runs when the message is sent. If it finds the word "attach" in the message body, it triggers a warning dialog.
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean) If InStr(1, Item.Body, "attach", vbTextCompare) > 0 Then If Item.Attachments.Count = 0 Then answer = MsgBox("There's no attachment, send anyway?", vbYesNo) If answer = vbNo Then Cancel = True End If End If End Sub
Skip attachments in signatures
If you have an image in your signature, it will be detected as a an attachment and pass the Attachment check. To avoid that problem, check for attachment size. You'll need to loop through all attachments on the message and skip over the attachments that are smaller than a specific size. In my example, I'm looking for attachments over approximately 5 KB. If your signature has larger images, you'll need to increase the attachment size you check for.
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean) If InStr(1, Item.Body, "attach", vbTextCompare) > 0 Then If Item.Attachments.Count = 0 Then answer = MsgBox("There's no attachment, send anyway?", vbYesNo) If answer = vbNo Then Cancel = True End If If Item.Attachments.Count > 0 Then For Each oAtt In Item.Attachments Debug.Print oAtt.Size If oAtt.Size < 5200 Then GoTo NextAtt Else answer = MsgBox("There's no attachment, send anyway?", vbYesNo) If answer = vbNo Then Cancel = True End If NextAtt: Next oAtt End If End If End Sub
Check for attachment name in subject
We had an Outlook user sending wrong file (attachment) to wrong recipients. We created a template for each client that contains a unique Client number and the attachment filename always starts with the unique client number. By validating the subject line with the file name we can warn user the client number doesn't match so they can check before sending out the email.
This code checks the first 15 characters of the attachment filename against the first 15 characters of the subject.
By changing the If statement you could check other values.
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean) Dim objAttachments As Outlook.Attachments Dim strAttachment As String Set objAttachments = Item.Attachments strAttachment = objAttachments.Item(1).FileName If Left(strAttachment, 15) = Left(Item.Subject, 15) Then Else prompt$ = "You sending " & strAttachment & ". Are you sure you want to send it?" If MsgBox(prompt$, vbYesNo + vbQuestion + vbMsgBoxSetForeground, "Check Sending Account") = vbNo Then Cancel = True End If End If End Sub
Combine Two ItemSend macros
If you want to use two ItemSend macros to check outgoing mail, you need to combine them into one. This example combines the "blank subject warning" and missing attachment macros.
We could do a better job of merging them into one macro, with one dialog box, but it will work simply by combing the two like this.
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean) Dim strSubject As String strSubject = Item.Subject If Len(Trim(strSubject)) = 0 Then Prompt$ = "Subject is Empty. Are you sure you want to send the Mail?" If MsgBox(Prompt$, vbYesNo + vbQuestion + vbMsgBoxSetForeground, "Check for Subject") = vbNo Then Cancel = True End If End If If InStr(1, Item.Body, "attach", vbTextCompare) > 0 Then If Item.Attachments.Count = 0 Then answer = MsgBox("There's no attachment, send anyway?", vbYesNo) If answer = vbNo Then Cancel = True End If End If End Sub
First: You will need macro security set to low during testing.
To check your macro security in Outlook 2010 or 2013, go to File, Options, Trust Center and open Trust Center Settings, and change the Macro Settings. In Outlook 2007 and older, it’s at Tools, Macro Security.
After you test the macro and see that it works, you can either leave macro security set to low or sign the macro.
Open the VBA Editor by pressing Alt+F11 on your keyboard.
To use the macro code in ThisOutlookSession:
- Expand Project1 and double click on ThisOutlookSession.
- Copy then paste the macro into ThisOutlookSession. (Click within the code, Select All using Ctrl+A, Ctrl+C to copy, Ctrl+V to paste.)
More information as well as screenshots are at How to use the VBA Editor
Your VBA works great. I would also like to test for any links. Instead of attaching documents I link many documents to coworkers. I tried to modify the code to find "linked" and to see if any documents a linked. But I have not had luck. Can you Help?
you can search for the word linked and https addresses. Not tested, but something like this:
If InStr(1, Item.Body, "linked", vbTextCompare) > 0 Then
If InStr(1, Item.Body, "http", vbTextCompare) = 0 Then
' link is missing
Only issue is that it will find http is signature links.
Thanks for your speedy reply. Interestingly "Linked" works for finding a name in the item.body. I have a link to my email address in my signature, so if I use: If InStr(1, Item.Body, "link", vbTextCompare)>0 , it will always be true even if the word "link" is nowhere in the item.body. That might be a good hint of how to find links although I have not had success yet working with properties. If I take the link out of my signature, then it will look for the word in the item. body. Although I would rather it use "link", I am okay with using "linked" which seems to work.
What does not seem to work is the "http" part. It seems to not find it in a link. I also often insert Excel spreadsheets, Word documents, and PDF files as hyperlinks. I was willing to add ".xls", ".doc", and "pdf" but it will not find those in the links either.
I link more things to my coworkers than I attach because my files often are huge. Please continue to help as I cannot find anywhere else about checking for links in an email. Thanks.
Oops... use item.htmlbody instead of item.body to see the underlying html code when you use a friendly hyperlink in the message.
I found the answer to the problem:
Hyperlinked documents in Item.Body always start with "HYPERLINK" so you can search for that. The web links, you can search for "http" like you suggested. The below will work for the link then. It changes the HYPERLINK to blank so that it will look only for the word link, and then it will look for hyperlinks for a message box:
If InStr(1, Replace(Item.Body, "HYPERLINK", "", , , vbBinaryCompare), "link", vbTextCompare) > 0 Then
If InStr(1, Item.Body, "http", vbTextCompare) + InStr(1, Item.Body, "HYPERLINK ""file:///", vbTextCompare) = 0 Then
vbMBR = MsgBox("There is no link, send anyway?", vbYesNo)
Cancel = vbMBR = vbNo
End If
End If
The code initially worked but I haven't been able to get it working again since.
I'm working on outlook 2007
I tried changing the macro security setting to 'Warnings for all Macros' and No security check for macros' and it still doesn't work.
This is the code I am using is copied from above, is there something I am missing?
Thanks for your help!!
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
If InStr(1, Item.Body, "attach", vbTextCompare) > 0 Then
If Item.Attachments.Count = 0 Then
answer = MsgBox("There's no attachment, send anyway?", vbYesNo)
If answer = vbNo Then Cancel = True
End If
If Item.Attachments.Count > 0 Then
For Each oAtt In Item.Attachments
Debug.Print oAtt.Size
If oAtt.Size < 5200 Then
GoTo NextAtt
Else
answer = MsgBox("There's no attachment, send anyway?", vbYesNo)
If answer = vbNo Then Cancel = True
End If
NextAtt:
Next oAtt
End If
End If
End Sub
i'm assuming if it worked once, that you have it in thisoutlooksession.
Add msgbox "working" to the top, before the IF lines - does the message box come up when you send?
How could this reminder be invoked for Office 2013+, from code, eg from Dephi or C#.Net?
Are you creating an addin? To use either, you'll need to create an addin.
This is not working for me though I have changed the Macro settings as suggested.
Did you put the macro in ThisOutlookSession? (Automatic macros need to be in thisoutlooksession).
Did you restart outlook? it's not need for the ItemSend macro, unless you changes the security settings after adding the macro.
After this line:
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
add this:
msgbox "ItemSend macro running"
and send a message. Does the message box come up?
Hi, I used the code shown below (as per your example) to check for attachments. I made only one change and that was the Attachments Count from 0 to 1 (because our emails always contain our logo which would, presumably, be detected as an attachment). It works - but it works on ALL emails when I press the Send button regardless of whether the word "attach" is in the body of the email or not!
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
If InStr(1, Item.Body, "attach", vbTextCompare) > 0 Then
If Item.Attachments.Count = 1 Then
answer = MsgBox("There is no attachment. Send anyway?", vbYesNo)
If answer = vbNo Then Cancel = True
End If
End If
End Sub
Any idea where I am going wrong?
Thanks in advance,
it looks good...and is working here. Is there anything in the signature that contains 'attach'? It will pick up 'attach' anywhere in the message or url - if there is a word that ends in attach, it would trigger on it.
Did you test it with a sample signature that only has the logo in it?
I cannot get this to work at all when i have a Signature with image. Any ideas ?
you'll need to use an if statement to ignore attachments under a certain size.
Hi, but doesn't it ignore the small attachments and when it finally finds a bigger one then it shows the programmed message? I found that this macro works exactly in the opposite way. Any thoughts on that?
I don't understand. I have copied & pasted the text for the check missing attachments into my "ThisOutlookSession" VBA window, and it worked at first but now has stopped working. Is there a chance I have messed up a setting, or what?
did you change the macro security setting? that is the usual reason why macros don't work after you restart outlook.
I am having the same problem. The attachment notification worked at first but nothing is working now after restarting outlook. My macro security settings are set at 'Notification for digitally signed macros, all other macros disabled'. Thanks is advance.
This is very useful.