David Shank
July 8, 1999
School is out in the U.S., and the talk around this office this month is about summer vacation. In some parts of the country, summer has arrived with record high temperatures. Here in the Pacific Northwest summer arrived, as usual, with rain, rain, and more rain.
I thought I'd start with the basics of working with Outlook objects from any Office application.
As a kid, I really looked forward to summer vacation. The last day of school, the first day of summer: a sense of things ending and a sense of new things just beginning. It's starting to feel a lot like summer vacation around here. Microsoft® Office 2000 is finally out the door and, well, it's raining.
What do you suppose we do around here when we don't have a new version of Office to get out the door? No, we don't plot how to take over the world. We get to spend some quality time with our customers. For many of us, it is the most interesting part of our job. It never ceases to amaze me the cool things that you do with the applications we put in that box. And the customers I've spoken with recently have been talking a lot about Outlook. It seems like people are spending a lot of time using that application or thinking about new ways to use it with the other Office applications.
Developers are asking for more information about programmatically incorporating features from Outlook into their custom Office solutions. This is a huge topic that I plan to talk about frequently. But I thought that at the beginning I'd start with the basics of working with Outlook objects from any Office application.
Increasingly, users are spending much of their time in Outlook. They use it to send and receive mail, make appointments, schedule meetings, manage contacts, and much more. The result is not only that Outlook contains several useful features, but it also contains important data that you may need to work with in your custom solution. Whether you are writing code in Word, Excel, Access, or Outlook, understanding how to work with Outlook objects programmatically will make your life a lot easier.
These objects are not difficult to work with—and once you understand how the objects work and relate to each other, you will be well on your way to being able to incorporate powerful new features into your custom Office solution.
There are two basic steps you need to take before you can work with Outlook objects from another Office application. First, you need to set a reference to the Outlook object library. You do this using the References command on the Tools menu in the Visual Basic® Editor. Second, you need to create an object variable representing the Outlook Application object. The Application object is the starting point for everything you will do with Outlook. For example, you could use the following code within a procedure to initialize an object variable representing the Application object:
Dim olApp As Outlook.Application
Set olApp = New Outlook.Application
Outlook is considered a multiuse automation server. This means that multiple applications will share the same instance of Outlook. If Outlook is already open when this code runs, the olApp object variable will use the existing instance of Outlook.
Once you have an object variable pointing to the Outlook Application object, you use the object's CreateItem method to create a new Outlook object. The CreateItem method uses a single argument that is an enumerated constant representing the type of object you want to create. For example, the following procedure creates a new appointment:
Sub CreateNewAppointment()
Dim olApp As Outlook.Application
Dim olNewMeeting As Outlook.AppointmentItem
Set olApp = New Outlook.Application
Set olNewMeeting = olApp.CreateItem(olAppointmentItem)
With olNewMeeting
.Recipients.Add "David Shank"
.Start = #7-21-99 2:30:00 PM#
.Duration = 30
.Importance = olImportanceHigh
.Subject = "Programming Outlook"
.Save
End With
End Sub
The CreateItem method can be used to create new appointments, contacts, distribution list items, journal entries, mail messages, notes, tasks, or postings to public folders.
In this section, I again use the CreateItem method—but this time, I use it to create a new e-mail message. I'll also illustrate how to create a general-purpose procedure you can use in your own solutions to create and send mail using Outlook.
An e-mail message typically has one or more recipients, a subject, a message, and perhaps one or more attachments. In Outlook, each of these components has a corresponding property or collection you can use to help create a mail item.
You use the Subject property to specify the subject of a mail item using the text you want to use as the subject of the mail. You use the Body property to specify the text of the e-mail message itself.
You use the Add method of the mail item's Recipients collection to add one or more recipients to the mail. Similarly, you use the Add method of the mail item's Attachments collection to add one or more attachments to the mail. In the procedure below, recipients and attachments are each passed to the procedure in an array that is then parsed to add the items to the e-mail.
The Example procedure uses the ResolveAll method of the Recipients collection to resolve the specified recipients against entries in the Outlook address book. If the ResolveAll method succeeds, the Send method is used to send the mail message. If the ResolveAll method fails, the Display method is used to display the mail message to the user to correct any invalid recipient names that may exist.
Function CreateMail(astrRecip As Variant, _
strSubject As String, _
strMessage As String, _
Optional astrAttachments As Variant) As Boolean
Dim olApp As Outlook.Application
Dim objNewMail As Outlook.MailItem
Dim varRecip As Variant
Dim varAttach As Variant
Dim blnResolveSuccess As Boolean
On Error GoTo CreateMail_Err
Set olApp = New Outlook.Application
Set objNewMail = olApp.CreateItem(olMailItem)
With objNewMail
' Add each item in the varRecip array to the Recipients collection.
For Each varRecip In astrRecip
.Recipients.Add varRecip
Next varRecip
' Determine if all recipients have corresponding entries in the
' Outlook address book.
blnResolveSuccess = .Recipients.ResolveAll
' Add each item in the varAttach array to the Attachments collection
' and specify the subject and text of the mail message.
For Each varAttach In astrAttachments
.Attachments.Add varAttach
Next varAttach
.Subject = strSubject
.Body = strMessage
' If all recipients are valid then send the message now, otherwise
' display the message so the user can fix invalid e-mail addresses.
If blnResolveSuccess Then
.Send
Else
MsgBox "Unable to resolve all recipients. Please check " _
& "the names."
.Display
End If
End With
CreateMail = True
CreateMail_End:
Exit Function
CreateMail_Err:
CreateMail = False
Resume CreateMail_End
End Function
The CreateMail procedure illustrates how easy it is to add Outlook e-mail functionality to your custom Office solution. To use this procedure, you programmatically gather the information needed for the procedure arguments and then call CreateMail. The procedure returns True if the mail item is successfully created and sent, otherwise it returns False.
A powerful feature of working with Outlook objects programmatically is that you have access to the information a user has stored in their Outlook contacts folder. This allows you to write code that gets information important to the user into your custom solution. For example, you can put Visual Basic for Applications code in a Word template or add-in that uses information from the contacts folder to create address entries or mailing labels.
Before you can work with information in an existing Outlook folder, you must first get access to the folder. You use the NameSpace object to work with existing folders. The NameSpace object represents an abstract root object for Outlook as a data source. You use the Application object's GetNameSpace method to create a NameSpace object.
In Outlook, the NameSpace object has at least two top-level folders. One folder represents all available public folders and the other represents the user's mailbox. The following code sample illustrates how you might access folders in each of these two top-level folders:
Dim olApp As Outlook.Application
Dim nsNameSpace As Outlook.NameSpace
Dim fldFolder As Outlook.MAPIfolder
Set olApp = New Outlook.Application
Set nsNameSpace = olApp.GetNameSpace("MAPI")
' Access the Inbox folder
Set fldFolder = nsNameSpace.GetDefaultFolder(olFolderInbox)
MsgBox "There are " & fldFolder.Items.Count & " items in your inbox."
' Access the SharedByAll public folder
Set fldFolder = nsNameSpace.Folders("Public Folders") _
.Folders("All Public Folders").Folders("SharedByAll")
MsgBox "There are " & fldFolder.Items.Count & _
" items in your SharedByAll folder."
You can use the GetDefaultFolder method of the NameSpace object to get the default Outlook folders such as the Inbox, Contacts, Tasks, and so on. To get other folders, you must provide the name of the specific folder you want to work with.
Imagine that you want to present the user with a list of contacts from which he can choose an entry to use to create a mailing address for a Word document. One way to do this is illustrated below in the GetContacts procedure. This procedure returns an array containing the name and mailing address for each entry in the user's contacts folder for which there is a business address.
The GetContacts procedure uses the GetDefaultFolder method to create a reference to the Contacts folder. It uses the Restrict method of the Contacts folder's Items collection to eliminate all contacts that do not have a business address. It then fills an array with name and address information for each remaining contact item in the style.
ContactName
ContactCompanyName
ContactBusinessAddress
Finally, the procedure sorts the array (in the QuicksortArray procedure, which is not shown here) and then returns the sorted array to the procedure that called the GetContacts function.
Function GetContacts() As Variant()
Dim olApp As Outlook.Application
Dim nspNameSpace As Outlook.NameSpace
Dim fldContacts As Outlook.MAPIFolder
Dim objContacts As Object
Dim objContact As Object
Dim avarContactsArray() As Variant
Dim intCntr As Integer
' Get reference to the Outlook Contacts folder.
Set olApp = New Outlook.Application
Set nspNameSpace = olApp.GetNamespace("MAPI")
Set fldContacts = nspNameSpace.GetDefaultFolder(olFolderContacts)
' Restrict the contact items to those that have an entry in
' the business address field.
Set objContacts = fldContacts.Items _
.Restrict("[BusinessAddress] <> '" & "" & "'")
' Resize the array to the number of Outlook Contacts.
ReDim avarContactsArray(objContacts.Count - 1)
For Each objContact In objContacts
' Format the entry so that each line of information is
' separated by a carriage return.
avarContactsArray(intCntr) = IIf(Len(objContact.FullName) > 0, _
objContact.FullName & vbCrLf, "") & _
IIf(Len(objContact.CompanyName) > 0, _
objContact.CompanyName & vbCrLf, "") _
& objContact.BusinessAddress
intCntr = intCntr + 1
Next objContact<
' Sort the array.
QuickSortArray avarContactsArray
' Return the sorted array to the calling procedure.
GetContacts = avarContactsArray
End Function
You might use the array returned by GetContacts to fill a list box on a user form used as a custom dialog box. GetContacts illustrates one of the many ways you can use Outlook objects to add sophisticated Outlook functionality to your custom Office solutions.
The information presented here should be enough to get you started working with Outlook objects in your own custom solution. Now that you have seen how easy it is to work with Outlook programmatically, take some time to explore what else you can do with Outlook objects.
For more information on working with Outlook, go to http://msdn.microsoft.com/officedev/technical/articles/outlook.asp.
David Shank is a Programmer/Writer on the Office team specializing in developer documentation. Rumor has it he lives high in the mountains to the east of Redmond and is one of the few native Northwesterners still living in the Northwest.