This new version lets you link a VBA subroutine to a rule

Like any new version of a popular application, Microsoft Outlook 2002 adds some interesting capabilities to the established feature set. Topping the list for programmers are programmable views and searches, new folder properties, and a BeforeDelete event that you can cancel. But in this column, I'd like to highlight a new feature that you won't find in the object browser.

Instead, you'll find this buried treasure in the Rules Wizard. Click Tools, Rules Wizard, and create a new rule that starts from a blank rule and checks new messages as they arrive. After you set one or more conditions, look on the list of actions near the bottom for the run a script action, which Figure 1 shows. The name of the action is misleading because it doesn't run an actual VBScript script. Instead, this type of rule runs code that you create in Outlook 2002 VBA.

The ability to run VBA procedures from Rules Wizard rules is a big advance in end-user customization. To run custom code against incoming items in Outlook 98 and Outlook 97, you must use the Launcher custom action in the Rules Wizard to launch a compiled .exe program. Outlook 2000 provides the Items.ItemAdd event (which I've covered in earlier Outlook VBA on Demand columns) and Application.NewMail event, but you can't depend on either of these events to make your code run against every incoming item.

Procedures that you want to run from the Rules Wizard need to be subroutines that have one argument: a MailItem object variable. You can place these subroutines in the built-in ThisOutlookSession module or in a new module that you create. For easier management, I recommend that you create a new module, name it basMyRules, and place all subroutines for use with the Rules Wizard in that module.

A Practical Application
Let's look at a practical application of a rule that invokes an Outlook VBA script. Say you prefer to not receive or send HTML mail messages. Maybe you're worried that some as-yet-undiscovered vulnerability in Microsoft Internet Explorer (IE)—which provides the components for displaying HTML messages in Outlook—will let a virus enter your system. Or perhaps you just don't like the overhead involved in sending HTML messages, which are larger than plain-text messages, and you don't like having images that contain links to the Internet trigger your dial-up connection. You've already set the default message format to plain text.

The code in Listing 1 provides a subroutine that you can use with a rule to convert all incoming HTML messages to plain text. The BodyFormat property that the ConvertHTMLToDefault subroutine uses is new in Outlook 2002. Earlier versions of Outlook provide no simple way to convert a message to plain text.

To create the rule that uses the subroutine, follow these steps:

  1. Click Tools, Rules Wizard.
  2. In the first Rules Wizard dialog box, click New.
  3. Select Start from a blank rule, then select Check messages when they arrive; click Next.
  4. From the What condition(s) do you want to check? list, select the conditions you want to apply to this rule. If you want to convert all incoming HTML messages to plain text, click Next without setting any conditions and answer Yes when Outlook asks whether you want the rule to apply to every message you receive.
  5. From the What do you want to do with the message? list, select run a script.
  6. In the Rule description box at the bottom of the Rules Wizard dialog box, click the underlined words a script.
  7. In the Select Script dialog box, select Project1.ConvertHTMLToDefault, then click OK.
  8. Click Next and add any exceptions to the rule (e.g., mailing lists that you prefer to receive in HTML format). Click Next again.
  9. Give the rule a name, then click Finish. Click OK to close the Rules Wizard.

Whenever an HTML message arrives, the rule will convert it to plain-text format.

One problem with using the BodyFormat property to force a message to plain text is that the property doesn't handle embedded images well. If an HTML message includes an embedded image, the converted plain-text message doesn't show the image as an attachment, even though a check of the Attachments collection and the file size for the message indicate that the image is still attached. This limitation means not only that you might be missing that great photo from the company picnic but that the 100KB embedded image is taking up space in your mailbox.

To tackle both of these problems, the ConvertHTMLToDefaultWithAtts subroutine in Listing 2 saves any embedded image attachments to the file system, then deletes them from the message. The subroutine's ValidFileName() function ensures that the filename follows Windows rules for filename length and excluded characters. The ConvertHTMLToDefaultWithAtts subroutine builds a list of attached files that the subroutine removes and appends the list to the converted message as clickable hyperlinks so that you can easily open the saved attachments. You can use the techniques in the ConvertHTMLToDefaultWithAtts subroutine to build other VBA rules that handle file attachments.