Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

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.

Thx

share|improve this question

2 Answers 2

up vote 4 down vote accepted

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

share|improve this answer
    
great solution, thx –  Esteban V Feb 9 '12 at 14:56
    
really cool option. I didn't know it. :) –  Alex Boev Feb 9 '12 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. –  Frederik P. Feb 9 '12 at 15:07
    
I've updated the code, since it contained some problems for this example –  Frederik P. Feb 9 '12 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 '12 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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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