More Outlook Resource Sites

Microsoft Developer Network (MSDN)

FAQs and other general resources

How to process incoming messages in Microsoft Outlook

While Outlook has a feature to allow all messages to be received and sent in plain text format, sometimes you might want to convert only selected incoming messages to plain text. Such a conversion also makes a useful demonstration for three different VBA approaches for processing incoming messages:

  • Using an Outlook rule
  • Using the Items.ItemAdd event on a specific folder
  • Using the NewMailEx event
Method 1: Using an Outlook rule

Starting with Outlook 2002, you can call a VBA subroutine from a Rules Wizard rule using the "run a script" rule action. This action calls not a "script" but a VBA procedure. The procedure can be in either the built-in ThisOutlookSession module or any regular (not class) code module. It must include either a MailItem or MeetingItem argument. This short example converts all incoming messages that meet the conditions for the rule to plain text by changing the value of the BodyFormat property:


A "run a script" rule is not a good choice for heavy traffic applications, as Outlook is likely to skip applying the rule if too many items arrive that meet the rule's conditions. 

To avoid security prompts when accessing properties like Body and Recipients, you must use the technique above to get the item indirectly, through its EntryID property and the Namespace.GetItemFromID method (or Application.Session object). If you attempt to access MyMail.Body or MyMail.SenderName, for example (MyMail being the name of the parameter for the "run a script" rule procedure), you will get a security prompt.

Generally, items that you want to process by a "run a script" rule should not be processed by other rules or other actions in the same rule. Put that rule high on the list, and include the "stop processing" action. Include in your VBA procedure all the actions you want to take on the items that meet the rule's conditions.

WARNING: I have seen cases where a machine running "run a script" rules completely loses the VbaProject.otm file that contains all the Outlook VBA code. If you use "run a script" rules, be sure to back up VbaProject.otm regularly or export the individual modules.

Method 2: Using the Items.ItemAdd event

This approach uses the ItemAdd event to convert all items arriving in the Inbox to plain text format. It needs to run in the built-in ThisOutlookSession module in Outlook VBA.


This sample monitors only the Inbox folder. You could do much the same thing with other folders by adding code to do the following:

  • Declare an Items collection object for each folder WithEvents
  • Instantiate each Items collection object in the Application_Startup event handler
  • Add an ItemAdd event handler for each Items collection object

If the folder you want to monitor is a default folder, you can use the Namespace.GetDefaultFolder method to return it as a MAPIFolder object (Folder in Outlook 2007). To monitor a default folder in another person's Exchange mailbox, use Namespace.GetSharedDefaultFolder to get the MAPIFolder or Folder. Otherwise, you can use my GetFolder() function to walk the folder hierarchy and return the MAPIFolder or Folder corresponding to a given path string.

The Items.ItemAdd method will not fire if more than 16 items arrive in a folder at one time.

Method 3: Using the NewMailEx event

The NewMailEx event fires for messages arriving on any email account. Unexpectedly, for messages arriving from an Exchange account, the NewMailEx event returns only one EntryID value each time it fires.

For a POP3 account running under a very heavy load, it may skip a few items, but still is more reliable than Items.ItemAdd.  If it is absolutely critical that you process all incoming items, it would be a good idea to supplement NewMailEx with a timer-based routine that checks periodically for unprocessed messages.


Changing a message from HTML to plain text makes any embedded image attachments inaccessible from the user interface. They are still stored in the message, however, and can be accessed via code.

The Application.NewMail event is not very useful in processing new mail, as it tells you only that messages have arrived -- not which ones nor which folder(s) they might be in.