You can use a Run a Script rule or an ItemAdd macro to look for messages with attachments, then check the file type. If certain file types are found, the macro does something with the message, in the example, the message is moved to a folder.
Use a run a script rule if your mail load is lighter and you want to use the script only on messages meeting certain conditions. Use an ItemAdd macro for heavier mail volumes or when you need to check all messages you receive.
Use a Run a Script rule
To use the run a script rule, create a rule.
Select the has an attachment condition and any other conditions you want to check. The only action will be run a script. Set exceptions as needed.
If you need to do more actions, such as mark the message read, forward a copy, etc, you'll need to add it to the script.
To check additional file types, use 4 characters for the extension name. If the extension is 3 characters, use the leading dot in the Select Case list: docx or .doc
Run a script macros will work in ThisOutlookSession but should be placed in a module.
Sub MoveMail(Item As Outlook.MailItem) If Item.Attachments.Count > 0 Then Dim attCount As Long Dim strFile As String Dim sFileType As String attCount = Item.Attachments.Count For i = attCount To 1 Step -1 strFile = Item.Attachments.Item(i).FileName sFileType = LCase$(Right$(strFile, 4)) Select Case sFileType Case ".pdf", ".doc", "docx" ' do something if the file types are found ' this code moves the message Item.Move (Session.GetDefaultFolder(olFolderInbox).Folders("Move")) ' stop checking if a match is found and exit sub GoTo endsub End Select Next i End If endsub: Set Item = Nothing End Sub
To test a run-a-script macro, you either need to keep sending yourself mail, use Run Rules Now, or use a "stub macro" to trigger the script on the selected message, as macros with parameters in the macro name: (Item As Outlook.MailItem) cannot be run manually.
Sub RunScript() Dim objApp As Outlook.Application Dim objItem As Object ' MailItem Set objApp = Application Set objItem = objApp.ActiveExplorer.Selection.Item(1) 'macro name you want to run goes here YourMacroName objItem End Sub
Use an ItemAdd macro
ItemAdd macros can handle larger volumes of mail and can watch any folder for new items. This macro must be placed in ThisOutlookSession. Click in Application_Startup to test the macro without restarting Outlook.
Option Explicit Private WithEvents olInboxItems As Items Private Sub Application_Startup() Dim objNS As NameSpace Set objNS = Application.Session ' instantiate objects declared WithEvents Set olInboxItems = objNS.GetDefaultFolder(olFolderInbox).Items Set objNS = Nothing End Sub Private Sub olInboxItems_ItemAdd(ByVal Item As Object) On Error Resume Next If Item.Attachments.Count > 0 Then Dim attCount As Long Dim strFile As String Dim sFileType As String Dim i attCount = Item.Attachments.Count For i = attCount To 1 Step -1 strFile = Item.Attachments.Item(i).FileName Debug.Print strFile sFileType = LCase$(Right$(strFile, 4)) Debug.Print sFileType Select Case sFileType Case ".pdf", ".doc", "docx" ' do something if the file types are found ' this code moves the message Item.Move (Session.GetDefaultFolder(olFolderInbox).Folders("Move")) Exit Sub End Select Next i End If End Sub
How to use these macros
First: You need to have macro security set to low during testing. The macros will not work otherwise.
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.
Some macros need to be in ThisOutlookSession, others go into a module or can be placed in either ThisOutlookSession or a module. The instructions are below.
Open the VBA Editor by pressing Alt+F11 on your keyboard.
If you are told to put the code in a module:
- Right click on Project1 and choose Insert > Module
- Copy and paste the macro into the new module.
If you are told to put 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
More Information
- Autoaccept a Meeting Request using Rules
- Automatically Add a Category to Accepted Meetings
- Blocking Mail From New Top-Level Domains
- Convert RTF Messages to Plain Text Format
- Create a rule to delete mail after a number of days
- Create a Task from an Email using a Rule
- Create an Outlook Appointment from a Message
- Create Appointment From Email Automatically
- Delegates, Meeting Requests, and Rules
- Delete attachments from messages
- Forward meeting details to another address
- How to Change the Font used for Outlook's RSS Feeds
- How to Process Mail After Business Hours
- Keep Canceled Meetings on Outlook's Calendar
- Macro to Print Outlook email attachments as they arrive
- Move messages CC'd to an address
- Open All Hyperlinks in an Outlook Email Message
- Outlook AutoReplies: One Script, Many Responses
- Outlook's Rules and Alerts: Run a Script
- Process messages received on a day of the week
- Read Outlook Messages using Plain Text
- Receive a Reminder When a Message Doesn't Arrive?
- Run a script rule: Autoreply using a template
- Run a script rule: Reply to a message
- Run a Script Rule: Send a New Message when a Message Arrives
- Run Rules Now using a Macro
- Run-a-Script Rules Missing in Outlook
- Save all incoming messages to the hard drive
- Save and Rename Outlook Email Attachments
- Save Attachments to the Hard Drive
- Save Outlook Email as a PDF
- Sort messages by Sender domain
- Talking Reminders
- To create a rule with wildcards
- Use a Macro to Copy Data in an Email to Excel
- Use a Rule to delete older messages as new ones arrive
- Use a run a script rule to mark messages read
- Use VBA to move messages with attachments
Hi, I have a particular software that is picking up emails from my inbox. The scenario I have is that on some occasions, there are senders that add an email as an attachment (to the email they are sending to me), and it throws this other software on this endless loop because it cannot open the email attachments. I am wondering if you can guide me on moving the email with the email attachment to a folder let's say called "Exceptions"
I should clarify. the macro can't be selected from the Run menu in the VBA editor (to test) and when added to a rule it doesn't seem to actually move the emails
You need to use a "stub macro" to trigger the rules macro - they can't be run on their own.
How would i go about fixing these?
some time in the recent past macros with subs that contain parameters stopped being runable / selectable...
https://stackoverflow.com/questions/45922417/macros-not-showing-up-in-the-run-macro-menu
ItemAdd script works well! I've been able to move all emails with excel files attached to their own folder. What's the flag for follow up script and where would I add it to the ItemAdd script above?
Sorry I missed this earlier. If you want to flag messages you move, before the move line, add this block, changing the values as needed:
With item
.MarkAsTask olMarkThisWeek
' sets a specific due date
.TaskDueDate = Now + 3
.ReminderSet = True
.ReminderTime = Now + 2
.Save
end with
https://www.slipstick.com/developer/code-samples/set-flag-follow-up-using-vba/
Will this script work for encrypted email?
I don't think so... I think it will see the encryption content as an attachment and apply to all messages.
Hi Diane
I have six rules that run six different scripts to copy attachments from emails to a unique folder based on the name of the rule. Basically all the scripts are the same except for the folder name the attachment gets copied, the folder name is the same name as the rule.
I want to have just one script and all the rules run it. I want the string value for the folder name to be the name of the rule that triggered it.
I cannot get the name of the rule that triggered the script. How do I get the name of the rule that triggered the script ?
Your help will be appreciated
is there anything in the emails that can be used to filter on? The other option is to use stub macros - the rule calls a macro, that macro sets the folder and pushes the value to the main macro that does the work.
if there is something in the messages that can trigger the folder, you could use one rule and one script.
' this is called by the rule and pushes the message to another macro
Sub MoveStuff(Item As Outlook.MailItem)
Set myFolder = [folder]
MoveMail Item
End Sub
Private Sub MoveMail(Item As Outlook.MailItem)
' all the move stuff here
' using myFolder object
End Sub
How do you move the an email with certain attachments to a new folder but skip the attachment next to the signature?
In your example I add
If Item.Attachments.Item(i).Size < 5200 Then
GoTo nexti
End If
After the case line so it would look past the attachment in the signature line. Problem is that this is not working. It will move the emails correctly but if there is an attachment in the signature line it moves this too. Any help on this would be appreciated.
Are the attachments in the signature all images?> Are the attachments you need to move images? The problem is likely the size if the image in the signature - this is looking for 5KB attachments. If you are moving other files types, use the case statement to look only for that file type.
yes. It still isn't working.
Here is what I have:
Sub MoveMail(Item As Outlook.MailItem)
If Item.Attachments.Count > 0 Then
Dim attCount As Long
Dim strFile As String
Dim sFileType As String
attCount = Item.Attachments.Count
For i = attCount To 1 Step -1
strFile = Item.Attachments.Item(i).FileName
sFileType = LCase$(Right$(strFile, 4))
Select Case sFileType
Case ".zip", ".jpg", ".gif"
If Item.Attachments.Item(i).Size < 9900 Then
GoTo nexti
End If
End Select
' do something if the file types are found
' this code moves the message
Item.Move (Session.GetDefaultFolder(olFolderInbox).Folders("Exception Attachments"))
' stop checking if a match is found and exit sub
GoTo endsub
nexti:
Next i
End If
endsub:
Set Item = Nothing
End Sub
so its still saving gif & jpg files if they are under ~9 KB? Do they have 'normal' file names or something you can filter on, like image00* ?
It filters pdf's too. is my logic correct?
the macro should apply to pdf's - you are only filtering for attachments under approx. 8 KB.
Case ".zip", ".jpg", ".gif"
If Item.Attachments.Item(i).Size < 9900 Then GoTo nexti End Ifit should work - if those types are small files, it goes to the next attachment. if any other file is found, or those files are larger, it moves and quits. Item.Move (Session.GetDefaultFolder(olFolderInbox).Folders("Exception Attachments")) ' stop checking if a match is found and exit sub GoTo endsub
No, They will be different since this rule is for a mailbox that gets mail from all sorts of different customers.
I fixed this but and it seems to be working but know it applies the rule to pdf's. Not sure why this is. Any ideas?
I've upgraded to Outlook 2013 and the VB doesn't seem to recognize that there is an attachment, so the VB fails. Anyone else run into this?
Any error messages? Are you using 32 or 64 Bit Outlook? Is the macro running at all?
(Most of the macros on the site were tested in 2013 or 2016.)