I'm trying to write a script that will take data from a Google spreadsheet and create events in my Google calendar.
I managed that fine but it produced duplicates every time I ran it. So now I'm trying to prevent that by creating a column 17 in the spreadsheet with an automatically produced unique event ID for each row and then each time the script is run it will look at the event ID for each row and delete the corresponding event in the calendar before recreating it with the original data or updated data if I've changed the row.
I'm new to scripting of any kind and cobbled this together but am hitting a wall now. Can anyone help sort this out?
function CalInsert() {
var cal = CalendarApp.getDefaultCalendar();
var id = SpreadsheetApp.getActiveSheet().getRange(2,17).getValue();
if (id != 0) {
var event = cal.getEventSeriesById(id);
event.deleteEventSeries();
}
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = sheet.getLastRow(); // Number of rows to process
var dataRange = sheet.getRange(startRow, 1, numRows, sheet.getLastColumn());
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
var title = row[0]; // First column
var desc = row[13]; // Second column
var tstart = row[14];
var tstop = row[15];
var event = cal.createEvent(title, tstart, tstop, {description:desc});
var eventid = event.getId();
SpreadsheetApp.getActiveSheet().getRange(2,17).setValue(eventid);
}
}
This is very similar to a question asked just two days ago, which was about synchronizing a spreadsheet of events with a calendar. It sounds like you want to consider the spreadsheet to be the master of events that it originates, which would simplify the problem considerably. The basics of what you need to do are covered in this answer. If you'd rather just modify existing code, I've got an implementation below.
I have a modified version of the code from this blog, that will modify pre-existing calendar entries to match the info in the spreadsheet. I have arranged my spreadsheet differently, and this is reflected in the code.
The event ID column gets filled in by the script when new events are created, and is then used in later invocations to retrieve events from the calendar, thereby avoiding duplication.
Script
Delete / Recreate
In this alternative, the eventID is used to find and delete the previously existing event. After that, a new event is created with the data in the spreadsheet. This has the benefit that all values of the event can be updated, including start and stop times (see Notes below). On the other hand, any changes that were made to the original event will be lost - for instance, if other people had been invited to the event, or custom reminders were added.
To use this alternative, simply replace the matching code with this:
Notes
getEventSeriesById
wrongly states it returnsnull
when no matching event is found, when instead it throws an exception. (nasty!) So I've enclosed it in a try / catch block just to keep on swimming.getEventSeriesById
works to retrieve an event, itreturns
anEventSeries
object, which does not support thesetTime()
method. If you don't expect to change the time of events, this OK. Otherwise, you can change theEvent
into anEventSeries
by setting the recurrence rules & times, or delete the old event and create a new one, as shown in Delete / Recreate. Issue 1154.Id like to Post this for anyone who would like to use it, I have modified the script to work within a sheet I was already using. Date Format and event duplication were a couple of issues that needed to be fixed but after some testing im pretty happy with how this is working.I Use it to Book jobs and share them with my employees who are mobile and do construction type work across the city. Next step is to pull calendar events to the spreadsheet so it can work both ways and I can use the calendar app on my phone to book jobs on the fly so if anyone has any advice im all ears, also i still need a script to insert form response data into the same sheet and add complete rows where the job numbers match keeping the existing Data intact.
`