Outlook's Rules and Alerts: Run a Script
http://www.slipstick.com/outlook/rules/outlooks-rules-and-alerts-run-a-script/
Outlook's Rules and Alerts: Run a Script
Last reviewed on December 11, 2014 — 55 Comments
Using the “Rules and Alerts” option to “run a script”, the list of scripts to run is empty. What makes a script appear in the list?
The argument must by type MailItem or MeetingItem for the subroutine to be available in the Rules Wizard in Outlook 2007. In Outlook 2010 and 2013, PostItem also works.
You need to avoid processing messages using more than one rule when you are using a run a script rule. Run a script rules should be placed at the top of the rules list and include the “stop processing” action.
All actions should be in the script – don’t combine actions in the rule with the run a script rule. Include all of the actions you want to take on the items that meet the rule’s conditions in the VBA procedure.
Something like this:
Public Sub ShowMessage(Item As Outlook.MailItem) 'code End Sub |
Using VBA Editor
Open Outlook’s VBA editor by pressing Alt+F11 and expand Microsoft Office Outlook Objects then double click on ThisOutlookSession.
You’ll type or paste the code into the module, then create the rule with the ‘run script’ Action and select this script
Create a Run a Script Rule
After the script is written, you need to add it to a rule.
- Open Rules Wizard. In Outlook 2010 and 2013, it’s on Outlook’s Home ribbon,
Rules > Manage Rules & Alerts. Look on the Tools menu in older versions.
- Click New Rule.
- Select Apply Rule on messages I receive and click Next.
- Select your conditions and click Next.
- Select Run a script action (near the bottom).
- Click on a script.
- Select your script, click OK.
- Click Next then finish the rule.
For best results, all actions should be in the script.
More Information
More Run a Script Samples:
Additional Information:
- How to process incoming messages in Microsoft Outlook (Outlookcode.com)
- How to create a script for the Rules Wizard in Outlook (MSKB)
- Retrieving Internet Headers Using VBA in Outlook 2007/2010 Instructions to send Internet headers to another address
Antonio says
April 18, 2013 at 4:22 am
What about runing scripts for OUTGOING messages? Any solution? Thanks
Diane Poremsky says
April 18, 2013 at 8:58 am
Rules scripts are not an option, you need to use the Send event. See Add attachments and set email fields during a mail merge for a code sample.
Richard says
May 30, 2013 at 6:34 am
Using VBA to save an attachment with the rule wizard
Diane Poremsky says
May 30, 2013 at 9:50 am
use the macro at Save attachments to drive with a run a script rule that calls the macro:
Sub SaveAttachmentsRule(Item As Outlook.MailItem)
SaveAttachments
End Sub
Andy says
August 30, 2013 at 2:07 am
Hi,
I am currently trying to create a script that can be ran as part of rule within Outlook 2013. This will look for a certain subject within the message, then run a script to copy a folder from a server down to my local machine. I believe I have the correct code for this however the script does not appear for selection when creating the rule.
The code reads -
Dim fso As FileSystemObject
Set fso = New FileSystemObject
fso.MoveFolder "Source", "DeStination"
Set fso = Nothing
I have opened VB editor, opened ThisOutlookSession, pasted in the code (with the correct source and destination), then saved the VB project, but this still does not appear for selection. Any help would be greatly appreciated!
Thanks,
Diane Poremsky says
August 31, 2013 at 7:49 pm
So you are basically using a message to trigger an action on your computer?
The VBA should look something like this - assuming your code is valid. It can go in either ThisOutlookSession or a module. The key to using a run a script rule is this part of the procedure name: (Item As Outlook.MailItem)
Public Sub MoveFolder(Item As Outlook.MailItem)
Dim fso As FileSystemObject
Set fso = New FileSystemObject
fso.MoveFolder "Source", "DeStination"
Set fso = Nothing
End Sub
Mark W says
September 5, 2013 at 10:18 pm
I got this to work the first time. It stopped working after I exited Outlook 2013 and went back in. Any ideas?
Diane Poremsky says
September 5, 2013 at 10:43 pm
Check the macro security settings - when this happens it usually means they are not on low.
Mark W says
September 10, 2013 at 2:31 pm
That seems to have fixed it. Thanks!
Al says
November 8, 2013 at 12:35 pm
My rule doesn't trigger my VBA script when an email enters the Inbox. I know my script works because I can run the rule manually.
Diane Poremsky says
November 8, 2013 at 4:17 pm
How does the rule read?
Al says
November 12, 2013 at 2:29 pm
Apply this rule after the message arrives
from xxxxxx
and with xxxxx in the subject
and on this computer only run xxxxxxxxxxxxx
Diane Poremsky says
November 17, 2013 at 10:29 am
It should work. I'd try removing subject from the rule and adding it to the code - or remove the from line and add it to the code.
If instr(lcase(item.subject,"keyword") then
'do whatever
End if
Chris D says
February 18, 2014 at 1:13 pm
Say I want to run my "script", which does subject line checking, on every message that comes in, but also allow additional rules to run on those messages that "fall through" my 'IF' statement in my code?
For example, say I have a mail with the subject "Attachements included" that has attachments I want to save, and another that has the subject "Just Move Me" that I have a rule set for that moves it to a folder. I want the "script" to run on both, but if the subject is "Attachements included", save them (I already have working code for this) and move the message, otherwise, do nothing.
I put my rule to "run a script" as follows:
Apply this rule after the message arrives
on this computer only
run Project1.ThisOutlookSession.stripAttachmentsFromMailItem
and another rule after it that says:
Apply this rule after the message arrives
with "Just Move Me" in the subject
and on this computer only
move it to the "Moved" folder
My question is if I put "Stop processing more rules" in my "run a script" rule, the additional ones never fire, and I lose my move message functionality, unless I want to code in moves for all of my rules (which I really don't... lol).
In small testing, it seems to work fine without it, but the warning above specifically states to not process additional rules on messages that have a "script" run on them. I guess I'm just wondering if my set up will work in the long run. Any advice? :)
Diane Poremsky says
February 19, 2014 at 12:32 am
The stop processing will stop looking for rules that match the current message, if it matched the current rule. You don;'t want to use that if you want all rules to check a message.
As an FYI, the run a script rule should probably be last.
francesca says
February 19, 2014 at 5:02 am
I need to create more projects to manage different rules.
How can i do?
Please help me !
Diane Poremsky says
February 20, 2014 at 1:54 am
You can use multiple macros.
Andrew Jones says
May 28, 2014 at 10:26 am
I just stumbled across this when looking for a solution to our needing to save attachments received from 2 different emails to the same folder. I receive these 2 specific emails from the same source at the same time every morning, but need to run two different versions of a script that saves the attachments. One that renames the attachment from one of the emails, and another that leaves the names alone. I know the code needed for each, but can't seem to figure out how to create a new project to get a 2nd script to appear in the list.
Diane Poremsky says
May 28, 2014 at 10:57 am
Outlook only supports one project. Did you try adding both changes to one script? How are you identifying the messages?
Are you using Rules to identify the messages, save the attachment, and file the message or using an itemadd macro to save the attachment?
One option is an if statement -
if itm.subject = "subject1" then
'do the save
else
'save and rename
end if
Chris D says
February 20, 2014 at 9:45 am
Ahh, good to know. Thank you.
Dallas M says
April 3, 2014 at 12:00 pm
I am trying to change the save destination of the PDF. Where would I replace the folder information?
P.S. I read and use your codes all the time! I have been able to create a few simple ones of my own because of you. Thanks!
Diane Poremsky says
April 3, 2014 at 5:30 pm
Depending on which macro you are using - it maybe be in this line or one similar:
strToSaveAs = MyDocs & "\" & sName & ".pdf"
you can change the path to a fully hardcoded path - like:
strToSaveAs = "C:\Email\" & sName & ".pdf"
Egharevba Osarugue says
April 10, 2014 at 9:41 am
Hello,
I am trying to find a way to accurate delete duplicate mails on outlook, or move them to a folder where i could review it before deleting it. Please could you help with a code that could do that or steps to follow to achieve that?
Diane Poremsky says
April 10, 2014 at 9:59 am
I don't have any samples that do that, but basically you need to compare the sender, recipients, sent date, subject and maybe the body. And you need to test each message against every other message in the folder. I'd check the subject first and if it matches, check the sender and sent date. That should be good enough, since you can't send two messages at the exact same time. But to be sure, you could check the recipients and the message body.
Vaibhav SIngh says
June 19, 2014 at 5:53 am
I am trying to open URL upon arrival of E-mail of a particular subject.
Please help me (Also, I cant see that script when I click on add " SCRIPT")
Diane Poremsky says
June 20, 2014 at 12:28 am
The same url all the time, not one in the message? This page shows how to open a url: http://www.slipstick.com/outlook/tasks/open-webpage-task-reminder-fires/ - put that together with the run a script rule. You could probably forget the script and use the option to run a program, loading the url with a batch file if entering the url as the program name didn't work.
Create the rule looking for the subject,
Public Sub OpenURL(Item As Outlook.MailItem)
Dim strURL As String
Dim oApp As Object
Set oApp = CreateObject("InternetExplorer.Application")
strURL = "http;//www.slipstick.com"
oApp.navigate (strURL)
oApp.Visible = True
'wait for page to load before passing the web URL
Do While oApp.Busy
DoEvents
Loop
End Sub
Meg says
August 22, 2014 at 12:28 pm
Hi, there is no "run script" option for me to choose from. How do I enable it?
Diane Poremsky says
August 22, 2014 at 12:30 pm
The run a script action is missing from the actions list in the rules wizard? What version of Outlook do you use? What type of email account?
Erica says
December 5, 2014 at 10:07 am
Hello,
I have the same problem as Meg. The "Run script" option isn't available. I have Outlook 2010, and I'm trying to set the rule for a MAPI account, but I also have an IMAP/SMTP on the same application. If is not possible to use the run script option, is there any other way? Thank you Diane!
Diane Poremsky says
December 6, 2014 at 9:28 am
The macro script *should* work in thisoutlooksession, but it's best to put it in a new module. And it needs to have the script name line in this format - with Item As Outlook.MailItem:
Sub MacroName(Item As Outlook.MailItem)
Hari Prasad says
November 5, 2014 at 12:31 am
1. We would like to check and append an Identifier to header (and) Or body of incoming mails in a folder something like . How can we do it in scripts?
2. This Number should increment automatically.
Is there a solution?
Any help is appreciated
Diane Poremsky says
November 5, 2014 at 8:30 am
Adding to the internet header is difficult, but you can add a value to the subject or body field or create a custom field for the number. See http://www.slipstick.com/developer/code-samples/create-custom-numbering-field/ for a sample. It needs converted to a run a script rule.
Z Tan says
December 1, 2014 at 4:26 am
I would like to have a script that when I replied the email, the user defined field " Replied" automatically captured the date of the action. Can anyone advise? I need a step by step guide.
Diane Poremsky says
December 5, 2014 at 1:25 am
You don't need a custom field - you need a custom form (cfg)- get the replied to time one from here - http://www.slipstick.com/exchange/adding-extended-mapi-fields-to-outlook/ - and install it.
Jaap Fox says
December 2, 2014 at 12:49 pm
Hi Diane, I am using Outlook 2007 and I would like to use a script rule to move a message that has been sent with a certain subject to another folder 30 seconds or 1 minute after it has been sent. Can you help me out?
Thanks,
Jaap
Diane Poremsky says
December 3, 2014 at 2:01 am
Outlook doesn't include a timer, so it's difficult to do a delayed move. Is there a reason why it needs to be delayed?
Jaap says
December 3, 2014 at 2:35 am
Thanks Diane. We have third-party software that uses via Outlook a certain mailbox (not my own, but I have full access to it) to send emails. I want a copy of the sent item put in the Sent folder of that mailbox using a rule. It does so, but no time of sending mail is shown (where the date and time should be shown it says 'none'). The email in my own Sent folder has all the information so now I still need to manually move that email to the correct Sent folder (of that other mailbox). So somehow I think the rule is carried out before the actual sending of the email. Thanks for your reply.
Diane Poremsky says
December 5, 2014 at 1:29 am
It sounds like its moving a draft message. I have a macro here - http://www.slipstick.com/developer/code-samples/use-a-macro-to-move-imap-account-sent-items/ - that moves sent items after they are dropped in the sent folder. Is the mailbox opened in your profile as a shared mailbox or as a separate account? The macro might need tweaked if it's open as a shared mailbox.
Narendra says
December 5, 2014 at 1:14 am
Hi Diane,
I am actually looking for How to auto forward an email with some added explanation. Can you plz help on this
Diane Poremsky says
December 5, 2014 at 1:30 am
like adding a note to it? See http://www.slipstick.com/outlook/rules/run-script-rule-reply-message/
Jaap says
December 5, 2014 at 6:03 am
Diane, many thanks. I use Exchange 2010 and have -within my own profile jaap@company.com- access to the mailbox of target@company.com. So the emailbox of target@company.com is visible in my left panel in Outlook. The name of that emailbox is 'Target | Company". I know have the following code:
Private WithEvents Items As Outlook.Items
Private Sub Application_Startup()
Set Items = Session.GetDefaultFolder(olFolderSentMail).Items
End Sub
Private Sub Items_ItemAdd(ByVal Item As Object)
If Item.SendUsingAccount = "target@company.com" Then
' Get the GetFolderPath function from http://slipstick.me/getfolderpath
Set Items = GetFolderPath("Target | Company\Sent items").Items
' After adding the function to ThisOutlookSession:
Function GetFolderPath(ByVal FolderPath As String) As Outlook.Folder
Dim oFolder As Outlook.Folder
Dim FoldersArray As Variant
Dim i As Integer
On Error GoTo GetFolderPath_Error
If Left(FolderPath, 2) = "\\" Then
FolderPath = Right(FolderPath, Len(FolderPath) - 2)
End If
'Convert folderpath to array
FoldersArray = Split(FolderPath, "\")
Set oFolder = Application.Session.Folders.Item(FoldersArray(0))
If Not oFolder Is Nothing Then
For i = 1 To UBound(FoldersArray, 1)
Dim SubFolders As Outlook.Folders
Set SubFolders = oFolder.Folders
Set oFolder = SubFolders.Item(FoldersArray(i))
If oFolder Is Nothing Then
Set GetFolderPath = Nothing
End If
Next
End If
'Return the oFolder
Set GetFolderPath = oFolder
Exit Function
GetFolderPath_Error:
Set GetFolderPath = Nothing
Exit Function
End Function
Set MovePst = GetFolderPath("Target | Company\Sent items")
Item.UnRead = False
Item.Move MovePst
End If
End Sub
I tested it, but is does not work yet. What am I doing wrong? Many thanks for your help!
Diane Poremsky says
January 7, 2015 at 1:16 am
This is telling the macro to watch the default sent folder:
Private Sub Application_Startup()
Set Items = Session.GetDefaultFolder(olFolderSentMail).Items
End Sub
And this tells it to watch the Target Company sent folder:
Set Items = GetFolderPath("Target | Company\Sent items").Items
The function goes at the end of the macro, as a separate macro.
You need this + the function:
Private WithEvents Items As Outlook.Items
Private Sub Application_Startup()
Set Items = Session.GetDefaultFolder(olFolderSentMail).Items
End Sub
Private Sub Items_ItemAdd(ByVal Item As Object)
If Item.SendUsingAccount = "target@company.com" Then
' Get the GetFolderPath function from http://slipstick.me/getfolderpath
Set MovePst = GetFolderPath("Target | Company\Sent items")
Item.UnRead = False
Item.Move MovePst
End If
end sub
Jaap says
December 10, 2014 at 11:53 am
Hi Diane, did you find the time to look at my code I sent earlier? I appreciate your help very much. Otherwise do you know the code for this part: Set newCalFolder = NS.GetSharedDefaultFolder(objOwner, olFolderCalendar) but then for a mailbox. SInce this example code (part of GetFolderPath macro regards the calender and my issue regards mailboxes.
Thank in advance,
Jaap
Diane Poremsky says
January 7, 2015 at 1:06 am
No, I hadn't had a chance yet (I took a lot of time off in Dec.) The getfolderpath macro works with any folder type - it just needs to be told the path. It'll work with all mailboxes open in the profile.
Jaap says
January 7, 2015 at 3:38 am
Thank you very much, Diane! Really appreciated.
Ken says
January 30, 2015 at 2:46 pm
Diane, I am attempting to set up this rule but in the rules wizard under select condition(s) there is not an option to "run a script"
Diane Poremsky says
January 30, 2015 at 5:42 pm
What version of Outlook? It should be near the bottom of the list of actions on the Actions page. (like 4th from the bottom)
ken says
January 30, 2015 at 4:02 pm
Diane, it sounds like the same issue as Meg from August 2014 & the other below it. What are you referring to in your comment " macro script *should* work in thisoutlooksession, but it's best to put it in a new module. And it needs to have the script name line in this format - with Item As Outlook.MailItem:
Sub MacroName(Item As Outlook.MailItem)" I don't see another reference to macro script
Diane Poremsky says
January 30, 2015 at 6:12 pm
In order for Outlook to use a macro in a run a script rule, the name of the macro needs to be in this format:
Sub MacroName(Item As Outlook.MailItem)
Macros with names in this format won't be listed when you click on run a script.
Sub MacroName()
I have a ton of macros - but only two can be used in rules:

Ken says
January 31, 2015 at 10:59 am
Hi Diane, It isOutlook 2010 and there is no Run a script in the rules wizard. Not sure what to do.
Diane Poremsky says
February 2, 2015 at 12:25 am
Run a script should be in all copies of Outlook 2010. What type of email account? Are you using a terminal server?
Bryan says
February 4, 2015 at 12:46 pm
Hello I am trying to get outlook to send an email to us if the customer does not recieve a report email that gets sent out daily. The code I have currently only causes a pop up box saying that the email was not found. I need it to email us so that we will know that the customer did not recieve the report. Any ideas? Here is the code I am currently using, thank you.
Private Sub Application_Reminder(ByVal Item As Object)
If Item.Class = olTask Then
If InStr(Item.Subject, "subject") > 0 Then
ReminderUnreceivedMail
End If
End If
End Sub
Sub ReminderUnreceivedMail()
Dim Itms As Items
Dim srchSender As String
Dim srchSubject As String
Set Itms = GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Items
srchSender = "sender"
srchSubject = "xyz"
Set Itms = Itms.Restrict("[SenderName] = 'sender' And [Subject] = 'subject' And [SentOn] > '" & Format(Date, "yyyy-mm-dd") & "'")
If Itms.Count = 0 Then
MsgBox "No " & srchSubject & " email on " & Format(Date, "yyyy-mm-dd")
End If
Set Itms = Nothing
End Sub
Diane Poremsky says
February 8, 2015 at 12:02 pm
In this code block you need to add the code to create a new message or call another macro that creates the message.
If Itms.Count = 0 Then
MsgBox "No " & srchSubject & " email on " & Format(Date, "yyyy-mm-dd")
End If
Dim objMsg As MailItem
Set objMsg = Application.CreateItem(olMailItem)
With objMsg
.To = "Alias@domain.com"
.Body = "Whatever"
.Subject = "This is the subject"
.Display
End With
Set objMsg = Nothing
Agent-311 says
February 20, 2015 at 8:22 pm
I know nothing about VBA other than "Alt + F11" and pasting the code into "Module1"
Current Script that works: Triggered by a Rule & Saves an attachment to a folder
I Need to catch totally different emails using a different Rule and trigger a 2nd script that does the same as the 1st script, but gives the attachment a different file name.
It sounds like I can't setup a 2nd Rule to trigger a 2nd script(?). So, how do I do this?
My Script
Public Sub saveAttachtoDisk(itm As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim saveFolder As String
saveFolder = "https://website.com/folder/"
For Each objAtt In itm.Attachments
objAtt.SaveAsFile saveFolder & "\File Name.txt"
Set objAtt = Nothing
Next
End Sub
Diane Poremsky says
March 21, 2015 at 1:22 am
You can create as many as you need, provided the macro name is different for each.