I need to make a change to all calendars in the site. We have a big hierarchy of sites and the calendar is enabled in all sites.

I have the code to make the change I need in one list.

SPWeb web = //get the SPWeb object from somewhere 
SPList list = web.Lists["CalendarName"]; 
var field = list.Fields[SPBuiltInFieldId.WorkspaceLink]; 
field.Hidden = true; field.Update(); 

What I am missing here is the loop to iterave over all lists of all sites and 2nd, detect only the ones which type is calendar or event.


2 Answers 2


There is no need to iterate through every web, Personnaly I even think its bad.

Instead, use the SPSiteDataQuery class

SPSiteDataQuery query = new SPSiteDataQuery();

// Query all Web sites in this site collection.
query.Webs = "<Webs Scope=\"SiteCollection\">";

//Ask for all lists created from the Calendar template.
query.Lists = "<Lists ServerTemplate=\"106\" />";

DataTable dtResults = site.RootWeb.GetSiteData(query);
String[] columns = {"ListId"};
DataTable dtDistinctResults = new DataView(dtResults).ToTable(true, columns);

foreach (DataRow oRow in dtDistinctResults .Rows)
SPWeb oWeb = site.OpenWeb(new Guid(oRow["WebId"].ToString()));
SPList oList = oWeb.Lists[new Guid(oRow["ListId"].ToString())];
//peprform your changes

This is a quick example. You should only open each web ONCE ! For example the dtDisctinctResults may contain 80 rows ( = 80 lists) but these 80 lists are on 4 sites. So you should only open SPWeb 4 times, not 80 times. Since this has nothing to do with the question itselves, I leave this up to you.

To help you, I have quickly written a piece of code which would guide you in the right direction. I am not claiming this piece of code is written as it should be... http://pastie.org/3349098

This should work for you, more info on: http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spsitedataquery.lists.aspx

PS: It might be possible that you need to assign more properties of the query class. here is my working example for tasks which are not completed:

SPSiteDataQuery oQuery = new SPSiteDataQuery();
oQuery.Lists = "<Lists ServerTemplate='107' />";
oQuery.Query = "<Where><Neq><FieldRef Name='" + "Status" + "' /><Value Type='Text'>" + "Completed" + "</Value></Neq></Where>";
oQuery.Webs = "<Webs Scope='SiteCollection' />";

Above code will return all ListItems (which are not completed) in task lists

  • great solution, thx Feb 9, 2012 at 14:56
  • really cool option. I didn't know it. :)
    – Alex Boev
    Feb 9, 2012 at 15:05
  • I haven't tested the performance of this solution vs iteration over all webs+lists. But my guess is this is alot quicker. Feb 9, 2012 at 15:07
  • I've updated the code, since it contained some problems for this example Feb 9, 2012 at 15:46
  • Frederik, I don't understand this - SPList oList = oWeb.Lists[new Guid(oRow["ListId"].ToString())]; It seems you works with lists from a single web.
    – Alex Boev
    Feb 9, 2012 at 15:51

SPSite.AllWebs collection is a plain collection of all webs in site collection. Note that you must dispose webs obtained from that collection. For each obtained SPWeb you can iterate through list via SPWeb.Lists property. You can filter lists by SPList.BaseTemplate property - for calendar lists it will be equal to SPListTemplateType.Events.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.