Creating Recurring Appointments and Meetings
Topic Last Modified: 2009-02-25
Recurring appointments and meetings occur more than once and follow a pattern in time. For example, a department meeting on the first Tuesday of each month can be defined as a recurring meeting.
In Collaboration Data Objects (CDO), a single Appointment object and one or more RecurrencePattern objects represent a recurring appointment or meeting. The Appointment object defines the first appointment or meeting, and the RecurrencePattern objects define the pattern for additional appointments or meetings. You can also specify modifications to the recurring meeting pattern by using one or more Exception objects.
To create a recurring appointment or meeting
- Create an Appointment object.
- Set the properties of the first appointment or meeting.
- Create a RecurrencePattern object and add it to the Appointment's RecurrencePatterns collection. You do this by using the IRecurrencePatterns.Add method.
- Set the properties of the RecurrencePattern object to create the desired recurrence pattern.
- For meetings, create one or more Attendee objects and specify the attendees.
- For meetings, create a CalendarMessage object by using the IAppointment.CreateRequest method and send the message.
- Save the appointment to the organizer's calendar (optional).
This topic contains Microsoft® Visual Basic®, Microsoft Visual C++®, Microsoft C#, and Visual Basic .NET code examples.
Example
Visual Basic
The following example creates a recurring meeting and then invites the specified attendees to the meeting.
' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library
' Note: It is recommended that all input parameters be validated when they are
' first obtained from the user or user interface.
Sub CreateRecurringMeeting(ObjPer As CDO.Person, _
ObjAppt As CDO.Appointment, _
ObjFreq As CDO.CdoFrequency, _
LngInterval As Long, _
dtmEndDate As Date, _
ObjMbx As IMailbox, _
strAttnMandatory() As String, _
strAttnOptional() As String)
Dim ObjConfig As New Configuration
Dim ObjRRule As IRecurrencePattern
Dim ObjCalMsg As CalendarMessage
Dim ObjAtten As New Attendee
Dim StrCalendarURL As String
Dim ObjConn As New ADODB.Connection
ObjConn.Provider = "ExOLEDB.DataSource"
'Set the configuration fields
ObjConfig.Fields(cdoSendEmailAddress) = ObjPer.Email
ObjConfig.Fields(CDO.cdoMailboxURL) = ObjMbx.BaseFolder
ObjConfig.Fields.Update
With ObjAppt
.Configuration = ObjConfig
'Create the RecurrencePattern Object
Set ObjRRule = .RecurrencePatterns.Add("Add")
'Define the recurrence pattern
'Frequency such as cdoWeekly or cdoDaily
ObjRRule.Frequency = ObjFreq
'Interval, for example "2"
ObjRRule.Interval = LngInterval
'The pattern end date.
ObjRRule.PatternEndDate = dtmEndDate
'Add attendees
Dim i As Long
For i = LBound(strAttnMandatory) To UBound(strAttnMandatory) - 1
Set ObjAtten = .Attendees.Add
ObjAtten.Address = CStr(strAttnMandatory(i))
ObjAtten.Role = cdoRequiredParticipant
Next i
For i = LBound(strAttnOptional) To UBound(strAttnOptional) - 1
Set ObjAtten = .Attendees.Add
ObjAtten.Address = CStr(strAttnOptional(i))
ObjAtten.Role = cdoOptionalParticipant
Next i
'Create Meeting Request Message and Send (to attendees).
Set ObjCalMsg = .CreateRequest
'Save the appointment to the organizer's calendar
ObjConn.Open ObjMbx.BaseFolder
.Datasource.SaveToContainer ObjMbx.Calendar, ObjConn
ObjCalMsg.Message.Send
' Clean up.
ObjConn.Close
Set ObjConn = Nothing
End With
End Sub
C++
The following example creates a recurring meeting and then invites the specified attendees to the meeting.
/*
Assume that the following paths are in your
INCLUDE or Directories path:
%CommonProgramFiles%\system\ado
%CommonProgramFiles%\microsoft shared\cdo
*/
#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#include <vector>
using namespace std;
// Note: It is recommended that all input parameters be validated when they are
// first obtained from the user or user interface.
void createRecurringMeeting(
IAppointmentPtr& iAppt,
IMailboxPtr& iMbx,
CdoFrequency Frequency,
long Interval,
DATE endDate,
vector<bstr_t>& AttnMand,
vector<bstr_t>& AttnOpt
)
{
if(iAppt == NULL || iMbx == NULL)
_com_issue_error(E_INVALIDARG);
IConfigurationPtr iConf(__uuidof(Configuration));
_ConnectionPtr Conn(__uuidof(Connection));
IRecurrencePatternPtr RRULE;
ICalendarMessagePtr iCalMsg;
IAttendeePtr iAttn;
IPersonPtr iPer;
Conn->Provider = "ExOLEDB.DataSource";
try {
iPer = iMbx;
}
catch(_com_error e ) {
cerr << "Invalid or unbound Person object reference passed." << endl;
_com_issue_error(E_INVALIDARG);
}
iConf->Fields->Item[cdoSendEmailAddress]->Value = variant_t(iPer->Email);
iConf->Fields->Item[cdoMailboxURL]->Value = variant_t(iMbx->BaseFolder);
iConf->Fields->Update();
iAppt->Configuration = iConf;
//Create the RecurrencePattern object
RRULE = iAppt->RecurrencePatterns->Add("Add");
/*
Define the recurrence pattern
Frequency, such as cdoWeekly or cdoDaily
*/
RRULE->Frequency = Frequency;
// Interval, for example "2"
RRULE->Interval = Interval;
// The pattern end date.
RRULE->PatternEndDate = endDate;
typedef vector<bstr_t>::const_iterator CI;
for(CI p = AttnMand.begin(); p != AttnMand.end(); p++) {
iAttn = iAppt->Attendees->Add(bstr_t());
iAttn->Address = _bstr_t(*p);
iAttn->Role = cdoRequiredParticipant;
cout << "Added " << bstr_t(*p) << " as required attendee to meeting." << endl;
}
for(p = AttnOpt.begin(); p != AttnOpt.end(); p++) {
iAttn = iAppt->Attendees->Add(bstr_t());
iAttn->Address = _bstr_t(*p);
iAttn->Role = cdoOptionalParticipant;
cout << "Added " << bstr_t(*p) << " as optional attendee to meeting." << endl;
}
try {
iCalMsg = iAppt->CreateRequest();
}
catch(_com_error e) {
cerr << "Error creating the request" << endl;
throw e;
}
//Save the appointment to the organizer's calendar
try {
Conn->Open(iMbx->BaseFolder, bstr_t(), bstr_t(), -1);
iAppt->DataSource->SaveToContainer(
iMbx->Calendar,
Conn,
adModeReadWrite,
adCreateNonCollection,
adOpenSource,
bstr_t(),
bstr_t());
// Close the connection.
Conn->Close();
Conn = NULL;
}
catch(_com_error e) {
cerr << "Error saving recurring appointment to user's calendar folder." << endl;
throw e;
}
try {
iCalMsg->Message->Send();
}
catch(_com_error e) {
cerr << "Error sending calendar message." << endl;
throw e;
}
}
C#
The following example creates a recurring meeting and then invites the specified attendees to the meeting.
// Reference to Microsoft ActiveX Data Objects 2.5 Library
// Reference to Microsoft CDO for Exchange 2000 Library
static void CreateRecurringMeeting (CDO.Person ObjPer,
CDO.Appointment ObjAppt,
CDO.CdoFrequency ObjFreq,
long LngInterval,
DateTime dtmEndDate,
CDO.IMailbox ObjMbx,
string[] strAttnMandatory,
string[] strAttnOptional)
{
try
{
// Variables.
CDO.Configuration ObjConfig = new CDO.Configuration();
CDO.IRecurrencePattern ObjRRule;
CDO.CalendarMessage ObjCalMsg;
CDO.Attendee ObjAtten = new CDO.Attendee();
ADODB.Connection ObjConn = new ADODB.Connection();
ObjConn.Provider = "ExOLEDB.DataSource";
// Set the configuration fields.
ObjConfig.Fields[CDO.CdoConfiguration.cdoSendEmailAddress].Value = ObjPer.Email;
ObjConfig.Fields[CDO.CdoConfiguration.cdoMailboxURL].Value = ObjMbx.BaseFolder;
ObjConfig.Fields.Update();
ObjAppt.Configuration = ObjConfig;
// Create the RecurrencePattern object.
ObjRRule = ObjAppt.RecurrencePatterns.Add("Add");
// Set the recurrence pattern frequency,
// such as cdoWeekly or cdoDaily.
ObjRRule.Frequency = ObjFreq;
// Set the recurrence pattern interval,
// such as "2".
ObjRRule.Interval = (int)LngInterval;
// Set the recurrence pattern end date.
ObjRRule.PatternEndDate = dtmEndDate;
// Add mandatory attendees.
long i;
for (i = 0; i < strAttnMandatory.Length; ++i)
{
ObjAtten = ObjAppt.Attendees.Add("");
ObjAtten.Address = Convert.ToString(strAttnMandatory[i]);
ObjAtten.Role = CDO.CdoAttendeeRoleValues.cdoRequiredParticipant;
}
// Add optional attendees.
for (i = 0; i < strAttnMandatory.Length; ++i)
{
ObjAtten = ObjAppt.Attendees.Add("");
ObjAtten.Address = Convert.ToString(strAttnOptional[i]);
ObjAtten.Role = CDO.CdoAttendeeRoleValues.cdoOptionalParticipant;
}
// Create the meeting request message.
ObjCalMsg = ObjAppt.CreateRequest();
// Save the appointment to the organizer's calendar.
ObjConn.Open(ObjMbx.BaseFolder, "", "", -1);
ObjAppt.DataSource.SaveToContainer(ObjMbx.Calendar, ObjConn,
ADODB.ConnectModeEnum.adModeReadWrite,
ADODB.RecordCreateOptionsEnum.adCreateNonCollection,
ADODB.RecordOpenOptionsEnum.adOpenSource, "", "");
// Send the meeting request message to the attendees.
ObjCalMsg.Message.Send();
// Close the connection.
ObjConn.Close();
Console.WriteLine("Meeting sent.");
}
catch (Exception err)
{
Console.WriteLine(err.ToString());
}
}
Visual Basic .NET
The following example creates a recurring meeting and then invites the specified attendees to the meeting.
' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library
Sub CreateRecurringMeeting(ByVal ObjPer As CDO.Person, _
ByVal ObjAppt As CDO.Appointment, _
ByVal ObjFreq As CDO.CdoFrequency, _
ByVal LngInterval As Long, _
ByVal dtmEndDate As Date, _
ByVal ObjMbx As CDO.IMailbox, _
ByVal strAttnMandatory() As Object, _
ByVal strAttnOptional() As Object)
Try
' Variables.
Dim ObjConfig As New CDO.Configuration()
Dim ObjRRule As CDO.IRecurrencePattern
Dim ObjCalMsg As CDO.CalendarMessage
Dim ObjAtten As New CDO.Attendee()
Dim ObjConn As New ADODB.Connection()
ObjConn.Provider = "ExOLEDB.DataSource"
' Set the configuration fields.
ObjConfig.Fields(CDO.CdoConfiguration.cdoSendEmailAddress).Value = ObjPer.Email
ObjConfig.Fields(CDO.CdoConfiguration.cdoMailboxURL).Value = ObjMbx.BaseFolder
ObjConfig.Fields.Update()
With ObjAppt
.Configuration = ObjConfig
' Create the RecurrencePattern object.
ObjRRule = .RecurrencePatterns.Add("Add")
' Set the recurrence pattern frequency,
' such as cdoWeekly or cdoDaily.
ObjRRule.Frequency = ObjFreq
' Set the recurrence pattern interval,
' such as "2"
ObjRRule.Interval = LngInterval
' Set the recurrence pattern end date.
ObjRRule.PatternEndDate = dtmEndDate
' Add mandatory attendees.
Dim i As Long
For i = LBound(strAttnMandatory) To UBound(strAttnMandatory)
ObjAtten = .Attendees.Add
ObjAtten.Address = CStr(strAttnMandatory(i))
ObjAtten.Role = CDO.CdoAttendeeRoleValues.cdoRequiredParticipant
Next i
' Add optional attendees.
For i = LBound(strAttnOptional) To UBound(strAttnOptional)
ObjAtten = .Attendees.Add
ObjAtten.Address = CStr(strAttnOptional(i))
ObjAtten.Role = CDO.CdoAttendeeRoleValues.cdoOptionalParticipant
Next i
' Create the meeting request message.
ObjCalMsg = .CreateRequest
' Save the appointment to the organizer's calendar.
ObjConn.Open(ObjMbx.BaseFolder)
.DataSource.SaveToContainer(ObjMbx.Calendar, ObjConn)
' Send the meeting request message to the attendees.
ObjCalMsg.Message.Send()
' Close the connection.
ObjConn.Close()
Console.WriteLine("Meeting sent.")
End With
Catch err As Exception
Console.WriteLine(err.ToString())
End Try
End Sub
When you use CDO to configure a recurrence pattern object, the recurrence pattern may not appear as expected in Outlook. For example, assume that you use CDO to create a "daily" meeting type with a recurrence of "weekdays." When an Outlook user views the meeting series, the recurrence pattern appears as a "weekly" meeting type together with the individual weekdays that are selected.
This is expected behavior. A daily meeting type with a recurrence of weekdays is functionally equal to a weekly meeting that has each weekday selected.