<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
		>
<channel>
	<title>Comments on: Updating Google Calendars from a Google Spreadsheet</title>
	<atom:link href="http://blog.ouseful.info/2010/03/04/maintaining-google-calendars-from-a-google-spreadsheet/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.ouseful.info/2010/03/04/maintaining-google-calendars-from-a-google-spreadsheet/</link>
	<description>Trying to find useful things to do with emerging technologies in open education</description>
	<lastBuildDate>Sat, 18 May 2013 11:27:16 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
	<item>
		<title>By: Subigya</title>
		<link>http://blog.ouseful.info/2010/03/04/maintaining-google-calendars-from-a-google-spreadsheet/#comment-41860</link>
		<dc:creator><![CDATA[Subigya]]></dc:creator>
		<pubDate>Mon, 13 May 2013 10:37:21 +0000</pubDate>
		<guid isPermaLink="false">http://ouseful.wordpress.com/?p=2983#comment-41860</guid>
		<description><![CDATA[Thanks a lot for this! I made an SMS alert system using Spreadsheet and Calendar.]]></description>
		<content:encoded><![CDATA[<p>Thanks a lot for this! I made an SMS alert system using Spreadsheet and Calendar.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Google Calendar / Spreadsheet reciprocity script with Gscript &#124; appsgoogleplus.com</title>
		<link>http://blog.ouseful.info/2010/03/04/maintaining-google-calendars-from-a-google-spreadsheet/#comment-37460</link>
		<dc:creator><![CDATA[Google Calendar / Spreadsheet reciprocity script with Gscript &#124; appsgoogleplus.com]]></dc:creator>
		<pubDate>Mon, 01 Apr 2013 15:40:00 +0000</pubDate>
		<guid isPermaLink="false">http://ouseful.wordpress.com/?p=2983#comment-37460</guid>
		<description><![CDATA[[...] http://blog.ouseful.info/2010/03/04/maintaining-google-calendars-from-a-google-spreadsheet/ [...]]]></description>
		<content:encoded><![CDATA[<p>[...] <a href="http://blog.ouseful.info/2010/03/04/maintaining-google-calendars-from-a-google-spreadsheet/" rel="nofollow">http://blog.ouseful.info/2010/03/04/maintaining-google-calendars-from-a-google-spreadsheet/</a> [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: nparson</title>
		<link>http://blog.ouseful.info/2010/03/04/maintaining-google-calendars-from-a-google-spreadsheet/#comment-29261</link>
		<dc:creator><![CDATA[nparson]]></dc:creator>
		<pubDate>Mon, 10 Dec 2012 23:12:53 +0000</pubDate>
		<guid isPermaLink="false">http://ouseful.wordpress.com/?p=2983#comment-29261</guid>
		<description><![CDATA[Hi, thanks for the reply. I ended finding the problem in the missing parenthetical and I simplified the script so it just updates the calendar like i needed. 

thanks again for the help]]></description>
		<content:encoded><![CDATA[<p>Hi, thanks for the reply. I ended finding the problem in the missing parenthetical and I simplified the script so it just updates the calendar like i needed. </p>
<p>thanks again for the help</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: cheney</title>
		<link>http://blog.ouseful.info/2010/03/04/maintaining-google-calendars-from-a-google-spreadsheet/#comment-29258</link>
		<dc:creator><![CDATA[cheney]]></dc:creator>
		<pubDate>Mon, 10 Dec 2012 21:46:14 +0000</pubDate>
		<guid isPermaLink="false">http://ouseful.wordpress.com/?p=2983#comment-29258</guid>
		<description><![CDATA[Sure, feel free to share the workbook with me at: cjoseph@cmredis.com, and i&#039;ll take a look at it. It may be helpful if you go ahead and share the calendar as well.]]></description>
		<content:encoded><![CDATA[<p>Sure, feel free to share the workbook with me at: <a href="mailto:cjoseph@cmredis.com">cjoseph@cmredis.com</a>, and i&#8217;ll take a look at it. It may be helpful if you go ahead and share the calendar as well.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: nparson</title>
		<link>http://blog.ouseful.info/2010/03/04/maintaining-google-calendars-from-a-google-spreadsheet/#comment-29206</link>
		<dc:creator><![CDATA[nparson]]></dc:creator>
		<pubDate>Sat, 08 Dec 2012 17:09:31 +0000</pubDate>
		<guid isPermaLink="false">http://ouseful.wordpress.com/?p=2983#comment-29206</guid>
		<description><![CDATA[Hi cheney,

Thanks for posting this script. This is exactly what I was looking for. One question... I continue to get the following error when pasting your script into the spreadsheet script editor. 

&quot;Missing ) in parenthetical. (line 72)&quot; Can you offer me any help with this? I&#039;ve done my best to solve the syntax error but I&#039;m beginner with google apps script.

Thanks,]]></description>
		<content:encoded><![CDATA[<p>Hi cheney,</p>
<p>Thanks for posting this script. This is exactly what I was looking for. One question&#8230; I continue to get the following error when pasting your script into the spreadsheet script editor. </p>
<p>&#8220;Missing ) in parenthetical. (line 72)&#8221; Can you offer me any help with this? I&#8217;ve done my best to solve the syntax error but I&#8217;m beginner with google apps script.</p>
<p>Thanks,</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: cheney</title>
		<link>http://blog.ouseful.info/2010/03/04/maintaining-google-calendars-from-a-google-spreadsheet/#comment-28295</link>
		<dc:creator><![CDATA[cheney]]></dc:creator>
		<pubDate>Thu, 25 Oct 2012 16:28:21 +0000</pubDate>
		<guid isPermaLink="false">http://ouseful.wordpress.com/?p=2983#comment-28295</guid>
		<description><![CDATA[These our my column headers that pull into the workbook in order:

[Flagged for Discussion,Title,Title,Resource,Notes,Status,Category,Start Date,Duration,End Date,Worksheet Link,Last Modified]
Handled in discussion for calendar event, in this order:
Notes:
Resource:
Status:
Category:
Flagged for Discussion:]]></description>
		<content:encoded><![CDATA[<p>These our my column headers that pull into the workbook in order:</p>
<p>[Flagged for Discussion,Title,Title,Resource,Notes,Status,Category,Start Date,Duration,End Date,Worksheet Link,Last Modified]<br />
Handled in discussion for calendar event, in this order:<br />
Notes:<br />
Resource:<br />
Status:<br />
Category:<br />
Flagged for Discussion:</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: cheney</title>
		<link>http://blog.ouseful.info/2010/03/04/maintaining-google-calendars-from-a-google-spreadsheet/#comment-28294</link>
		<dc:creator><![CDATA[cheney]]></dc:creator>
		<pubDate>Thu, 25 Oct 2012 16:12:42 +0000</pubDate>
		<guid isPermaLink="false">http://ouseful.wordpress.com/?p=2983#comment-28294</guid>
		<description><![CDATA[Here&#039;s an updated version of the code I post. I&#039;ve cleaned up the code, and added some comments, the biggest change is now I pull multiple columns into the description, so those can be updated in both places but the spreadsheet will keep the columns organized. It was the best solution I could think of without being able to add actual fields to the calendar event. I also put in some code to replace variations of initials and first names, my solution was hardcoded after I gave up finding a better way to do it, I would love to hear some suggestions on how to handle that batter. Hopefully this helps someone looking for something similiar to what I needed, I still have to work this in at a more global level to our task tracking workbooks, so I may or may not have another major update. I&#039;m getting a funky extra title row, but won&#039;t be able to revisit it until next week, I think I need to exclude a header row in one of the for loops.

Hopefully someone finds this useful, suggestions welcomed:

function onOpen() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var menuEntries = [ {name: &quot;Sync Spreadsheet to Calendar&quot;, functionName: &quot;calsync&quot;},
                    {name: &quot;Clear Calendar&quot;, functionName: &quot;clearcalendar&quot;}];
                    //{name: &quot;Sync&quot;, functionName: &quot;myimport&quot;}];
  ss.addMenu(&quot;Calendar Sync&quot;, menuEntries);
}

function calsync() 
{
//  // Here are the steps the script follows
//  1.Builds events array from calendar, if null ignores, i add a feature, or facility on a sheet level with a template sheet, so 
//  2.Get calendar from sheet, combine columns, and add headers so that many columns fit in description
//  3. Concatenate arrays
//  4.Filter for last modified, take most recent data
//  5. replace initials or first name with full name
//  6. array is ready to be sent back to calendar
//  7. split out columns based on header (currently it depends on the order, I would like to be able to find based on header and header rank, and then send them in the standard order,
//      but since no one is adding new calendar events, just edditing its not a big deal.
//  Just a side note, I use the flagged for discussion column to query all sheets on all workbooks where a team member would like to raise issue, to achieve maximum visibility on questions/concerns.
  
  var myCalendar = CalendarApp.openByName(&quot;Test2&quot;);
  var events = myCalendar.getEvents(new Date(&quot;January 1, 2011 EST&quot;), 
      new Date(&quot;January 1, 2014 EST&quot;));
  if (events[0]) {
    var eventarray = new Array();
    var line = new Array();
    line.push(&#039;Title&#039;);
    line.push(&#039;Start Date&#039;);
    line.push(&#039;End Date&#039;);
    line.push(&#039;Description&#039;);
    line.push(&#039;Last Modified&#039;);
    eventarray.push(line);
    
    var i = 0;
    for (i = 0; i &lt; events.length; i++) {
      line = new Array();
      line.push(events[i].getTitle());
      line.push(events[i].getStartTime());
      line.push(events[i].getEndTime());
      line.push(events[i].getDescription());
      line.push(events[i].getLastUpdated());

      eventarray.push(line);
    }
 } 

    var mySpreadsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(&quot;Test2&quot;);
    var last_row = mySpreadsheet.getLastRow();
    var last_column = mySpreadsheet.getLastColumn();
    var dataRange = mySpreadsheet.getRange(&quot;A2:&quot;+last_column+last_row);
    var data = dataRange.getValues();
   
  if (data[0]) {
    var dataarray = new Array();
    var line2 = new Array();
    
    var j = 0;
    for (j = 0; j  0) {
    if (typeof columnIndex != &quot;number&quot; &#124;&#124; columnIndex &gt; data[0].length) {
      throw &#039;Choose a valide column index&#039;;
    }
    var r = new Array();
    var areDates = true;
    for (var i = 0; i &lt; data.length; i++) {
      var date = new Date(data[i][columnIndex]);
      if (isNaN(date.getYear()) &amp;&amp; data[i][columnIndex] != &#039;&#039;) areDates = false;
      else if (data[i][columnIndex] != &#039;&#039;) data[i][columnIndex] = date;
      r.push(data[i]);
    }
    return r.sort(function (a, b) {
      if (ascOrDesc) return ((a[columnIndex] &lt;b&gt; b[columnIndex]) ? 1 : 0));
      return ((a[columnIndex] &gt; b[columnIndex]) ? -1 : ((a[columnIndex] &lt;b&gt; 0){
  var i = 0;
  var dataArray = new Array();
  var line = new Array();
    line.push(&#039;Title&#039;);
    line.push(&#039;Start Date&#039;);
    line.push(&#039;End Date&#039;);
    line.push(&#039;Description&#039;);
    line.push(&#039;Last Modified&#039;);
    dataArray.push(line);
  for (i = 0; i &lt; data.length; i++) {
  line = new Array();
  var  row = data[i];
    var temp = row[3];// for the initial replacement my solution is unacceptable longterm, I have to add people individually I know I could just do a simple table,
//    but I wanted to cover variation so from a spreadsheet I build out what I paste in, it&#039;s replace.(Resource: Initials, Full Name) or replace.(firstname) for everyone and all likely variations.... 
//    it ends up being a very long line of code, suggestions welcomed!
    line.push(row[0]);
    line.push(row[1]);
    line.push(row[2]);
    line.push(temp);
    line.push(row[4]);
    dataArray.push(line);
  }
}
  UpdateCalendar(dataArray);
  Logger.log(dataArray);
  
   var dataarray2 = new Array();
    var line2 = new Array();
    line2.push(&#039;Flagged for Discussion&#039;)
    line2.push(&#039;Title&#039;);
    line2.push(&#039;Title&#039;);
    line2.push(&#039;Resource&#039;);
    line2.push(&#039;Notes&#039;);
    line2.push(&#039;Status&#039;);
    line2.push(&#039;Category&#039;);
    line2.push(&#039;Start Date&#039;);
    line2.push(&#039;Duration&#039;);
    line2.push(&#039;End Date&#039;);
    line2.push(&#039;Worksheet Link&#039;);
    line2.push(&#039;Last Modified&#039;);       
    dataarray2.push(line2); 

    var j = 0;
    for (j = 1; j &lt; data.length; j++) {
      line2 = new Array();
      var row = dataArray[j];
      
      var length = row[3].length;
      var locnotes = row[3].indexOf(&#039;Notes:&#039;);
      var locresource = row[3].indexOf(&#039;Resource:&#039;);
      var locstatus = row[3].indexOf(&#039;Status:&#039;)
      var loccategory= row[3].indexOf(&#039;Category: &#039;)
      var locflagged = row[3].indexOf(&#039;Flagged for Discussion:&#039;);
      var locwslink = row[3].indexOf(&#039;Worksheet Link:&#039;);
      
      var splittitle = row[0].split(&quot;- &quot;);
      var shorttitle = splittitle[2];
      Logger.log(shorttitle);
     
      var notes = row[3].slice(&quot;notes: &quot;.length+locnotes,locresource);
      var resource = row[3].slice( &quot;resource: &quot;.length+locresource,locstatus);
      var status = row[3].slice(&quot;status: &quot;.length+locstatus,loccategory);//will be ,loccategory); if we add it
      var category = row[3].slice(&quot;category: &quot;.length+loccategory,locflagged);
      var flagged = row[3].slice(&quot;Flagged for Discussion: &quot;.length+locflagged,locwslink);     
      var worksheetlink = row[3].slice(&quot;Worksheet Link: &quot;.length+locwslink,length);
 
      line2.push(flagged);
      line2.push(row[0]);
      line2.push(splittitle[2]);
      line2.push(resource);
      line2.push(notes);
      line2.push(status);
      line2.push(category);
      line2.push(row[1]);
      line2.push(row[2]-row[1]); //this needs to be 7 if we delete duration
      line2.push(row[2]);
      line2.push(worksheetlink);
      line2.push(row[4]);
      dataarray2.push(line2);  
    }
  UpdateSpreadsheet(dataarray2);
   var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(&quot;Test3&quot;);
  sheet.clear();
  sheet.getRange(1, 1, dataarray2.length, dataarray2[0].length).setValues(dataarray2);
}
function UpdateCalendar(data) 
{
   var myCalendar = CalendarApp.openByName(&quot;Test2&quot;);
  
  // optional - delete existing events
  var events = myCalendar.getEvents(new Date(&quot;January 1, 2011 EST&quot;), 
      new Date(&quot;January 1, 2013 EST&quot;));
  Logger.log(events);
  for (var i = 0; i &lt; events.length; i++) 
  {
     events[i].deleteEvent();
  }
  

  for (i in data) 
  {
      var row = data[i];
      // assume that each row contains a date entry and a text entry
      var theTitle  = row[0];  // First column of row
      var theStartDate = row[1];  // Second column of row
      var theEndDate = row[2];  // Third column of row
      var theDescription = row[3];  // Fourth column of row
    myCalendar.createEvent(theTitle, new Date(theStartDate),new Date(theEndDate),{description: theDescription});
  }
 
}

function UpdateSpreadsheet(data) {
 var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(&quot;Test2&quot;);
  sheet.clear();
  sheet.getRange(1, 1, data.length, data[0].length).setValues(data);
}

function ClearCalendar() 
{
   var myCalendar = CalendarApp.openByName(&quot;Test2&quot;);
  
  // optional - delete existing events
  var events = myCalendar.getEvents(new Date(&quot;January 1, 2011 EST&quot;), 
      new Date(&quot;January 1, 2013 EST&quot;));
  for (var i = 0; i &lt; events.length; i++) 
  {
     events[i].deleteEvent();
  }
}]]></description>
		<content:encoded><![CDATA[<p>Here&#8217;s an updated version of the code I post. I&#8217;ve cleaned up the code, and added some comments, the biggest change is now I pull multiple columns into the description, so those can be updated in both places but the spreadsheet will keep the columns organized. It was the best solution I could think of without being able to add actual fields to the calendar event. I also put in some code to replace variations of initials and first names, my solution was hardcoded after I gave up finding a better way to do it, I would love to hear some suggestions on how to handle that batter. Hopefully this helps someone looking for something similiar to what I needed, I still have to work this in at a more global level to our task tracking workbooks, so I may or may not have another major update. I&#8217;m getting a funky extra title row, but won&#8217;t be able to revisit it until next week, I think I need to exclude a header row in one of the for loops.</p>
<p>Hopefully someone finds this useful, suggestions welcomed:</p>
<p>function onOpen() {<br />
  var ss = SpreadsheetApp.getActiveSpreadsheet();<br />
  var menuEntries = [ {name: "Sync Spreadsheet to Calendar", functionName: "calsync"},<br />
                    {name: "Clear Calendar", functionName: "clearcalendar"}];<br />
                    //{name: &#8220;Sync&#8221;, functionName: &#8220;myimport&#8221;}];<br />
  ss.addMenu(&#8220;Calendar Sync&#8221;, menuEntries);<br />
}</p>
<p>function calsync()<br />
{<br />
//  // Here are the steps the script follows<br />
//  1.Builds events array from calendar, if null ignores, i add a feature, or facility on a sheet level with a template sheet, so<br />
//  2.Get calendar from sheet, combine columns, and add headers so that many columns fit in description<br />
//  3. Concatenate arrays<br />
//  4.Filter for last modified, take most recent data<br />
//  5. replace initials or first name with full name<br />
//  6. array is ready to be sent back to calendar<br />
//  7. split out columns based on header (currently it depends on the order, I would like to be able to find based on header and header rank, and then send them in the standard order,<br />
//      but since no one is adding new calendar events, just edditing its not a big deal.<br />
//  Just a side note, I use the flagged for discussion column to query all sheets on all workbooks where a team member would like to raise issue, to achieve maximum visibility on questions/concerns.</p>
<p>  var myCalendar = CalendarApp.openByName(&#8220;Test2&#8243;);<br />
  var events = myCalendar.getEvents(new Date(&#8220;January 1, 2011 EST&#8221;),<br />
      new Date(&#8220;January 1, 2014 EST&#8221;));<br />
  if (events[0]) {<br />
    var eventarray = new Array();<br />
    var line = new Array();<br />
    line.push(&#8216;Title&#8217;);<br />
    line.push(&#8216;Start Date&#8217;);<br />
    line.push(&#8216;End Date&#8217;);<br />
    line.push(&#8216;Description&#8217;);<br />
    line.push(&#8216;Last Modified&#8217;);<br />
    eventarray.push(line);</p>
<p>    var i = 0;<br />
    for (i = 0; i &lt; events.length; i++) {<br />
      line = new Array();<br />
      line.push(events[i].getTitle());<br />
      line.push(events[i].getStartTime());<br />
      line.push(events[i].getEndTime());<br />
      line.push(events[i].getDescription());<br />
      line.push(events[i].getLastUpdated());</p>
<p>      eventarray.push(line);<br />
    }<br />
 } </p>
<p>    var mySpreadsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(&quot;Test2&quot;);<br />
    var last_row = mySpreadsheet.getLastRow();<br />
    var last_column = mySpreadsheet.getLastColumn();<br />
    var dataRange = mySpreadsheet.getRange(&quot;A2:&quot;+last_column+last_row);<br />
    var data = dataRange.getValues();</p>
<p>  if (data[0]) {<br />
    var dataarray = new Array();<br />
    var line2 = new Array();</p>
<p>    var j = 0;<br />
    for (j = 0; j  0) {<br />
    if (typeof columnIndex != &#8220;number&#8221; || columnIndex &gt; data[0].length) {<br />
      throw &#8216;Choose a valide column index&#8217;;<br />
    }<br />
    var r = new Array();<br />
    var areDates = true;<br />
    for (var i = 0; i &lt; data.length; i++) {<br />
      var date = new Date(data[i][columnIndex]);<br />
      if (isNaN(date.getYear()) &amp;&amp; data[i][columnIndex] != &#039;&#039;) areDates = false;<br />
      else if (data[i][columnIndex] != &#039;&#039;) data[i][columnIndex] = date;<br />
      r.push(data[i]);<br />
    }<br />
    return r.sort(function (a, b) {<br />
      if (ascOrDesc) return ((a[columnIndex] <b> b[columnIndex]) ? 1 : 0));<br />
      return ((a[columnIndex] &gt; b[columnIndex]) ? -1 : ((a[columnIndex] </b><b> 0){<br />
  var i = 0;<br />
  var dataArray = new Array();<br />
  var line = new Array();<br />
    line.push(&#8216;Title&#8217;);<br />
    line.push(&#8216;Start Date&#8217;);<br />
    line.push(&#8216;End Date&#8217;);<br />
    line.push(&#8216;Description&#8217;);<br />
    line.push(&#8216;Last Modified&#8217;);<br />
    dataArray.push(line);<br />
  for (i = 0; i &lt; data.length; i++) {<br />
  line = new Array();<br />
  var  row = data[i];<br />
    var temp = row[3];// for the initial replacement my solution is unacceptable longterm, I have to add people individually I know I could just do a simple table,<br />
//    but I wanted to cover variation so from a spreadsheet I build out what I paste in, it&#039;s replace.(Resource: Initials, Full Name) or replace.(firstname) for everyone and all likely variations&#8230;.<br />
//    it ends up being a very long line of code, suggestions welcomed!<br />
    line.push(row[0]);<br />
    line.push(row[1]);<br />
    line.push(row[2]);<br />
    line.push(temp);<br />
    line.push(row[4]);<br />
    dataArray.push(line);<br />
  }<br />
}<br />
  UpdateCalendar(dataArray);<br />
  Logger.log(dataArray);</p>
<p>   var dataarray2 = new Array();<br />
    var line2 = new Array();<br />
    line2.push(&#039;Flagged for Discussion&#039;)<br />
    line2.push(&#039;Title&#039;);<br />
    line2.push(&#039;Title&#039;);<br />
    line2.push(&#039;Resource&#039;);<br />
    line2.push(&#039;Notes&#039;);<br />
    line2.push(&#039;Status&#039;);<br />
    line2.push(&#039;Category&#039;);<br />
    line2.push(&#039;Start Date&#039;);<br />
    line2.push(&#039;Duration&#039;);<br />
    line2.push(&#039;End Date&#039;);<br />
    line2.push(&#039;Worksheet Link&#039;);<br />
    line2.push(&#039;Last Modified&#039;);<br />
    dataarray2.push(line2); </p>
<p>    var j = 0;<br />
    for (j = 1; j &lt; data.length; j++) {<br />
      line2 = new Array();<br />
      var row = dataArray[j];</p>
<p>      var length = row[3].length;<br />
      var locnotes = row[3].indexOf(&#039;Notes:&#039;);<br />
      var locresource = row[3].indexOf(&#039;Resource:&#039;);<br />
      var locstatus = row[3].indexOf(&#039;Status:&#039;)<br />
      var loccategory= row[3].indexOf(&#039;Category: &#039;)<br />
      var locflagged = row[3].indexOf(&#039;Flagged for Discussion:&#039;);<br />
      var locwslink = row[3].indexOf(&#039;Worksheet Link:&#039;);</p>
<p>      var splittitle = row[0].split(&quot;- &quot;);<br />
      var shorttitle = splittitle[2];<br />
      Logger.log(shorttitle);</p>
<p>      var notes = row[3].slice(&quot;notes: &quot;.length+locnotes,locresource);<br />
      var resource = row[3].slice( &quot;resource: &quot;.length+locresource,locstatus);<br />
      var status = row[3].slice(&quot;status: &quot;.length+locstatus,loccategory);//will be ,loccategory); if we add it<br />
      var category = row[3].slice(&quot;category: &quot;.length+loccategory,locflagged);<br />
      var flagged = row[3].slice(&quot;Flagged for Discussion: &quot;.length+locflagged,locwslink);<br />
      var worksheetlink = row[3].slice(&quot;Worksheet Link: &quot;.length+locwslink,length);</p>
<p>      line2.push(flagged);<br />
      line2.push(row[0]);<br />
      line2.push(splittitle[2]);<br />
      line2.push(resource);<br />
      line2.push(notes);<br />
      line2.push(status);<br />
      line2.push(category);<br />
      line2.push(row[1]);<br />
      line2.push(row[2]-row[1]); //this needs to be 7 if we delete duration<br />
      line2.push(row[2]);<br />
      line2.push(worksheetlink);<br />
      line2.push(row[4]);<br />
      dataarray2.push(line2);<br />
    }<br />
  UpdateSpreadsheet(dataarray2);<br />
   var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(&quot;Test3&quot;);<br />
  sheet.clear();<br />
  sheet.getRange(1, 1, dataarray2.length, dataarray2[0].length).setValues(dataarray2);<br />
}<br />
function UpdateCalendar(data)<br />
{<br />
   var myCalendar = CalendarApp.openByName(&quot;Test2&quot;);</p>
<p>  // optional &#8211; delete existing events<br />
  var events = myCalendar.getEvents(new Date(&quot;January 1, 2011 EST&quot;),<br />
      new Date(&quot;January 1, 2013 EST&quot;));<br />
  Logger.log(events);<br />
  for (var i = 0; i &lt; events.length; i++)<br />
  {<br />
     events[i].deleteEvent();<br />
  }</p>
<p>  for (i in data)<br />
  {<br />
      var row = data[i];<br />
      // assume that each row contains a date entry and a text entry<br />
      var theTitle  = row[0];  // First column of row<br />
      var theStartDate = row[1];  // Second column of row<br />
      var theEndDate = row[2];  // Third column of row<br />
      var theDescription = row[3];  // Fourth column of row<br />
    myCalendar.createEvent(theTitle, new Date(theStartDate),new Date(theEndDate),{description: theDescription});<br />
  }</p>
<p>}</p>
<p>function UpdateSpreadsheet(data) {<br />
 var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(&quot;Test2&quot;);<br />
  sheet.clear();<br />
  sheet.getRange(1, 1, data.length, data[0].length).setValues(data);<br />
}</p>
<p>function ClearCalendar()<br />
{<br />
   var myCalendar = CalendarApp.openByName(&quot;Test2&quot;);</p>
<p>  // optional &#8211; delete existing events<br />
  var events = myCalendar.getEvents(new Date(&quot;January 1, 2011 EST&quot;),<br />
      new Date(&quot;January 1, 2013 EST&quot;));<br />
  for (var i = 0; i &lt; events.length; i++)<br />
  {<br />
     events[i].deleteEvent();<br />
  }<br />
}</b></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Todd</title>
		<link>http://blog.ouseful.info/2010/03/04/maintaining-google-calendars-from-a-google-spreadsheet/#comment-28224</link>
		<dc:creator><![CDATA[Todd]]></dc:creator>
		<pubDate>Mon, 22 Oct 2012 20:29:10 +0000</pubDate>
		<guid isPermaLink="false">http://ouseful.wordpress.com/?p=2983#comment-28224</guid>
		<description><![CDATA[I found a solution for updating events, with the help of Waqar Ahmad.  I&#039;ve spent the last half hour watching events disappear and then reappear on my calendar.  The code is available here:

http://stackoverflow.com/questions/13005699/how-do-i-modify-a-google-calendar-event-using-google-apps-script/13019195#13019195]]></description>
		<content:encoded><![CDATA[<p>I found a solution for updating events, with the help of Waqar Ahmad.  I&#8217;ve spent the last half hour watching events disappear and then reappear on my calendar.  The code is available here:</p>
<p><a href="http://stackoverflow.com/questions/13005699/how-do-i-modify-a-google-calendar-event-using-google-apps-script/13019195#13019195" rel="nofollow">http://stackoverflow.com/questions/13005699/how-do-i-modify-a-google-calendar-event-using-google-apps-script/13019195#13019195</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Cheney</title>
		<link>http://blog.ouseful.info/2010/03/04/maintaining-google-calendars-from-a-google-spreadsheet/#comment-28223</link>
		<dc:creator><![CDATA[Cheney]]></dc:creator>
		<pubDate>Mon, 22 Oct 2012 20:17:18 +0000</pubDate>
		<guid isPermaLink="false">http://ouseful.wordpress.com/?p=2983#comment-28223</guid>
		<description><![CDATA[I&#039;ve been looking for/working on a two way sync and here&#039;s a proof of concept I got working. It still needs to be fined tuned, but I thought I would post it in case anyone has insight in optimizing the code, and for anyone that would find it useful. Basically the code creates an array from the calendar, and the spreadsheet, combines them. Sorts it on last modified (date last updated for event, and the standard scripted last modified column for spreadsheet), removes duplicates, and submits to both the calendar (currently after deleting all events) and the spreadsheet. I was planning on adding a key, and having a list where you would type the key to remove the items from both locations, the upside being you can add spreadsheet rows from calendar and vice versa. Thanks in advance for any helpful input.
function onOpen() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var menuEntries = [ {name: &quot;Sync Spreadsheet to Calendar&quot;, functionName: &quot;calsync&quot;}];
                    //{name: &quot;Sync&quot;, functionName: &quot;myimport&quot;}];
  ss.addMenu(&quot;Calendar Sync&quot;, menuEntries);
}

function calsync() 
{
  // This function should be executed from the 
  //  spreadsheet you want to export to the calendar
  var mySpreadsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(&quot;Test123&quot;);
  
  var myCalendar = CalendarApp.openByName(&quot;Test&quot;);
  
  //calendar event array
  var events = myCalendar.getEvents(new Date(&quot;January 1, 2011 EST&quot;), 
      new Date(&quot;January 1, 2014 EST&quot;));
  if (events[0]) {
    var eventarray = new Array();
    var line = new Array();
    line.push(&#039;Title&#039;);
    line.push(&#039;Start Date&#039;);
    line.push(&#039;End Date&#039;);
    line.push(&#039;Description&#039;);
    line.push(&#039;Last Modified&#039;);
    eventarray.push(line);
    
    var i = 0;
    for (i = 0; i &lt; events.length; i++) {
      line = new Array();
      line.push(events[i].getTitle());
      line.push(events[i].getStartTime());
      line.push(events[i].getEndTime());
      line.push(events[i].getDescription());
      line.push(events[i].getLastUpdated());
      //line.push(events[i].getLocation());
      eventarray.push(line);
    }
  } else {
    Browser.msgBox(&#039;nothing between &#039; + startDate + &#039; till &#039; + endDate);
  }
  
    var dataRange = mySpreadsheet.getRange(&quot;A2:E53&quot;);
    var data = dataRange.getValues();
   
  if (data[0]) {
    var dataarray = new Array();
    var line2 = new Array();
    
    var j = 0;
    for (j = 0; j &lt; data.length; j++) {
      var row = data[j];
      line2 = new Array();
      line2.push(row[0]);
      line2.push(row[1]);
      line2.push(row[2]);
      line2.push(row[3]);
      line2.push(row[4]);
      //line.push(events[i].getLocation());
      //line.push((events[i].getEndTime() - events[i].getStartTime()) / 3600000);
      dataarray.push(line2);
    }
  } else {
    Browser.msgBox(&#039;nothing between &#039; + startDate + &#039; till &#039; + endDate);
  }
  
 var newarray = eventarray.concat(dataarray);
 uniquedata(newarray);
  
}

//found at https://developers.google.com/apps-script/articles/removing_duplicates
function uniquedata(data) { 
  var newData = new Array();
  var data2 = sort(data, 4, false);
  for(i in data2){
    var row = data2[i];
    var duplicate = false;
    for(j in newData){
      if(row[0] == newData[j][0]){
        duplicate = true;
      }
    }
    if(!duplicate){
      newData.push(row);
    }
  }
 var filtered = sort(newData, 4 , false);
  UpdateSpreadsheet(filtered);
  UpdateCalendar(filtered);
// var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(&quot;Test123&quot;);
//  sheet.clearContents();
//  sheet.getRange(1, 1, filtered.length, filtered[0].length).setValues(filtered);
}

function UpdateSpreadsheet(data) {
 var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(&quot;Test123&quot;);
  sheet.clearContents();
  sheet.getRange(1, 1, data.length, data[0].length).setValues(data);
}

function UpdateCalendar(data) 
{
   var myCalendar = CalendarApp.openByName(&quot;Test&quot;);
  
  // optional - delete existing events
  var events = myCalendar.getEvents(new Date(&quot;January 1, 2011 EST&quot;), 
      new Date(&quot;January 1, 2013 EST&quot;));
  for (var i = 0; i  0) {
    if (typeof columnIndex != &quot;number&quot; &#124;&#124; columnIndex &gt; data[0].length) {
      throw &#039;Choose a valide column index&#039;;
    }
    var r = new Array();
    var areDates = true;
    for (var i = 0; i &lt; data.length; i++) {
      var date = new Date(data[i][columnIndex]);
      if (isNaN(date.getYear()) &amp;&amp; data[i][columnIndex] != &#039;&#039;) areDates = false;
      else if (data[i][columnIndex] != &#039;&#039;) data[i][columnIndex] = date;
      r.push(data[i]);
    }
    return r.sort(function (a, b) {
      if (ascOrDesc) return ((a[columnIndex] &lt;b&gt; b[columnIndex]) ? 1 : 0));
      return ((a[columnIndex] &gt; b[columnIndex]) ? -1 : ((a[columnIndex] &lt; b[columnIndex]) ? 1 : 0));
    });
  }
  else {
    return data;
  }
}]]></description>
		<content:encoded><![CDATA[<p>I&#8217;ve been looking for/working on a two way sync and here&#8217;s a proof of concept I got working. It still needs to be fined tuned, but I thought I would post it in case anyone has insight in optimizing the code, and for anyone that would find it useful. Basically the code creates an array from the calendar, and the spreadsheet, combines them. Sorts it on last modified (date last updated for event, and the standard scripted last modified column for spreadsheet), removes duplicates, and submits to both the calendar (currently after deleting all events) and the spreadsheet. I was planning on adding a key, and having a list where you would type the key to remove the items from both locations, the upside being you can add spreadsheet rows from calendar and vice versa. Thanks in advance for any helpful input.<br />
function onOpen() {<br />
  var ss = SpreadsheetApp.getActiveSpreadsheet();<br />
  var menuEntries = [ {name: "Sync Spreadsheet to Calendar", functionName: "calsync"}];<br />
                    //{name: &#8220;Sync&#8221;, functionName: &#8220;myimport&#8221;}];<br />
  ss.addMenu(&#8220;Calendar Sync&#8221;, menuEntries);<br />
}</p>
<p>function calsync()<br />
{<br />
  // This function should be executed from the<br />
  //  spreadsheet you want to export to the calendar<br />
  var mySpreadsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(&#8220;Test123&#8243;);</p>
<p>  var myCalendar = CalendarApp.openByName(&#8220;Test&#8221;);</p>
<p>  //calendar event array<br />
  var events = myCalendar.getEvents(new Date(&#8220;January 1, 2011 EST&#8221;),<br />
      new Date(&#8220;January 1, 2014 EST&#8221;));<br />
  if (events[0]) {<br />
    var eventarray = new Array();<br />
    var line = new Array();<br />
    line.push(&#8216;Title&#8217;);<br />
    line.push(&#8216;Start Date&#8217;);<br />
    line.push(&#8216;End Date&#8217;);<br />
    line.push(&#8216;Description&#8217;);<br />
    line.push(&#8216;Last Modified&#8217;);<br />
    eventarray.push(line);</p>
<p>    var i = 0;<br />
    for (i = 0; i &lt; events.length; i++) {<br />
      line = new Array();<br />
      line.push(events[i].getTitle());<br />
      line.push(events[i].getStartTime());<br />
      line.push(events[i].getEndTime());<br />
      line.push(events[i].getDescription());<br />
      line.push(events[i].getLastUpdated());<br />
      //line.push(events[i].getLocation());<br />
      eventarray.push(line);<br />
    }<br />
  } else {<br />
    Browser.msgBox(&#039;nothing between &#039; + startDate + &#039; till &#039; + endDate);<br />
  }</p>
<p>    var dataRange = mySpreadsheet.getRange(&quot;A2:E53&quot;);<br />
    var data = dataRange.getValues();</p>
<p>  if (data[0]) {<br />
    var dataarray = new Array();<br />
    var line2 = new Array();</p>
<p>    var j = 0;<br />
    for (j = 0; j &lt; data.length; j++) {<br />
      var row = data[j];<br />
      line2 = new Array();<br />
      line2.push(row[0]);<br />
      line2.push(row[1]);<br />
      line2.push(row[2]);<br />
      line2.push(row[3]);<br />
      line2.push(row[4]);<br />
      //line.push(events[i].getLocation());<br />
      //line.push((events[i].getEndTime() &#8211; events[i].getStartTime()) / 3600000);<br />
      dataarray.push(line2);<br />
    }<br />
  } else {<br />
    Browser.msgBox(&#039;nothing between &#039; + startDate + &#039; till &#039; + endDate);<br />
  }</p>
<p> var newarray = eventarray.concat(dataarray);<br />
 uniquedata(newarray);</p>
<p>}</p>
<p>//found at <a href="https://developers.google.com/apps-script/articles/removing_duplicates" rel="nofollow">https://developers.google.com/apps-script/articles/removing_duplicates</a><br />
function uniquedata(data) {<br />
  var newData = new Array();<br />
  var data2 = sort(data, 4, false);<br />
  for(i in data2){<br />
    var row = data2[i];<br />
    var duplicate = false;<br />
    for(j in newData){<br />
      if(row[0] == newData[j][0]){<br />
        duplicate = true;<br />
      }<br />
    }<br />
    if(!duplicate){<br />
      newData.push(row);<br />
    }<br />
  }<br />
 var filtered = sort(newData, 4 , false);<br />
  UpdateSpreadsheet(filtered);<br />
  UpdateCalendar(filtered);<br />
// var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(&quot;Test123&quot;);<br />
//  sheet.clearContents();<br />
//  sheet.getRange(1, 1, filtered.length, filtered[0].length).setValues(filtered);<br />
}</p>
<p>function UpdateSpreadsheet(data) {<br />
 var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(&quot;Test123&quot;);<br />
  sheet.clearContents();<br />
  sheet.getRange(1, 1, data.length, data[0].length).setValues(data);<br />
}</p>
<p>function UpdateCalendar(data)<br />
{<br />
   var myCalendar = CalendarApp.openByName(&quot;Test&quot;);</p>
<p>  // optional &#8211; delete existing events<br />
  var events = myCalendar.getEvents(new Date(&quot;January 1, 2011 EST&quot;),<br />
      new Date(&quot;January 1, 2013 EST&quot;));<br />
  for (var i = 0; i  0) {<br />
    if (typeof columnIndex != &#8220;number&#8221; || columnIndex &gt; data[0].length) {<br />
      throw &#8216;Choose a valide column index&#8217;;<br />
    }<br />
    var r = new Array();<br />
    var areDates = true;<br />
    for (var i = 0; i &lt; data.length; i++) {<br />
      var date = new Date(data[i][columnIndex]);<br />
      if (isNaN(date.getYear()) &amp;&amp; data[i][columnIndex] != &#039;&#039;) areDates = false;<br />
      else if (data[i][columnIndex] != &#039;&#039;) data[i][columnIndex] = date;<br />
      r.push(data[i]);<br />
    }<br />
    return r.sort(function (a, b) {<br />
      if (ascOrDesc) return ((a[columnIndex] <b> b[columnIndex]) ? 1 : 0));<br />
      return ((a[columnIndex] &gt; b[columnIndex]) ? -1 : ((a[columnIndex] &lt; b[columnIndex]) ? 1 : 0));<br />
    });<br />
  }<br />
  else {<br />
    return data;<br />
  }<br />
}</b></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Pedro</title>
		<link>http://blog.ouseful.info/2010/03/04/maintaining-google-calendars-from-a-google-spreadsheet/#comment-28152</link>
		<dc:creator><![CDATA[Pedro]]></dc:creator>
		<pubDate>Fri, 19 Oct 2012 18:18:33 +0000</pubDate>
		<guid isPermaLink="false">http://ouseful.wordpress.com/?p=2983#comment-28152</guid>
		<description><![CDATA[Hi, great thread here :) i&#039;ve been trying this and took a look at the duplicated event thread, however if we want to run the script to create event A and then want to update event A again how do we do it? How do we get the eventid from the event A we just created so that we can maybe update it?

Thanks!]]></description>
		<content:encoded><![CDATA[<p>Hi, great thread here :) i&#8217;ve been trying this and took a look at the duplicated event thread, however if we want to run the script to create event A and then want to update event A again how do we do it? How do we get the eventid from the event A we just created so that we can maybe update it?</p>
<p>Thanks!</p>
]]></content:encoded>
	</item>
</channel>
</rss>
