Programmatically add a recurring event to a MOSS 2007 (SharePoint) Calendar
The following function was designed to add an event to a calendar. Note that I had a custom Category choice field in my calendar, so the line where you set the Category field is commented out so the function will work with a standard MOSS 2007 calendar.
Sample Usage:
string strRet="";
The part that confused me was that the Date portion of the Start Date and End Date are used to determine the range of the recurrence.
The Time portions of the Start Date and End Date are used to determine the start time and end time of the event on the day it occurs. Recurring events are limited to a duration of a single calendar day.
Therefore, in the code above, I have the start date set with the current year, and the end date is the current year + 100 years to make the event recur for 100 years.
Also, note, that the Time Zone is set to GMT time in the above code. You can change this to your settings as needed.
I've made an event query page that queries for the events with recurrence:
This way, if you don't feel like figuring out what xml to add for time zone or recurrence data, you can just create the event through the GUI and then use the query page to view the XML generated by MOSS 2007 and use it in your code.
The following code could be placed somewhere in your _layouts directory and then run from the site with your calendar in it.
Note that in the code, the calendar name is called “Holiday.” You should replace that portion of the code with the name of the Calendar you want to query.
I like to use the _layouts/custom directory:
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\Custom
QueryCalendar.aspx.cs:
QueryCalendar.aspx:
/// <summary>
/// Adds a holiday event to the holiday calendar
///
/// NOTE: if you are adding a recurring event, then the date portion of the start and end date define the duration of the recurrence.
/// The time portion is the Start and End Time of the event are the start and end times of the event on a single day.
/// </summary>
/// <param name="web"></param>
/// <param name="strListName"></param>
/// <param name="StartDate"></param>
/// <param name="EndDate"></param>
/// <param name="bAllDayEvent"></param>
/// <param name="strTitle"></param>
/// <param name="strDescription"></param>
/// <param name="strCategory"></param>
/// <param name="bRecurrence"></param>
/// <param name="strRecurrenceData"></param>
/// <returns></returns>
public static string AddHolidayEvent(SPWeb web, string strListName, DateTime StartDate, DateTime EndDate, Boolean bAllDayEvent, string strTitle, string strDescription, string strCategory, Boolean bRecurrence, string strRecurrenceData)
{
string strRet = "";
try
{
SPList list = web.Lists[strListName];
if (list != null)
{
//Check if item already exists
SPQuery query = new SPQuery();
query.Query = string.Concat(
"<Where><Eq>",
"<FieldRef Name='Title' />",
"<Value Type='Text'>", strTitle, "</Value>",
"</Eq>",
"</Where>");
query.ViewFields = string.Concat("<FieldRef Name='Title' />",
"<FieldRef Name='Recurrence' />");
SPListItemCollection items = list.GetItems(query);
if (items.Count < 1)
{
SPListItem newEvent = list.Items.Add();
newEvent["Title"] = strTitle;
newEvent["Start Time"] = StartDate.ToString("yyyy-MM-dd hh:mm");
newEvent["End Time"] = EndDate.ToString("yyyy-MM-dd hh:mm");
newEvent["Description"] = strDescription;
// newEvent["Category"] = strCategory;
newEvent["All Day Event"] = bAllDayEvent;
newEvent["TimeZone"] = 0;
if (bRecurrence == true)
{
newEvent["Recurrence"] = -1;
newEvent["RecurrenceData"] = strRecurrenceData;
newEvent["UID"] = System.Guid.NewGuid();
newEvent["Event Type"] = 1; //Must be 1. MOSS 2007 sets this automatically.
newEvent["Order"] = 100;
newEvent["XMLTZone"] = "<timeZoneRule><standardBias>0</standardBias><additionalDaylightBias>0</additionalDaylightBias></timeZoneRule>";
}
else
{
newEvent["Recurrence"] = false;
}
web.AllowUnsafeUpdates = true;
newEvent.Update();
newEvent.ParentList.Update();
web.AllowUnsafeUpdates = false;
}
else
{
strRet += strTitle + " is already in the list.<br />";
return strRet;
}
}
return strRet+"Added " + strTitle + " holiday.<br />";
}
catch (Exception ex)
{
return strRet+"Error occurred adding event: " + ex.Message + "<br />";
}
}Sample Usage:
string strRet="";
string strRecur="<recurrence><rule><firstDayOfWeek>su</firstDayOfWeek><repeat><yearlyByDay yearFrequency=\"1\" mo=\"TRUE\" weekdayOfMonth=\"second\" month=\"10\" /></repeat><repeatForever>FALSE</repeatForever></rule></recurrence>";
strRet+= AddHolidayEvent(web, "Holiday", new DateTime(DateTime.Now.Year, 10, 1), new DateTime(DateTime.Now.Year+100, 10, 1), true, "Columbus Day", "Columbus Day", "US Holiday", true, strRecur);
strRecur = "<recurrence><rule><firstDayOfWeek>su</firstDayOfWeek><repeat><yearly yearFrequency=\"1\" month=\"11\" day=\"11\"/></repeat><repeatForever>TRUE</repeatForever></rule></recurrence>";
strRet+=AddHolidayEvent(web, "Holiday", new DateTime(DateTime.Now.Year, 11, 11), new DateTime(DateTime.Now.Year+100, 11, 11), true, "Veteran's Day", "Veteran's Day", "US Holiday", true, strRecur);
The part that confused me was that the Date portion of the Start Date and End Date are used to determine the range of the recurrence.
The Time portions of the Start Date and End Date are used to determine the start time and end time of the event on the day it occurs. Recurring events are limited to a duration of a single calendar day.
Therefore, in the code above, I have the start date set with the current year, and the end date is the current year + 100 years to make the event recur for 100 years.
Also, note, that the Time Zone is set to GMT time in the above code. You can change this to your settings as needed.
I've made an event query page that queries for the events with recurrence:
This way, if you don't feel like figuring out what xml to add for time zone or recurrence data, you can just create the event through the GUI and then use the query page to view the XML generated by MOSS 2007 and use it in your code.
The following code could be placed somewhere in your _layouts directory and then run from the site with your calendar in it.
Note that in the code, the calendar name is called “Holiday.” You should replace that portion of the code with the name of the Calendar you want to query.
I like to use the _layouts/custom directory:
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\Custom
QueryCalendar.aspx.cs:
using System;
using System.Collections;
using System.Configuration;
using System.Data;
//using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
//using System.Xml.Linq;
using Microsoft.SharePoint;
using System.Text;
public partial class _QueryCalendar : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (txtCalendarDate.Text == "")
{
txtCalendarDate.Text = DateTime.Now.ToString("yyyy-MM-dd");
}
}
protected void btnQueryCalendar_Click(object sender, EventArgs e)
{
using (SPSite site = new SPSite(SPContext.Current.Web.Url))
{
using (SPWeb web = site.OpenWeb())
{
StringBuilder sbRet = new StringBuilder();
try
{
SPList list = web.Lists["Holiday"];
sbRet.Append("Found list...<br />");
SPQuery query = new SPQuery();
query.Query = string.Concat(
"<Where><DateRangesOverlap>",
"<FieldRef Name='EventDate' />",
"<FieldRef Name='EndDate' />",
"<FieldRef Name='RecurrenceID' />",
"<Value Type='DateTime'>",
"<Year />",
"</Value>",
"</DateRangesOverlap>",
"</Where>");
query.ExpandRecurrence = true;
try
{
query.CalendarDate = DateTime.Parse(txtCalendarDate.Text);
}
catch (Exception ex)
{
sbRet.Append("INVALID CALENDAR DATE: " + ex.Message + "<br /> Using default ("+DateTime.Now.ToString("yyyy-mm-dd")+")...");
query.CalendarDate = DateTime.Now;
}
sbRet.Append("Querying list using Calendar Date: "+query.CalendarDate.ToString("yyyy-MM-dd")+"<br />");
SPListItemCollection items = list.GetItems(query);
if (items == null)
{
sbRet.Append("Null returned.");
}
else
{
sbRet.Append("Items not null.<br />");
}
sbRet.Append("List queried...<br />");
sbRet.Append("Item Count: " + items.Count.ToString() + "<br />");
sbRet.Append("End ItemCount<br />");
sbRet.Append("<table border='1' style='border-collapse: collapse;'><tr>");
foreach (SPField field in items.List.Fields)
{
sbRet.Append("<td>" + field.Title + "["+field.InternalName+"]"+"</td>");
}
sbRet.Append("</tr>");
foreach (SPListItem item in items)
{
sbRet.Append("<tr>");
foreach (SPField field in items.List.Fields)
{
if (item[field.Title] != null)
{
sbRet.Append("<td>" + Server.HtmlEncode(item[field.Title].ToString()) + "</td>");
}
else
{
sbRet.Append("<td>[null]</td>");
}
}
sbRet.Append("</tr>");
}
sbRet.Append("</table>");
lblOutput.Text = sbRet.ToString();
}
catch (Exception ex)
{
lblOutput.Text = "Error occurred: " + ex.Message +"<br />"+ sbRet.ToString();
}
}
}
}
}
QueryCalendar.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="QueryCalendar.aspx.cs" Inherits="_QueryCalendar" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Calendar Query</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<br />
Calendar Date: <asp:TextBox ID="txtCalendarDate" runat="server"></asp:TextBox><br />
<asp:Button ID="btnQueryCalendar" runat="server"
Text="QueryCalendar" onclick="btnQueryCalendar_Click" />
<br />
<div style="border: solid 1px silver; padding: 5px;">
<asp:Label ID="lblOutput" runat="server" Text=""></asp:Label>
</div>
</div>
</form>
</body>
Comments
Post a Comment