In addition to the application-level events discussed so far, Outlook also supports a wide variety of item-level events — events that fire when items are manipulated rather than the application as a whole being affected.
You can handle item-level events in Outlook in two ways:
By declaring an event in a class module and running an initialization procedure, so that VBA then traps the event when it fires. This chapter takes this approach.
By creating Visual Basic Script (VBScript) code and placing it in the form used by the item. This approach is especially useful for custom forms, but it is more limited than the previous approach, because some of the events that Outlook supports are not available in VBScript.
Follow these steps to declare an object variable and initialize an event:
Decide which class module to use for the declaration by using one of the following three methods:
To use the ThisOutlookSession module, in the Project Explorer expand the Project1 item that represents the Outlook VBA project, expand the Microsoft Outlook Objects item, and double-click the ThisOutlookSession item to open a Code window showing its contents.
Create a class module by right-clicking in the Project Explorer and choosing Insert Class Module from the context menu. The Visual Basic Editor automatically opens a Code window for the class.
Open an existing class module by double-clicking it in the Project Explorer.
In the declarations area at the beginning of the class module (at the top of the Code window), declare a variable to represent the object to which the event applies. Use the WithEvents keyword to denote that the object has events. The following example creates a public variable named myPublicContactItem:
PublicWithEventsmyPublicContactItemAsContactItem
Initialize the object variable by setting it to represent the appropriate object. The following example sets the myPublicContactItem variable to represent the first item in the default contacts folder:
Set myPublicContactItem = Application.GetNamespace("MAPI") _ .GetDefaultFolder(olFolderContacts).Items(1)
Once you've initialized the object variable, the procedure will run after the event fires.
You can initialize the object variable manually if necessary, and you may find it convenient to do so when you're writing and testing code to handle events. But if you need to handle the event each time Outlook runs — if you want to make the macro a permanent part of your macro collection — it's obviously best to run the code to initialize the object variable automatically. For example, you might use the Startup event of the Application object (discussed in "Using the Startup Event," earlier in this chapter) to run event-handling initialization code automatically each time Outlook starts.
Many of the item-level events apply to all the message items: the AppointmentItem, ContactItem, DistListItem, DocumentItem, Explorer, Inspector, JournalItem, MailItem, MeetingItem, PostItem, RemoteItem, ReportItem, TaskItem, TaskRequestAcceptItem, TaskRequestDeclineItem, TaskRequestItem, and TaskRequestUpdateItem items. Table 27.1 lists these events.
The events that fire before an action occurs allow you to cancel the action so that it doesn't take place. The syntax for these events uses a Boolean argument named Cancel that you can set to True to prevent the action from taking place. For example, the syntax for the BeforeDelete event is as follows:
Sub expression_BeforeDelete(ByVal Item As Object, Cancel As Boolean)
Here, expression is a required expression that returns one of the message items to which the event applies (for example, a TaskItem object). The following example uses the BeforeDelete event to check that the TaskItem object that's open in an inspector is marked as complete when the user tries to delete it. If the task is not marked as complete, a message box prompts the user to complete the task, and the example then sets the Cancel argument to True to prevent the deletion from occurring.
Private Sub myTaskItem_BeforeDelete(ByVal Item As Object, Cancel As Boolean) If myTaskItem.Complete = False Then MsgBox "Please complete the task before deleting it.", _ vbOKOnly +vbExclamation, "Task Is Incomplete" Cancel = True End If End Sub
The Difference between the Read and Open EventsThe Read event and the Open event both occur when the user opens an existing item for editing. The difference between the two events is that the Open event occurs only when the item is being opened in an inspector window, whereas the Read event occurs both when the item is being opened in an inspector window and when it is being selected for editing in a cell. |
Table 27.2 lists the events that apply to explorers, inspectors, or views. Some events apply to both explorers and inspectors.
If you work on a small screen (for example, a laptop screen), you might prefer to use the NewInspector event to maximize each inspector window you open and to hide any toolbars you don't need. The first procedure in the following example (which includes the necessary declarations) uses the NewInspector event to make sure the Standard toolbar is displayed, hide the Advanced toolbar, and assign the Inspector object representing the new inspector to the Public object variable myInspector. The second procedure uses the Activate event of the myInspector object to maximize its window by setting the WindowState property to olMaximized.
The net effect of these two event procedures is to configure the toolbars as described earlier and maximize the inspector window. The Activate event procedure is necessary because the NewInspector event runs before the inspector window is displayed, which means the NewInspector event procedure cannot maximize the inspector window.
Public WithEvents myInspectors As Inspectors Public WithEvents myInspector As Inspector Private Sub myInspectors_NewInspector(ByVal Inspector As Outlook.Inspector) With Inspector With .CommandBars .Item("Standard").Visible = True .Item("Advanced").Visible = False End With Set myInspector = Inspector End With End Sub Private Sub myInspector_Activate() myInspector.WindowState = olMaximized End Sub
Outlook provides three events (see Table 27.3) that apply to folders.
Event | Event Occurs | Available in VBScript? |
---|---|---|
FolderAdd | When a folder is added to the specified Folders collection | No |
FolderChange | When a folder in the specified Folders collection is changed | No |
FolderRemove | When a folder is removed from the specified Folders collection | No |
Table 27.4 lists the events that apply to items and results.
The following example uses the ItemChange event to monitor when any contact is changed in the Contacts folder. After a change, the event procedure displays a message box asking if the user wants to inform colleagues of the change to the contact. If the user clicks the Yes button, the example creates and sends a message containing the vCard for the contact. The message goes to the Marketing Associates distribution list and has the subject Contact details change: and the name of the contact.
How to Test Event Handler ProceduresYou don't test event handlers the same way that you test ordinary VBA modules (where you simply click inside the procedure to put the blinking insertion point in the code, and then press F5 to execute the macro). Instead, you must first assign an object variable by executing initialization code in a separate procedure of its own or in a startup procedure (the Startup event). These steps are described earlier in this chapter in the section "Declaring an Object Variable and Initializing an Event." After you've initialized your event handler, you can trigger it either through code or by doing something in the application interactively. The following example is of the latter type: you interactively modify one of the contacts in the contacts folder (just add a note to an existing contact, for example). As soon as you click the Save and Close button in a contact box after having modified its contents, the event triggers and a message box is displayed asking if you want to notify your colleagues — as you can see in the following code example. So, to test the event in the following example, add the following code to the ThisOutlookSession class module's Code window (find this module in the Project Explorer). Or choose Insert Class Module in the Outlook Visual Basic Editor. Event handlers must be placed within class modules, not ordinary VBA modules such as the typical Module1. After the code is typed into the class module, execute the Initialize_myContacts procedure to assign the needed contact item object to the object variable myContacts. (To execute this initialization procedure, press F5 to open the Macros dialog box, and select ThisOutlookSession.Initialize_myContacts in the list displayed in the Macros dialog box. Then click the Run button in the dialog box.) Now you've established the connection to the event handler, and the handler procedure will sit there waiting for one of the contacts to change — the event it's designed to detect — at which point it will execute the code you've written in the myContacts_ItemChange event handler. Public WithEvents myContacts As Items Public Sub Initialize_myContacts Set myContacts = Application.GetNamespace("MAPI") _ .GetDefaultFolder(olFolderContacts).Items End Sub Private Sub myContacts_ItemChange(ByVal Item As Object) Dim ContactUpdateMessage As MailItem If MsgBox("Notify your colleagues of the contact change?", _ vbYesNo +vbQuestion, "Contact Data Changed") = vbYes Then Set ContactUpdateMessage = Application.CreateItem(ItemType:=olMailItem) With ContactUpdateMessage .To = "Marketing Associates" .Subject = "Contact details change: " & Item.Subject .Body = "The following contact has changed: " & vbCr & vbCr _ & Item.Subject .Attachments.Add Source:=Item, Position:=50 .Send End With End If End Sub |
Outlook supports various events that apply to the Outlook bar (see Table 27.5). You may find these events useful if you need to customize the Outlook bar or constrain the user's navigation capabilities. For example, you can use the BeforeNavigate event to check the shortcut to which the user is attempting to navigate. If the user is not permitted to access the folder associated with the shortcut, you can cancel the navigation.
Event | Applies To | Event Occurs | Available in VBScript? |
---|---|---|---|
GroupAdd | OutlookBarGroup | After a new group is added to the Shortcuts pane. | No |
BeforeGroupAdd | OutlookBarGroups | Before a new group is added to the Shortcuts pane. | No |
BeforeGroupRemove | OutlookBarGroups | Before a group is removed from the Shortcuts pane. | No |
BeforeGroupSwitch | OutlookBarPane | When a new group is opened in the Outlook bar. Does not fire in Outlook 2003 because Outlook 2003 has a different Navigation pane and Shortcuts pane. | No |
BeforeNavigate | OutlookBarPane | After the user clicks a shortcut in the Shortcuts pane but before Outlook displays the folder represented by the shortcut. | No |
BeforeShortcutAdd | OutlookBarShortcuts | Before a new shortcut is added to a group in the Shortcuts pane. | No |
BeforeShortcutRemove | OutlookBarShortcuts | Before a shortcut is removed from a group in the Shortcuts pane. | No |
ShortcutAdd | OutlookBarShortcuts | After a new shortcut is added to a Shortcuts pane group. | No |
Table 27.6 explains the events that Outlook provides for reminders. You can use these events to take actions when a reminder fires, before the Reminder dialog box appears, when the user clicks the Snooze button to dismiss a reminder, or when reminders are added, changed, or removed.
Event | Event Occurs | Available in VBScript? |
---|---|---|
BeforeReminderShow | Before Outlook displays the Reminder dialog box | Yes |
ReminderAdd | When a reminder is added | Yes |
ReminderChange | After a reminder has been changed | Yes |
ReminderFire | Before a reminder is executed | Yes |
ReminderRemove | When a reminder is removed from the Reminders collection | Yes |
Snooze | When the user dismisses a reminder by clicking the Snooze button | Yes |
If you write procedures to synchronize Outlook, you may need to use the three events that apply to the SyncObject object, which represents a Send/Receive group for a user. (You can access the SyncObject object by using the SyncObjects property of the NameSpace object to return the SyncObjects collection.) Table 27.7 explains the events that apply to the SyncObject object.
Event | Event Occurs | Available in VBScript? |
---|---|---|
SyncStart | When Outlook starts synchronizing a user's folders | No |
SyncEnd | After synchronization ends | No |
OnError | When an error occurs during synchronization | No |
The following example uses the OnError event with the object variable mySyncObject. If an error occurs during synchronization of the SyncObject represented by mySyncObject, the procedure displays an error message giving the error code and description:
Private Sub mySyncObject_OnError(ByVal Code As Long, _ ByVal Description As String) Dim strMessage As String
strMessage = "An error occurred during synchronization:" & vbCr & vbCr strMessage = strMessage & "Error code: " & Code & vbCr strMessage = strMessage & "Error description: " & Description MsgBox strMessage, vbOKOnly +vbExclamation, "Synchronization Error" End Sub
3.19.208.13