An ItemAdd macro watches a specific folder and runs a macro on it as messages are dropped into it, using any method: using rules, dragging messages to the folder, using the move or copy to folder command, or even copy and paste in place.
You can watch any folder that is in your profile using ItemAdd, including share folders; you can watch more than one folder, but you need to identify each folder in the Application_Startup macro.
When you use an Application_Startup macro, you set a variable that Outlook remembers while it's open (one exception: if any macro fails, the variable will be forgotten).
If you need to watch more than one folder, you'll need to use declare another variable name (Private WithEvents... ) and set it in the Application_Startup macro. Each folder will have it's own variable.
Option Explicit Private objNS As Outlook.NameSpace Private WithEvents objItems As Outlook.Items Private Sub Application_Startup() Dim objWatchFolder As Outlook.Folder Set objNS = Application.GetNamespace("MAPI") 'Set the folder and items to watch: Set objWatchFolder = objNS.GetDefaultFolder(olFolderInbox) Set objItems = objWatchFolder.Items Set objWatchFolder = Nothing End Sub
Along with telling Outlook which folder(s) to watch, you need the ItemAdd macro that tells Outlook what do when a new item is dropped in the folder. You'll do this with a macro that has the variable name in it's name: Private Sub objItems.ItemAdd(ByVal Item As Object). If you are watching more than one folder, each folder will have it's own macro.
When the ItemAdd macro fires, you'll refer to the items using the variable set in parenthesis. In this example, it's Item: (ByVal Item As Object).
Private Sub objItems_ItemAdd(ByVal Item As Object) ' Your code goes here MsgBox "Message subject: " & Item.Subject & vbcrlf & "Message sender: " & Item.SenderName &" (" & Item.SenderEmailAddress & ")" Set Item = Nothing End Sub
All of the code used in an ItemAdd macro goes in ThisOutlookSession.
To test your macro without restarting Outlook, place the cursor in the Application_Startup macro and click Run. To test the ItemAdd macro without sending yourself mail, you can select an item, copy and paste in place (Ctrl+C, V). Alternately, you can drag an item from another folder and drop it in the folder you're watching. Eitehr method will trigger the ItemAdd macro.
Watch other folders
You can watch any folder in your profile. The folders in your default data file will use GetDefaultFolder method, including folders you added. If you're watching a folder you added, use this format:
Set objWatchFolder = objNS.GetDefaultFolder(olFolderInbox).Folders("Folder name")
If the folder is in another data file, you'll need to use the GetFolderPath function on "this page" and reference it using the display name in the navigation pane: GetFolderPath("me@domain.com\My Stuff").
Shared Exchange mailboxes will use the GetSharedDefaultFolder method.
See "Working with VBA and non-default Outlook Folders" for help referencing other folders in a macro. There is a list of default folder references on that page, along with the GetFolderPath function and code that uses the GetSharedDefaultFolder method.
If you need to watch two (or more) folders and run the same macro on each, you'll need to set each folder name variable and create an ItemAdd macro. If the macro is short, duplicating the code isn't a big deal, but you can call another macro instead of repeating the same code multiple times.
In this example, I'm watching two folders (set in the Application Startup macro, not shown here) and when a new item arrives, it passes the Item object to another macro to do something.
Private Sub slipstickItems_ItemAdd(ByVal Item As Object) On Error Resume Next SetCategories Item End Sub Private Sub cdoliveInbox_ItemAdd(ByVal Item As Object) On Error Resume Next SetCategories Item End Sub Private Sub SetCategories(ByVal Item As Object) ' do something End if
More Information
- Create Appointment From Email Automatically
- How to Change the Font used for Outlook's RSS Feeds
- How to Process Mail After Business Hours
- Process messages received on a day of the week
- Processing Incoming E-mails with Macros
- Save all incoming messages to the hard drive
- Use VBA to move messages with attachments
Hi Diane, Thanks for the article. I modified it to use on Outlook 2016 Calendar. It worked well when I did ItemAdd (without ItemChange). : However when I added Sub objItems_ItemChange, the VBA would no longer run. Would you know why this is so please? and how to correct the code to have both ItemAdd and ItemChange working at the same time? My desired result is Msg whenever a new appointment is added or an existing appointment is modified. Kindly find below modifcations I made, based on your code: Option Explicit Private objNS As Outlook.NameSpace Private WithEvents objItems As Outlook.Items Private Sub Application_Startup() Dim objWatchFolder As Outlook.Folder Set objNS = Application.GetNamespace("MAPI") 'Set the folder and items to watch: Set objWatchFolder = objNS.GetDefaultFolder(olFolderCalendar) Set objItems = objWatchFolder.Items Set objWatchFolder = Nothing End Sub Private Sub objItems_ItemAdd(ByVal Item As Object) ' Your code goes here ' MsgBox "Message subject: " & Item.Subject & vbCrLf & "Message sender: " & Item.SenderName & " (" & Item.SenderEmailAddress & ")" ' https://www.slipstick.com/developer/itemadd-macro MsgBox "*** PROPERTIES of olFolderCalendar ***" & vbNewLine & _ "Subject: " & Item.Subject & vbNewLine & _ "Start: " & Item.Start & vbNewLine… Read more »
Hi Diane, thank you for this article. It helped me greatly.
Hi,
Great macro! Is there a way to deal with exception situation: "(one exception: if any macro fails, the variable will be forgotten)."
Hi,
I am getting compile error on the following line. It says "Invalid attribute in Sub or Function".
Private WithEvents objItems As Outlook.Items
This is in Outlook in Microsoft 365 Apps for enterprise.
Hello Diane. Great article! I'm trying to run a version of your code. When an e-mail arrives at my defined folder, Outlook search for some specific phrases in the body. If one of them are there, then i run another code to do other stuff. If not, then the macro does nothing. I can't create a rule and use the "execute a script" option because it is not available. Is my work pc and the IT is very annoying with alterating the reg so i don't consider this a possibility. Could you help me out? I've changed the code back to your model and language because my native language is not English so it would be very hard to you read. Option Explicit Private objNS As Outlook.NameSpace Private WithEvents objItems As Outlook.Items Private Sub Application_Startup() Dim objWatchFolder As Outlook.Folder Set objNS = Application.GetNamespace("MAPI") 'Aqui você define qual a pasta que vai rodar esta macro. Set objWatchFolder = objNS.Folders("xxxxxxx@xxxxxx.com").Folders("xxxx1").Folders("xxxx2") 'Eu escolhi ficar de olho em todos os items que chegam na pasta, sem exceção. Set objItems = objWatchFolder.Items '("Resultado do processamento das ORDENS (Upload)") Set objWatchFolder = Nothing End Sub Private Sub objItems_ItemAdd(ByVal Item As Object) 'Inserir o código que você… Read more »
Hi, Thank you very much for posting. I thought I had left this comment yesterday but it seems to have disappeared now. Did I do something wrong? Maybe I just didn’t post it correctly… I’m trying to run a version of your code to watch a particular folder for new items. The problem is that when I try to set my WithEvents variable, it seems to disappear after the Application_Startup sub finishes: it’s empty in in my watch window when I run other subs and the ItemAdd sub I built on it doesn’t fire when an item is added. I know I’ve assigned my variable to the right folder because the correct subject prints from the Debug.Print clntFldrItms.item(1).Subject line. I also know that the Application_Startup sub runs on startup because every time I open Outlook, the VBA editor opens and code has stopped at the Stop command. I’m using Outlook 2016 with an IMAP email address (gmail). All code is in ThisOutlookSession. Code below. Any help you can provide would be really appreciated. Thank you! Peter Option Explicit Public WithEvents clntFldrItms As Outlook.Items Private Sub Application_Startup() Dim clntFldr As MAPIFolder Set clntFldr = Application.Session.GetDefaultFolder(olFolderSentMail).Folders("Client Emails") Set clntFldrItms = clntFldr.Items Debug.Print… Read more »
the previous comment was here - comments are held in moderation queue until I have time to answer them, otherwise they get lost in the mass of comments. (I currently have over 400 comments needing answers - most came in over the Christmas holidays when I took some time off.)
It works here (after fixing the parts wordpress broke & using a valid file path). On the file path, does it end with a slash? If not, it will save in the wrong folder. Rather than debug.print in the startup (or in addition to), add a debug.print before the save to print the full file path.
Debug.Print "C:\Users\Diane\Documents\Test\" & saveName & ".msg"
I would remove the stop -this can cause the app startup to stop working, and will if you don't finish running the code. Use a msgbox to pop up a message if you want to know if it is working.
Great article - I used your code almost unmodified to check when someone changed a shared contact so I could update another system and keep them in-sych. I have one issue though.....
How can I tell if the 'call-back' gets broken? The code seems to work just fine, but the application runs unattended and updates to contacts do not happen so often. After days/weeks, someone will say 'it's not working'. I go in and there are no errors on the screen. Exit Outlook and restart. Everything works again. I am assuming that the call-back is somehow broken, but I'm not sure. How can I test for that?
Thanks!
Russell
I'm not aware of a way to alert you if it's not working - other than something popping up a message box when it runs - but if its unattended, no one will see it. If it hits an error, the macro can quit working but if you use an error handler it should keep on working.
For anyone getting a "Compiler Error: Expected end of statement" error when trying the code above, change the line that says
Private Sub objItems.ItemAdd(ByVal Item As Object)
to
Private Sub objItems_ItemAdd(ByVal Item As Object)
which has an underscore instead of a period. It started working fine for me after that. Great post!
What version of Outlook are you using? It should work with the underscore and not with the dot.