Chapter 24. Understanding the Outlook Object Model

IN THIS CHAPTER

  • About the Outlook Object Model

  • Creating object references

  • The Object Model hierarchy

  • Referencing Outlook folders

  • Programming email items

  • Programming calendar items

In order to program Outlook with macros, it is necessary to have some understanding of the Outlook Object Model. Though this may sound intimidating, it is actually a great help to the macro programmer and makes your job much easier.

This chapter gives you an overview of programming the Outlook Object Model and presents numerous examples. The focus is on programming mail items and calendar items because it is these two aspects of Outlook that benefit the most from macro programming. The next chapter develops a few of the programming concepts presented here into full VBA applications you can use or modify.

Understanding Office Objects

All Office programs operate on the principle of objects. This means that internally, all the various components of the program are represented by their own kind of object. In Word, for example, a paragraph is an object, a table is an object, and an entire document is an object. In Excel, a worksheet is an object, and charts and cells are objects, too. Outlook works the same way.

From the perspective of the end user, the fact that a program is structured as objects does not make any practical difference. For the macro programmer, however, it makes a world of difference because all the objects are available for you to use in your macros. Each type of object has a great deal of functionality built in, and that functionality is all ready for you to use with very little programming effort. To be an effective macro programmer, therefore, you need to know about the Outlook Object Model.

Creating Object References

Before you can work with an object in your VBA code, you must have a reference to it. A reference is simply a variable name. Instead of holding data, however, an object reference lets you work with an object in your code.

There are two parts to obtaining an object reference. First, you must create a variable that is of the proper type to hold a reference to the specific kind of object you are dealing with. The preferred way to do this is as follows:

Din RefName As type

This looks like a regular Dim statement for declaring a variable—and in fact, it is the same except that type refers to the specific type of object and not to a data type. For example, in the Outlook Object Model the object type MailItem represents an email message. To declare a variable that can reference a message, you would write the following:

Dim MyMessage As Outlook.MailItem

Note that the Outlook prefix to the object name is used to ensure that you are referencing the Outlook Object Model, because some object names are duplicated between programs.

At this point you have a name that can refer to the specified type of object—Outlook.MailItem in this case—but it does not yet refer to an actual object. Your next step will take one of two paths depending on your needs.

First, you can create a new object of the specified type and set the variable name to refer to it. You do this with the Set and New keywords:

Set RefName = New type

However, this technique cannot be used with many kinds of objects, including MailItem. Rather, you must get a reference to an instance of the object using the Outlook Object Model. For example, you cannot create a new MailItem object with the following code:

Set MyMessage = New Outlook.MailItem

You see exactly how to create references to Outlook objects throughout the chapter.

Working with Collections

Collections are an important part of Outlook macro programming. Whenever the Object Model requires more than one of something, it uses a collection to keep track of them. For example, in Outlook each mail folder, such as the Inbox, is represented by an object. A folder can contain any number of email messages, and these messages are represented as a collection. Collections are designed with built-in tools that make is easy to find an individual object in the collection or to do something with all of the objects in the collection. Every collection has the Count property, which tells you the number of elements in the collection.

The most common use for collections is when you want to process every item in the collection. For example, suppose you want to write a macro that looks at every email message in the Inbox and moves those messages from a certain sender to another folder. By looping through the collection of email messages in this folder, the task is easily accomplished no matter how many or few messages there are in the folder. You use the For Each...Next loop, introduced in Chapter 23, for this purpose.

First, you must declare an object variable of the same type as the objects in the collection. Continuing with the email example:

Dim msg As Outlook.MailItem

Then create a reference to the object that contains the collection—in this case, an Outlook folder—specifically, the Inbox:

Dim f As Outlook.Folder
Dim MyOutlookNamespace As Outlook.NameSpace
Set MyOutlookNameSpace = GetNameSpace("MAPI")
Set f = MyOutlookNameSpace.GetDefaultFolder(olFolderInbox)

Finally, loop through the collection as follows:

For Each msg in f.Items
  ' With each repetition of the loop, msg refers to the   ' next
message in the collection.
Next

The previous code examples are missing a couple of details and will not actually run, but they serve to illustrate the principle of collections. You'll note that this is one of those exceptions where a collection—Items in this case—is not named as the plural of the kind of object it contains, MailItems.

Using Named Constants

If you examine the previous code snippet, you'll see this line of code:

Set f = GetDefaultFolder(olFolderInbox)

What is olFolderInbox? It's not a variable that you have declared. Rather it's one of the named constants in the Object Model. Some methods (a procedure that is part of an object) require an argument to tell them what to do. Rather than use hard-to-remember numbers, the Object Model provides these descriptive constants that are a lot easier to remember. What's more, the VBA Editor's IntelliSense feature will list the available constants as you are typing in your code, as shown in Figure 24.1.

The editor's IntelliSense feature lets you select from a list of named constants.

Figure 24.1. The editor's IntelliSense feature lets you select from a list of named constants.

The Outlook Object Model Hierarchy

The Object Models for all Office applications are arranged in a hierarchical structure. Two of the top-level objects in this arrangement are Application and Namespace.

The Application Object

At the very top of the Outlook Object Model is the Application object. As you might have already guessed, this object represents the Outlook application itself. All other objects in the hierarchy are subsidiary to the Application object. Often, when you are trying to locate data in Outlook, you start with the Application object and work down to levels of greater detail.

The Application object is available as an implicit reference for VBA code in Outlook. This means that you do not have to use the term in your code—it is understood automatically. If you were writing VBA code to run in another Office application, such as Word, you would have to explicitly reference the Outlook Application object.

For example, the GetNamespace() method is part of the Outlook Application object. Full syntax for this would be

Application.GetNamespace()

but because of the implicit availability of the Application reference, you can write it like this:

GetNamespace()

The Namespace Object

Another high-level object in the Outlook Object Model is the Namespace object. It exists because Outlook was designed to be usable with different kinds of data, each of which would be identified by its own namespace. So far, only one kind of data is supported in Outlook, MAPI data (MAPI stands for Messaging Application Programming Interface). Therefore there is only one namespace. Though it seems like unnecessary effort, you must use this namespace when accessing email and other items in Outlook. In many of the code examples in this and later chapters, you'll see a few lines of code like this:

Dim MyOutlookNamespace As Outlook.Namespace
Set MyOutlookNamespace = GetNamespace("MAPI")

Then, the Namespace object is used when accessing mail and other folders:

Set f = MyOutlookNS.GetDefaultFolder(olFolderInbox)

Getting References to Outlook Folders

Outlook items are all stored in folders, and before you can work with items you need to get a reference to the containing folder. Outlook has two types of folders: the default folders and user-created folders.

Referencing Default Folders

A default folder is one of the folders that is part of Outlook and cannot be deleted, such as the Inbox, the Deleted Items folder, and the Notes folder. To get a reference to one of these folders, which are represented by the Folder object, you use the GetDefaultFolder() method. This method takes one argument that specifies the folder you are interested in:

Dim folder As Outlook.Folder
Set folder = MyOutlookNamespace.GetDefaultFolder(foldertype)

The foldertype argument can be one of the named constants listed in Table 24.1, along with the folder each returns. This table lists only those constants used frequently; you can refer to online help for the complete list.

Table 24.1. Constants for the GetDefaultFolder Method's foldertype Argument

Constant

Folder Containing

olFolderCalendar

Calendar items

olFolderContacts

Contacts

olFolderDeletedItems

Items that have been deleted

olFolderDrafts

Drafts of incompleted items

olFolderInbox

Received email messages

olFolderJournal

Journal entries

olFolderNotes

Note entries

olFolderOutbox

Email messages waiting to be sent

olFolderSentMail

Email messages that have been sent

olFolderTasks

Task entries

Referencing User-Created Folders

Folders that the user has created are not default Outlook folders and references to them are obtained from the Folders collection. Because folders can themselves be organized in a hierarchy, things are arranged as follows:

  • Each top-level folder is a member of the NameSpace object's Folders collection.

  • Each of these top-level folders has its own Folders collection, which contains any subfolders that the folder contains.

  • Each folder in turn has its own Folders collection.

User-created folders are identified by name, which is obtained from the Folder object's name property. To get a reference to a folder, assuming that you do not know exactly where it is located, you must look through all folders until you either find it or run out of places to look. This technique can locate the default folders as well, based on their name, but the technique using the GetDefaultFolder() method, described in the previous section, is easier to use.

In the folder hierarchy, what the user considers a top-level folder is in fact a second-level folder. Thus, for example, in the folder structure shown in Figure 24.2, Clients is considered a second-level folder and Acme, Consolidated, and National are third-level folders. The top-level folders are Personal Folders, Archive Folders, Internet Calendar, and similar items.

To get a reference to a specific folder, you can use the function in Listing 24.1. This function is passed the name of the desired folder and returns a reference to the desired folder, if it exists, or else the value Nothing. Be aware that folder names in Outlook are case-sensitive. If the folder does not exist, the value Nothing is returned. You can check for the Nothing value using Is Nothing as explained earlier in this chapter.

This function looks at second- and third-level folders but does not go any deeper. Thus, looking at the folder structure in Figure 24.2 the function would find Clients, and it would find Acme, Consolidated, and National, but it would not find any folders nested deeper than that. It could easily be modified to do so, however, and that would be a good programming exercise for you.

Understanding Outlook folder levels.

Figure 24.2. Understanding Outlook folder levels.

Example 24.1. A Function to Obtain a Reference to a User-Created Folder

Public Function FindFolder(FolderName As String) _
    As Outlook.Folder

Dim folder1 As Outlook.Folder
Dim folder2 As Outlook.Folder
Dim folder3 As Outlook.Folder
Dim FoundFolder As Outlook.Folder
Dim MyOutlookNamespace As Outlook.NameSpace

Set MyOutlookNamespace = GetNamespace("MAPI")
Set FindFolder = Nothing

For Each folder1 In MyOutlookNamespace.Folders
    ' We know that top-level folders will not match
    ' so no comparison is needed here.
    For Each folder2 In folder1.Folders
        If folder2.Name = FolderName Then
            Set FindFolder = folder2
            Exit Function
        End If
        For Each folder3 In folder2.Folders
            If folder3.Name = FolderName Then
                Set FindFolder = folder3
                Exit Function
            End If
        Next
    Next
Next

End Function

Working with Folder Items

Every folder can contain items, and the purpose for getting a reference to an Outlook folder is almost always to do something with the items that it contains. With user-defined folders, you specify the type of Outlook item the folder will contain when you create the folder. When you are working with a folder in VBA, you may want to determine its default type of item. For example, perhaps you are writing a macro that will look for certain information in all email messages in all folders. You can iterate through all Outlook folders using the techniques described earlier in this chapter, and then process the folder items only if its default item type is email.

To determine a folder's default item type, look at its DefaultItemType property. The values that can be returned are represented by named constants as described in Table 24.2. This property is read-only, which means that you cannot change it.

Table 24.2. Named Constants for the Folder Object's DefaultItemType Property

Constant

Value

Meaning

olAppointmentItem

1

Appointment items

olContactItem

2

Contact items

olDistributionListItem

3

Exchange distribution list items (relevant to Exchange Server accounts only)

olJournalItem

4

Journal items

olMailItem

5

Mail items (email messages)

olNoteItem

6

Note items

olPostItems

7

Post items (an item posted to a public folder)

olTaskItems

8

Task items

Programming Email Items

In Outlook, an email message is represented by the MailItem object. Once you have a reference to a folder containing email items, you can loop through the folder's Items collection to access each email in turn. You can also create macros that compose and send email messages.

Working with Received Messages

Many of the things you'll do with email messages that you have received involve message properties that provide information about the subject, recipients, sender, and other aspects of the message. The MailItem properties used most often when working with received messages are described in Table 24.3.

Table 24.3. MailItem Properties Used When Working with Received Messages

Property

Description

Attachments

A collection of Attachment objects, each representing a document or link attached to the message.

Body

Text of the message (if the message is in plain text format).

CreationTime

The date when the message was created (as a type Date).

HTMLBody

The text of the message (if the message is in HTML format).

Importance

Returns the importance level of the message as one of the following values: olImportanceHigh, olImportanceLow, and olImportanceNormal.

ReceivedTime

Returns the date specifying when the message was received (as a type Date).

Recipients

A collection of Recipient objects representing the message recipients.

Saved

True if the message has been saved since it was last modified, False otherwise.

SenderName

The display name of the message sender.

SentOn

The date when the message was sent (as a type Date).

Subject

The message subject.

To

A semicolon-delimited list of the message recipients' display names.

UnRead

Returns True if the message has not been opened. False if it has been.

Next look at some examples of writing macros to perform useful, everyday tasks in Outlook.

Moving Selected Messages

One way you can use macros is to go through any folder containing email messages, typically the Inbox, and move messages to various other folders depending on their sender, subject, or other characteristics.

The first step in doing this is to get a reference to both folders. You have already seen how to get a reference to the Inbox using the GetDefaultFolder() method, and how to get a reference to a user-created folder using the FindFolder() procedure presented earlier in this chapter.

Next you must loop through all the messages in the Inbox, checking each one to see whether it meets the criterion for being moved. You use a For Each...Next loop for this purpose. For this code snippet, assume that:

  • fInbox is a reference to the Inbox.

  • The variable m has been declared as type Outlook.MailItem.

  • The variable Subject holds the text you want to look for.

For Each m In fInbox.Items
    If InStr(m.Subject, Subject) > 0 Then
        ' Move the message here.
    End If
Next

Note the use of the Instr() function. This is one of VBA's built-in string functions. It looks for one string in another and returns a value greater than 0 if it is found. In this example you use Instr() to see whether the subject text you are looking for, in the variable Subject, is found in the message's subject, obtained as the m.Subject property.

The final step is moving the message. This is easily done with the Move method. If fDestination is the folder you want to move the message to, and m is a reference to the message, you would write:

m.Move fDestination

There's a small wrinkle, however. If you move a message out of the Inbox before you have completed looping through all the messages, the For Each...Next loop can sometimes be thrown off and the process will not be completed properly. For this reason, it is necessary to keep a list of the messages to be moved without actually moving them until the For Each...Next loop has finished looking through the Inbox. You see how this is done in the full application presented in Chapter 25.

Dealing with Attachments

An email message can contain one or more attachments. An attachment can be either an actual file or a link to the file location. A MailItem object, representing an email message, has the Attachments collection, which contains one Attachment object for each attachment associated with the message.

When you are dealing with a received message, you can determine how many attachments the message has from the MailItems.Attachments.Count property. If this property returns a non-zero value, you can loop through the attachments using a For Each...Next loop:

Dim at As Outlook.Attachment
For Each at in MyMailItem.Attachments
  ' Deal with each attachment here.
Next

The Attachment object has the following properties that you can use to work with it:

  • DisplayName: The name that Outlook displays below the attachment's icon when the message is displayed on-screen. This is often, but not necessarily, the same as the attachment's filename.

  • FileName: The filename of the attachment.

  • PathName: The full path to an attached linked file. This property is valid only for linked attachments.

  • Type: The type of the attachment. Possible settings are olByValue (an attached file), and olByReference (a link to a file).

To save an attached file (but not a linked file) to disk, call its SaveAsFile method. This method's one argument is the path and filename for the file. You can, but do not have to, use the original attachment filename when saving, as shown in this example, which saves all attachments to disk under their original name and using the specified path:

Dim at As Outlook.Attachment

For Each at in MyMailItem.Attachments
    If at.Type = olByValue Then
        at.SaveAsFile("c:data" & at.FileName)
    End If
Next

Creating and Sending Messages

In addition to processing received messages, you can write macros that create and send email messages. Outlook's Object Model makes the task relatively simple. The MailItem object has some properties mostly relevant when you are creating a new message to send. These properties are described in Table 24.4.

Table 24.4. Properties of the MailItem Object for Creating and Sending Messages

Property

Description

Attachments

A collection that contains one Attachment object for each file attached to the message.

BCC

A semicolon-delimited list of display names for the blind carbon copy (BCC) recipients.

Body

The text of the message for plain text messages.

CC

A semicolon-delimited list of display names for the carbon copy (CC) recipients.

HTMLBody

The text of the message for HTML format messages.

ReadReceiptRequested

Set to True in order to request a read receipt for the message, False by default.

Recipients

A collection that contains one Recipient object for each message recipient.

SaveSentMessageFolder

The Outlook folder where a copy of the message will be saved when it is sent. The default is the Sent Items folder.

Sent

True if the message has been sent, otherwise False.

To

A semicolon-delimited list of display names for the message recipients.

The general procedure for creating and sending an email message is as follows:

  1. Create a new MailItem object.

  2. Put the message text in the Body property (for plain text messages) or HTMLBody property (for HTML format messages).

  3. Put the message subject in the Subject property.

  4. Put one or more recipients in the Recipients collection.

  5. Call the MailItem object's Send() method.

The following sections look at some details.

Creating a New Message

As mentioned, creating a new message means creating a new MailItem object. However, you cannot do this in the usual way using the New keyword. Rather, you must use the CreateItem() method as shown here:

Dim msg As Outlook.MailItem
Set msg = CreateItem(olMailItem)

Once you have the new MailItem, you can address, compose, and send it.

Addressing the Message

Each recipient of a message is represented by a Recipient object. All message recipients are placed in the MailItem object's Recipients collection. This is true for regular "To" recipients as well as CC and BCC recipients. Whether a given recipient is To, CC, or BCC is controlled by its Type property.

To add a recipient to message, call the Add() method of the MailItem.Recipients collection and pass it the recipient's email address. This method returns a reference to the new recipient, which you'll need as I soon show you. Assume that msg refers to the new MailItem object created as described in the previous section:

Dim recip As Outlook.Recipient
Set recip = msg.Recipients.Add("[email protected]")

By default, new recipients are considered "To" recipients. To change a recipient to CC or BCC, set the Recipient.Type property to either of the named constants olCC or olBCC:

recip.Type = olCC

You can also add a recipient based on his or her display name as shown here:

Dim recip As Outlook.Recipient
Set recip = msg.Recipients.Add("Jane Austin")

When you use this approach, the recipient must be resolved before you can send the message. This procedure looks through the Outlook address book for the specified display name. If it is found, the corresponding email address is added to the recipient and you can send the message. If a message has one or more unresolved recipients, trying to send it will cause an error.

To resolve a recipient, call the Resolve() method. The method returns True if the resolution was successful, False if not. Here's an example:

Dim recip As Outlook.Recipient
Set recip = msg.Recipients.Add("Jane Austin")
If recip.Resolve Then
  ' Resolved OK - safe to send.
Else
  ' Resolution failed - take steps to correct.
End If

Adding Attachments to a Message

When you are writing VBA code to create email messages, you can add attachments to each message as desired. You use the Attachments collection's Add() method, which has the following syntax:

MailItem.Attachments.Add(Source, Type, Position, DisplayName)
  • Source is a required argument specifying the path and name of the file to attach.

  • Type is an optional argument specifying the type of the attachment: olByValue (for an attached file) or olByReference for a link (shortcut) to a file. The default is olByValue.

  • Position is an optional argument specifying the position of the attachment in the message. The default is for attachments to be placed at the end of the message.

  • DisplayName is an optional argument giving the attachment's display name. If this argument is omitted, the name of the file will be used as the display name.

It is recommended to save a message before adding or removing attachments. Here's a code example that attaches two file attachments to a message:

MyMailMessage.Save
With MyMailMessage.Attachments
    .Add "c:dataTechnologyWhitePaper.doc", olByValue, , _
        "White Paper"
    .Add "c:dataMedicalExpenses.xls"
End With

Completing and Sending a Message

Other than addressing an email message, a message needs a subject line and a body. The subject is set by assigning text to the MailItem.Subject property.

The body is not quite so simple because you have the option of sending a plain text format message, a Rich Text Format (RTF) message, or an HTML format message. When you create a new MailItem object, the format is set to the default message format as specified in Outlook's mail options (refer to Chapter 5 for more information). To change the format for an individual message, set the MailItem.BodyFormat property to one of these constants: olFormatHTML, olFormatPlain, or olFormatRichText.

You assign the actual body of the message to either the Body property or the HTMLBody property depending on whether or not the text includes HTML formatting tags. Of course, the HTMLBody property is irrelevant for a plain text format message.

Finally, call the MailItem.Send() method to send the message.

Programming Calendar Items

The first thing you must do to work programmatically with calendar items is to get a reference to the Calendar folder. Because this is one of Outlook's default folders, you obtain this reference using the GetDefaultFolder() method just like you learned earlier in this chapter for the Inbox folder:

Dim MAPINameSpace As Outlook.NameSpace
Dim CalendarFolder As Outlook.Folder
Set MAPINameSpace = GetNameSpace("MAPI")
Set CalendarFolder = _
    MAPINameSpace.GetDefaultFolder(olFolderCalendar)

Once you have this reference, you can start accessing the individual calendar items. Though several kinds of objects can be present in the Calendar folder, the most important one is the AppointmentItem object, which represents one-time appointments, recurring appointments, all-day events, and multi-day events. This object has a set of properties that hold information about the appointment. The AppointmentItem properties that you are most likely to need in your macro programming are described in Table 24.5.

Table 24.5. Properties of the AppointmentItem Object

Property

Description

AllDayEvent

True if the appointment is an all-day event, in which case the start and stop times are ignored.

Body

The main body of the appointment.

Categories

Holds information about the appointment category, if any.

CreationTime

Returns a date value indicating the date and time when the appointment was created.

Duration

The duration of the appointment, in minutes.

End

A date value specifying the ending date/time for the appointment.

Importance

Specifies the importance of the appointment. Possible values are indicated by the constants olImportanceLow, olImportanceNormal, and olImportanceHigh.

IsRecurring

True if the appointment is recurring.

Location

Specifies the location of the event.

ReminderMinutesBeforeStart

The number of minutes before the start of the appointment that the reminder is to be displayed.

ReminderSet

A True/False value specifying whether a reminder will be displayed before the appointment start time.

Start

A date specifying the starting date/time for the appointment.

Subject

The subject of the appointment.

Creating a New Appointment

To create a new appointment, you use the CreateItem() method. The syntax is

Dim NewAppt As Outlook.AppointmentItem
Set NewAppt = CreateItem(olAppointmentItem)

The new appointment is, of course, blank—you must fill in the various details such as subject, start/stop times, and whether a reminder will be displayed. A new appointment created in code is not visible on the screen. There are two approaches to filling in the details of a new appointment.

You can do it all in code without ever making the appointment visible to the user. In this case you must save the appointment by calling the Save() method:

Dim NewAppt As Outlook.AppointmentItem
Set NewAppt = CreateItem(olAppointmentItem)
NewAppt.Subject = "Sales review meeting"
NewAppt.Location = "Conference Room B"
NewAppt.Start = #9/26/2006 1:00:00 PM#
NewAppt.End = #9/26/2006 3:00:00 PM#
NewAppt.Body = "Make sure to bring the worksheet."
NewAppt.Save

The other approach is to display the appointment to the user by calling its Display() method. The user fills in the appointment details and saves it by clicking the Save & Close button, as usual.

Accessing Existing Appointments

You access existing appointments using the Calendar folder's Items collection. You can retrieve an appointment based on its subject. Here's how to retrieve an appointment by its subject, in this case "New Employee Training" (assume that CalendarFolder is a reference to Outlook's Calendar folder):

Dim MyAppt As Outlook.AppointmentItem
Set MyAppt = CalendarFolder.Items("New Employee Training")

The problem with this approach is that if there are multiple appointments with the same subject, it retrieves only the first one. It is preferable to loop through all the appointments in the folder with a For Each...Next statement, looking for one or more appointments of interest. Here's an example that sets the variable MyAppt to point at the first appointment that has "New Employee Training" as its subject. If there is no such appointment, a message is displayed alerting the user.

Warning

If you try to retrieve an appointment by subject and there is no matching appointment, a runtime error occurs. This error can be trapped, but it is better to avoid trying to retrieve individual appointments in this manner.

Dim MyAppt As Outlook.AppointmentItem
Dim Appt As Outlook.AppointmentItem
Dim Found As Boolean

Found = False
For Each Appt In CalendarFolder.Items
    If Appt.Subject = "New Employee Training" Then
        Found = True
        Set MyAppt = Appt
End If
Next

If Found Then
    ' Process the matching appointment here.
Else
    MsgBox "Appointment 'New Employee Training' not found."
End If

A Calendar Demonstration

Chapter 25 presents a complete calendar application that creates and prints a document listing all the appointments for the upcoming week. This demonstration also shows you how an Outlook VBA program can control other Office applications.

Summary

The Outlook Object Model is central to any macros or VBA applications that you create in Outlook. The objects represent all the various components in Outlook—folders, messages, appointments, and so on. The functionality built in to these objects is available for you to use in your VBA code.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.94.153