Adding appointments and tasks
Other than communicating to the outside world, you might use Outlook to keep users up to date. While you can build a calendar into your application, why duplicate effort? Why not just use the one that s already on the user s machine? It s easy to both create new appointments in Outlook and read the ones that are already there. Along the same lines, don t build a "to do" list into your application. Let your applications talk to Outlook s Task list.
As with other Outlook items, adding appointments and tasks is as simple as calling CreateItem and filling in the blanks, then calling the Save method for the new object. Table 5 shows key properties of the AppointmentItem method. Table 6 looks at TaskItem properties.
The MarkComplete method of TaskItem indicates that the task has been completed on the current date. It sets PercentComplete to 100 and Complete to .T. as well. We re not sure why you can t pass it a parameter to indicate when the task was done.
The code in Listing 3 adds the birthdays of all the TasTrade employees to the Calendar as all-day events for the next two years, and creates a task of sending each of them a birthday card. The due date for the task varies depending on the country to allow sufficient time for mailing. You ll find it as MakeBdays.PRG in the Developer Download files available at
www.hentzenwerke.com.Table 5
. Making appointments. These are the properties you re most likely to set for an AppointmentItem object. Property | Type | Description |
Start, End | DateTime | The start and end time, respectively, of the appointment. |
Duration | Numeric | The length of the appointment, in minutes. Interacts with Start and End, of course. You can t set all three. |
AllDayEvent | Logical | Indicates whether the item is an "all-day event," that is, something that lasts all day rather than occurring at a specific time. |
Subject | Character | The description of the item. The subject can be used as an index into the Items collection. |
Location | Character | The location of the appointment. In the Calendar, the location appears next to the subject in parentheses. |
Body | Character | The notes for the appointment. These don t appear at all in the Calendar, only in the Appointment dialog itself. |
ReminderSet | Logical | Indicates whether Outlook should provide a reminder for this appointment. |
ReminderMinutesBeforeStart | Numeric | The number of minutes before the Start time when Outlook should provide the reminder for the appointment. |
Table 6
. Describing tasks. These properties are the keys to putting a TaskItem on the Task list. Property | Type | Description |
Subject | Character | The description of the task, it shows in the Subject column in the Task list. This property can be used as an index into the Items collection. |
DueDate | DateTime | The date by which the task is supposed to be completed. |
Complete | Logical | Indicates whether the task has been completed. Although this property isn t ReadOnly, it s better to use the MarkComplete method to set this property. |
DateCompleted | DateTime | The date on which the task was completed. Note that this is a datetime item, but only the date portion is significant. Like the Complete property, it s better to use the MarkComplete method to set this property. |
StartDate | DateTime | The date the task was started. |
Status | Numeric | The current status of the task. Use one of these constants: olTaskNotStarted 0 olTaskWaiting 3 olTaskInProgress 1 olTaskDeferred 4 olTaskComplete 2
|
PercentComplete | Numeric | Indicates how far along the task is. |
Importance | Numeric | The priority of the task (corresponding to the Priority field in the Task dialog). Uses these constants: olImportanceLow 0 olImportanceNormal 1 olImportanceHigh 2
|
Categories | Character | A comma-separated or semi-colon-separated list of categories in which the task should be placed. |
Body | Character | Notes for the task. Displayed only in the Task dialog and in memo-style output. |
ReminderSet | Logical | Indicates whether Outlook should provide a reminder for this task. |
ReminderTime | DateTime | The date and time when Outlook should provide a reminder for this task. |
Listing 3
. Adding appointments and tasks. This routine adds the birthdays for all the TasTrade employees to Outlook s Calendar for the next two years, as well as creating a task of sending each a birthday card each time.* Add TasTrade employee birthdays to the Calendar and
* create a task for each to send a birthday card
#DEFINE olAppointmentItem 1
#DEFINE olTaskItem 3
#DEFINE CR CHR(13)
LOCAL oNameSpace, oAppt1, oAppt2, oTask1, oTask2
LOCAL dNextBirthday
IF VarType(oOutlook) <> "O"
* Start or connect to Outlook
* Make it public for demonstration purposes.
RELEASE oOutlook
PUBLIC oOutlook
oOutlook = CreateObject("Outlook.Application")
ENDIF
oNameSpace = oOutlook.GetNameSpace("MAPI")
* Open the Employee table
OPEN DATABASE _SAMPLES+"\TasTrade\Data\TasTrade"
USE Employee
SCAN
* Create one appointment and one task for each employee
* for each of two years
oAppt1 = oOutlook.CreateItem( olAppointmentItem )
WITH oAppt1
* Figure out when the employee's next birthday will occur
dNextBirthday = GOMONTH( Birth_Date, ;
(YEAR(DATE()) - YEAR(Birth_Date)) * 12)
IF dNextBirthday <= DATE()
dNextBirthday = GOMONTH( dNextBirthday, 12)
ENDIF
* Set the date and make it an all-day event
.Start = DTOT( dNextBirthday )
.AllDayEvent = .T.
* Use the employee's name in the subject
.Subject = First_Name - (" " + Last_Name ) - "'s Birthday"
* Turn off reminders for this
.ReminderSet = .F.
.Save()
ENDWITH
oTask1 = oOutlook.CreateItem( olTaskItem )
WITH oTask1
* Set the task name using the employee name
.Subject = "Send a birthday card to " + First_Name - (" " + Last_Name)
* Figure out the due date based on the country it's going to
DO CASE
CASE INLIST(Country , "USA", "Canada")
.DueDate = dNextBirthday - 3
CASE INLIST(Country, "UK", "France")
.DueDate = dNextBirthday - 7
OTHERWISE
* Figure this'll take a long time
.DueDate = dNextBirthday - 10
ENDCASE
* Put the mailing address in the body for convenience
cAddress = Address + CR + ;
City + CR + ;
Region + CR + ;
Postal_Code + CR + ;
Country
.Body = "Mailing Address (unformatted): " + CR + cAddress
* Set a reminder one day ahead
.ReminderTime = .DueDate - 1440*60
.ReminderSet = .T.
* Set the category
.Categories = "Gifts"
.Save()
ENDWITH
* Now do second year
oAppt2 = oAppt1.Copy()
WITH oAppt2
* Move the date forward one year
.Start = GOMONTH( .Start, 12 )
.Save()
ENDWITH
oTask2 = oTask1.Copy()
WITH oTask2
* Move the date forward one year
.DueDate = GOMONTH( .DueDate, 12 )
.Save()
ENDWITH
ENDSCAN
USE IN Employee
CLOSE DATA
RETURN
In case, like us, you don t really want to leave these items scattered throughout your copy of Outlook, Listing 4 is an antidote program. It s included as CleanBdays.PRG in the Developer Download files available at
www.hentzenwerke.com. It uses the Find method of the Items collection. Find takes a single parameter, a filter string, and returns the first item that matches that filter. The required format for the filter makes us really glad that FoxPro has three sets of character delimiters properties of the item must be surrounded with square brackets. If no matching item is found, Find returns .null.It s worth noting that there s also a FindNext method. In this program, it s not needed because each time we find a matching item, we delete it immediately. So, the next search is again looking for the first item that matches the filter string. (For another approach to this problem, check out the Restrict method in the Help file. It s like setting a filter on the list of items.)
Listing 4
. Finding and removing items. This program cleans up after the one in Listing 3.* Clean up birthday entries added to Outlook
#DEFINE olFolderCalendar 9
#DEFINE olFolderTasks 13
LOCAL oNameSpace, oAppt, oTask
LOCAL oAppts, oTasks, cFilter
IF VarType(oOutlook) <> "O"
* Start or connect to Outlook
* Make it public for demonstration purposes.
RELEASE oOutlook
PUBLIC oOutlook
oOutlook = CreateObject("Outlook.Application")
ENDIF
oNameSpace = oOutlook.GetNameSpace("MAPI")
oAppts = oNameSpace.GetDefaultFolder( olFolderCalendar )
oTasks = oNameSpace.GetDefaultFolder( olFolderTasks )
* Open the Employee table
OPEN DATABASE _SAMPLES+"\TasTrade\Data\TasTrade"
USE Employee
SCAN
* Create a filter string
cFilter = '[Subject] = "' + First_Name - ;
(" " + Last_Name ) - "'s Birthday" + '"'
* Loop until there are no more matches
oAppt = oAppts.Items.Find( cFilter )
DO WHILE NOT IsNull( oAppt )
oAppt.Delete()
oAppt = oAppts.Items.Find( cFilter )
ENDDO
* Now do the same thing for the Tasks
cFilter = '[Subject] = "Send a birthday card to ' + ;
First_Name - (" " + Last_Name) +'"'
* Loop until there are no more matches
oTask = oTasks.Items.Find( cFilter )
DO WHILE NOT IsNull( oTask )
oTask.Delete()
oTask = oTasks.Items.Find( cFilter )
ENDDO
ENDSCAN
RETURN
Copyright 2000 by Tamar E. Granor and Della Martin All Rights Reserved