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.

Script in the VBA Editor

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.

  1. 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.
  2. Open Rules Wizard

  3. Click New Rule.
  4. Select Apply Rule on messages I receive and click Next.
  5. Select your conditions and click Next.
  6. Select Run a script action (near the bottom).
  7. Click on a script.
  8. Select your script, click OK.
  9. The finished run a script rule

  10. Click Next then finish the rule.
  11. Select the script

For best results, all actions should be in the script.

More Information

More Run a Script Samples:

Additional Information:

Comments

  1. Andy says

    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

      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

  2. Al says

    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.

  3. Al says

    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

      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

  4. Chris D says

    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

      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.

    • Andrew Jones says

      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

      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

  5. Dallas M says

    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

      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"

  6. Egharevba Osarugue says

    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

      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.

  7. Vaibhav SIngh says

    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

      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

    • Diane Poremsky says

      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

      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

      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)

  8. Hari Prasad says

    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

  9. Z Tan says

    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.

  10. Jaap Fox says

    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

      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?

  11. Jaap says

    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.

  12. Narendra says

    Hi Diane,

    I am actually looking for How to auto forward an email with some added explanation. Can you plz help on this

  13. Jaap says

    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 PoremskyDiane Poremsky says

      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

  14. Jaap says

    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 PoremskyDiane Poremsky says

      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.

  15. Ken says

    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 PoremskyDiane Poremsky says

      What version of Outlook? It should be near the bottom of the list of actions on the Actions page. (like 4th from the bottom)

  16. ken says

    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 PoremskyDiane Poremsky says

      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:
      Run a script

    • Diane PoremskyDiane Poremsky says

      Run a script should be in all copies of Outlook 2010. What type of email account? Are you using a terminal server?

  17. Bryan says

    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 PoremskyDiane Poremsky says

      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

  18. Agent-311 says

    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 PoremskyDiane Poremsky says

      You can create as many as you need, provided the macro name is different for each.

Leave a Reply

Please post long or more complicated questions at OutlookForums by Slipstick.com.

If the Post Comment button disappears, press your Tab key.