Geeks With Blogs
David Jacobus SharePoint Consultant

Wow! did, I have a comeuppance when, I tried to use this previous blog post with real data!  Problem, No Recurring Events!  SPSiteDataQuery does not return recurring events!  Darn!   So not to be denied, I took a look on how to make this work!  We can do this and do it with a Sandbox Solution! The gist of the problem is that we need to do merge of each lists DataTable.  DataTable has a merge method!    The great timesaver here is that SPListItemCollection has a built-in method  GetDataTable(); Here is a summary of how to modify this solution to make it work in the sandbox:

  1. Create an Event Receiver on ItemAdded  which Adds ListID and WebID to the list Item (we will need these later)
  2. Create a method to return ListID and WebID from ContentType using SPSiteDataQuery (Much more difficult in a sandbox solution vice a Farm Solution as a Farm Solution can use IList usages = SPContentTypeUsage.GetUsages(CT) which is not available in the sandbox).
  3. Create a method to to return a DataTable using SPQuery, which allows Recurring Events.
  4. Merge the DataTables.

Here is the Code for the Event Receiver:

 public override void ItemAdded(SPItemEventProperties properties)
        {

            base.ItemAdded(properties);

            using (SPSite site = properties.OpenSite())
            {
                using (SPWeb web = site.OpenWeb())
                {
                    using (DisabledEventsScope scope = new DisabledEventsScope())
                    {

                        SPListItem listItem = properties.ListItem;

                        listItem["ListID"] = listItem.ParentList.ID;
                        listItem["WebID"] = web.ID;
                        listItem.Update();
                    }

                }
            }
        }

 

Here is the code to get unique list ID’s:

       public static List getListID2s(SPWeb web)
        {
            
            List lists = new List();
            var query = new SPSiteDataQuery();
            SPContentType cTypeCollection = web.ContentTypes["RollUpCalendar"];





            string where = string.Format(
                              @"
                   
                       
                             {0}
                    

                 
", cTypeCollection.Id);

            // Set the query string.
            query.Query = where;
           query.ViewFields = "";
           query.ViewFields += "";


            query.Webs = "";

           DataTable results = web.GetSiteData(query);
           DataTable view = results.DefaultView.ToTable(true, "ListId","WebID");

          foreach (DataRow row in view.Rows)
          {

              string listid = String.Format("{1};{0}", row["WebID"], row["ListId"]);
              lists.Add(listid);
          }
            return lists;
        }

 

Used to return Distinct Rows.  As we only want distinct webs, and lists.

Here is the code to get the events by site:

 

    public static DataTable getSiteData(SPWeb web, string listID)
        {

            //listID is the string url + ; + listID
            Guid guid = new Guid(listID.ToString().Substring(0, listID.LastIndexOf(";")));
            string webguid = listID.ToString().Substring(listID.LastIndexOf(";") + 1);


            SPList list;
            using (SPSite site = new SPSite(web.Site.ID))
            {
                using (SPWeb subWeb = site.OpenWeb(new Guid(webguid)))
                {

                    list = subWeb.Lists[guid];
                }
            }

            SPQuery query = new SPQuery();
            query.Query = @"
                                
                                ";
            query.ViewFields = "";
            query.ViewFields += "";
            query.ViewFields += "";
            query.ViewFields += "";
            query.ViewFields += "";
            query.ViewFields += "";
            query.ViewFields += "";
            query.ViewFields += "";
            query.ViewFields += "";
            query.ViewFields += "";
            query.ViewFields += "";
            query.ExpandRecurrence = true;
            query.RowLimit = 1000;
            SPListItemCollection col = list.GetItems(query);
            

            return list.GetItems(query).GetDataTable();
        }
 
To tie it all together and get all the events(including recurring) in the site collection:
 

IList lists = Utilities.getListID2s(web);
                
                  DataTable master = new DataTable();

                  foreach (string l in lists)
                  {
                      DataTable results = Utilities.getSiteData(web, l);
                      master.Merge(results);

                  }

Notice how the DataTable is merged  then use the DataTable master as the source for the Full Calendar events.  Here is a calendar at the top level with a single event:

 

image

 

Here is a Calendar in a sub site with a recurring event:

image

Here is the Full Calendar Roll Up Web Part:

image

Took me awhile to get the workarounds to work!  But we do have a Sandbox web part that can roll up the calendar in the entire site collection!  I will update the Codeplex solution soon to include this new code.  I just need to remove all Client References from my current code.

Posted on Wednesday, July 9, 2014 2:39 PM | Back to top


Comments on this post: Full Calendar III SharePoint 2010 Sandbox Solution (Not SharePoint Online) Corporate Rollup Calendar

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © David Jacobus | Powered by: GeeksWithBlogs.net