Google sheet to auto- populate google calendar - google-apps-script

I am trying to get data from a particular google sheets to create events in google calendar. See the spreadsheet.
https://docs.google.com/spreadsheets/d/1eBEStiTKXI0YPXfQBYzqXjwwv4kZ21033TdtysxdhHI/edit?usp=sharing
Basically, when someone ticks the boxes, it creates an event for the person (row 2) at date (Col B) at 10:00:00 AEST. So for example, when some ticks the box in cell P14, it creates an event with:
name - Lily Ahadi - PC
Date of event - 16-Mar-2020
Time of event: 10:00:00
Here is the code I partially worked on and then got someone else to help and we both didnt get anywhere. I am about to give up but thought I will give a last try with stackflow experts. The code is availabe in the script editor of the sheet.
function onEdit(e) {
try {
var range = e.range;
Browser.msgBox(range);
var nameSheet = e.source.getSheetName();
var rowID = range.rowStart;
var colID = range.columnStart;
var res = e;
var oldValue = res.oldValue;
var newValue = res.value;
var data = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(nameSheet);
if (oldValue == "FALSE" && newValue == "TRUE" && nameSheet == "Master Client List"){
var category = data.getRange(3, colID).getValue();
var date = data.getRange(rowID, 2).getValue();
date = getYesterdaysDate(date)
var timeDiff = 60;
var startTime = "10:00:00";
if (category == "PC"){
var name = data.getRange(2, colID - 1).getValue();
Browser.msgBox(name+'-'+category + date);
}else{
var name = data.getRange(2, colID - 2).getValue();
}
// var startDateTime = date+' '+startTime+':00';
var startDateTime = testMoment1(date, startTime);
var endDateTime = addMins(startDateTime, timeDiff);
var event = CalendarApp.getDefaultCalendar().createEvent(name+'-'+category,
new Date(startDateTime),
new Date(endDateTime),
{description: ''});
Logger.log('Event ID: ' + event.getId());
}
}
catch(err) {
SpreadsheetApp.getUi().alert(err);
}
}
function testMoment(date, time) {
eval(UrlFetchApp.fetch('https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js').getContentText());
var date = moment(date).format('YYYY/MM/DD');
// var time = time;
// Logger.log(moment(date).format('MM/DD/YYYY'));
// tell moment how to parse the input string
var momentObj = moment(date + time, 'YYYY-MM-DDLT');
// conversion
var dateTime = momentObj.format('YYYY-MM-DDTHH:mm:ss');
return dateTime;
}
function testMoment1(date, time) {
eval(UrlFetchApp.fetch('https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js').getContentText());
// var date = moment(date).format('YYYY/MM/DD');
// var time = time;
// Logger.log(moment(date).format('MM/DD/YYYY'));
var c = new Date();
var n = c.getFullYear();
// tell moment how to parse the input string
var momentObj = moment(date + time, 'YYYY-MM-DDLT').set('year', n).add(0, 'days');
// conversion
var dateTime = momentObj.format('YYYY-MM-DDTHH:mm:ss');
// dateTime = moment(dateTime, "YYYY-MM-DDTHH:mm:ss");
return dateTime;
}
function addMins(dateTime, durationInMinutes){
eval(UrlFetchApp.fetch('https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js').getContentText());
var startTime = dateTime;
// var durationInMinutes = '120';
var endTime = moment(startTime, 'YYYY-MM-DDTHH:mm:ss').add(durationInMinutes, 'minutes').format('YYYY-MM-DDTHH:mm:ss');
return endTime;
}
function getYesterdaysDate(date1) {
var date = new Date(date1);
date.setDate(date.getDate());
var day = date.getDate();
var month = (date.getMonth()+1);
var year = date.getFullYear();
month = month < 10 ? '0'+month : month;
day = day < 10 ? '0'+day : day;
// Logger.log(date.getFullYear() + '-' + (date.getMonth()+1) + '-' + date.getDate());
return year + '/' + month + '/' + day;
}
function myFunction() {
var data=SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Master Client List');
// var s=ss.getActiveSheet();
var c=data.getLastColumn();
for (var i = 3; i <= c; i++) {
if (i%3 === 0){
var name = data.getRange(2, i).getValue();
var dob = data.getRange(1, i).getValue();
var timeDiff = 60;
var startTime = "10:00:00";
Logger.log(name);
Logger.log(name);
Logger.log(startTime);
//birthdayevent(name, dob, startTime, timeDiff)
Logger.log(name);
// break;
}
}
}

Your code has two main issues:
1. You are querying for if (oldValue == "FALSE")
If you implement into your code the line Logger.log(oldValue); you will realize that an empty checkbox will return you the value "false" and not "FALSE". You need to modfy your if condition accordingly.
2. You are trying to use UrlFetchApp on simple onEdit trigger
As specified under restrictions for simple triggers:
They cannot access services that require authorization.
This problem can be easily solved by transforming your trigger into an installable one.
For this:
Rename your function onEdit() to something different
Bind to the funciton an installable onEdit trigger as described here
After you implement those two modifications your code will run and create an event when you check a checkbox.
Now, I am not familiar enough to judge either the event parameters (data, event title) are retrieved as you desire. For troubleshooting I recommend you to log all variables - this will help you to spot any error quickly.

Related

Add events from Google sheets to google calendar

I am trying to write scirpt to add events from a spreadsheet to my google calendar. This is the script that I am using.
function addEvents() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var lr = ss.getLastRow();
var cal = CalendarApp.getCalendarById("c_fe882662e583725f15fd4faa8c8fdf5124f3affe543778ecdcf0838d6eb17f26#group.calendar.google.com")
var data = ss.getRange("A3:D"+lr).getValues();
for(var i = 0;i<data.length;i++){
cal.createEvent(data[i][2],data[i][4],data[i][5],{location: data[i][6], description: data[i][7]});
}
}
When I run the script I am getting the following error. Error Exception: Invalid argument: startTime addEvents # Code.gs:10
This is the sheet that I am using with my dates.
https://docs.google.com/spreadsheets/d/1qG68-NLnq9LscPPzlnzRLCfHFIsN3v7V5zvWiVsG0qU/edit?usp=sharing
I want the title of the event to be column C, the start time to be Column E, the endtime to be Column F, Location G, and Description H.
Modification points:
In your script, in the for loop, data[i][4],data[i][5] is used as the start and end time. And also, data[i][7] is used. But, atvar data = ss.getRange("A3:D"+lr).getValues();, 4 columns of "A" to "D" are retrieved. I thought that this might be the reason for your issue. In this case, it is required to be var data = ss.getRange("A3:H" + lr).getValues().
But, when I saw your Spreadsheet, the start and end times don't have the year and month. In this case, 1899 year is used. Please be careful about this. From your Spreadsheet, I guessed that you might have wanted to use the year, month, and date from column "A".
When my understanding of your current issue and your goal, how about the following modification?
Modified script:
function addEvents() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var lr = ss.getLastRow();
var cal = CalendarApp.getCalendarById("c_fe882662e583725f15fd4faa8c8fdf5124f3affe543778ecdcf0838d6eb17f26#group.calendar.google.com");
var data = ss.getRange("A3:I" + lr).getValues();
while (data[data.length - 1][0] == '') data.pop();
for (var i = 0; i < data.length; i++) {
var year = data[i][8].getFullYear();
var month = data[i][8].getMonth();
var date = data[i][8].getDate();
data[i][4].setFullYear(year);
data[i][4].setMonth(month);
data[i][4].setDate(date);
data[i][5].setFullYear(year);
data[i][5].setMonth(month);
data[i][5].setDate(date);
cal.createEvent(data[i][2], data[i][4], data[i][5], { location: data[i][6], description: data[i][7] });
}
}
When this script is run, the start and end times are retrieved from the columns "E" and "F", respectively. And also, the year, month, and date are retrieved from column "A". Using these values, the start and end date are created and they are used with createEvent.
When you want to use other values of year, month, and date instead of column "A", please tell me.
Note:
From your reply of This sounds promising, the sheet that I am using is actually setting up a mail merge as well and the date in column A is for the mail merge and not for the calendar. I would actually like column I to be the date for the calendar events. , I modified the above script.
From your reply of If I run this script twice (or multiple times) as I will continue to add events, it seems to duplicate the events that are already added. Any idea how to eliminate that?, I updated the above script as follows.
function addEvents() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var lr = ss.getLastRow();
var cal = CalendarApp.getCalendarById("c_fe882662e583725f15fd4faa8c8fdf5124f3affe543778ecdcf0838d6eb17f26#group.calendar.google.com");
var data = ss.getRange("A3:R" + lr).getValues();
while (data[data.length - 1][0] == '') data.pop();
var rangeList = [];
for (var i = 0; i < data.length; i++) {
if (data[i][17] == "created") continue;
var year = data[i][8].getFullYear();
var month = data[i][8].getMonth();
var date = data[i][8].getDate();
data[i][4].setFullYear(year);
data[i][4].setMonth(month);
data[i][4].setDate(date);
data[i][5].setFullYear(year);
data[i][5].setMonth(month);
data[i][5].setDate(date);
cal.createEvent(data[i][2], data[i][4], data[i][5], { location: data[i][6], description: data[i][7] });
rangeList.push(`R${i + 3}`);
}
if (rangeList.length == 0) return;
ss.getRangeList(rangeList).setValue("created");
}
Try changing this: cal.createEvent(data[i][2],data[i][4],data[i][5],{location: data[i][6], description: data[i][7]}); to this cal.createEvent(data[i][2],new Date(data[i][4]),new Date(data[i][5]),{location: data[i][6], description: data[i][7]});
Try changing this var data = ss.getRange("A3:D"+lr).getValues(); to this var data = ss.getRange("A3:H"+lr).getValues();
Try this:
function addEvents() {
const ss = SpreadsheetApp.getActive();
var sh = ss.getActiveSheet();
var cal = CalendarApp.getCalendarById("jimesteban#jimesteban.com")
var data = sh.getRange("A3:H" + sh.getLastRow()).getValues();
for (var i = 0; i < data.length; i++) {
cal.createEvent(data[i][2], data[i][4], data[i][5], { location: data[i][6], description: data[i][7] });
}
}

Script for scheduling busy times, similar to a calendar

I am working on a "vehicle scheduler" for my workplace that will display the dates and times a truck will be unavailable. Here's the link to the Google Sheets where the script runs. I have set up two example "busy times" to show what I am doing
One adjustment that was requested from me is to do 30 minute increments, but then the amount of columns gets absolutely bonkers.
I am open to any recommendations to improve this tool, even if it means something better (and free) already exists.
I appreciate your input!
See code below... (I am RIDICULOUSLY novice at coding, so be kind :)
function processForm(formObject){
var day = formObject.dow;
var vehicle = formObject.vehicle;
var jobName = formObject.job;
var driverName = formObject.driver;
var duration = formObject.duration;
var startTime = formObject.startTime;
var ampm = formObject.ampm;
var location = formObject.location;
var returnArray = [day, vehicle, jobName, driverName, duration, startTime, ampm, location]
var startTimeColumn = 0;
var startDayColumn = 2;
var sduration = startTime;
var ss = SpreadsheetApp.getActive().getSheetByName("Week View");
if (day=="Monday"){
startDayColumn = 26;
}
else if (day=="Tuesday"){
startDayColumn = 50;
}
else if (day=="Wednesday"){
startDayColumn = 74;
}
else if (day=="Thursday"){
startDayColumn = 98;
}
else if (day=="Friday"){
startDayColumn = 122;
}
else if (day=="Saturday"){
startDayColumn = 146;
}
if (ampm=="PM"){
startDayColumn+=12;
}
if (startTime==12){
startTime = 0;
}
startTimeColumn = parseInt(startTimeColumn) + parseInt(startDayColumn) + parseInt(startTime);
var columnA = ss.getRange(1,1,ss.getLastRow(),1).getValues();
for (var rr=0;rr<ss.getLastRow();rr++){
if (columnA[rr]==vehicle){
break;
}
}
rr +=1;
for (var cc=0; cc<duration; cc++){
var checkColumn = parseInt(cc) + parseInt(startTimeColumn);
if (ss.getRange(rr, checkColumn).isBlank()){}
else return "It looks like that time is booked :(";
}
var displayString = "Job: " + jobName + String.fromCharCode(10) + "Driver: " + driverName + String.fromCharCode(10) + sduration + ":00 " + ampm + String.fromCharCode(10) + location;
var merging = ss.getRange(rr,startTimeColumn,1,duration).mergeAcross();
var enterInfo = ss.getRange(rr, startTimeColumn).setValue(displayString);
if (rr % 2 == 0){
enterInfo.setBackgroundRGB(45, 114, 157);
}
else {enterInfo.setBackgroundRGB(26, 153, 136);}
enterInfo.setFontColor('white')
return "Success! Load has been booked to the scheduler.";
}
Instead of making Sheets jump thru hoops and create a interface for inserting data and a Calendar to show it, why not use Forms and Calendar to do it all?
What I have in mind
Sheets as a long-time database for Truck Information and schedules
Calendar as a way to visualize the availability of Trucks
Forms as a interface for data-input
Set-up
A Spreadsheet file with a "List of Trucks" Sheet.
A Form attached to it that allows users to insert information about the truck booking.
To make this work, I have inputted some data on out List of Trucks:
Then I associated a form with that sheet and setup some basic questions:
I also modified the forms settings to allow people to edit it on the future, this will allow us to add information to the calendar to tie an event with a response form the form.
I added a script to the Forms that populates the first question with the data from our sheets:
function populateForm() {
var form = FormApp.getActiveForm();
var TruckIdQ = form.getItems()[0];
var truckList = SpreadsheetApp.openByUrl("YOUR SHEET URL").getSheetByName("List of Trucks").getDataRange().getValues().map(function (row) { return row[0]});
truckList.shift(); //Remove header
var choices = [];
for (var i=0; i< truckList.length; i++) {
choices.push(TruckIdQ.asListItem().createChoice(truckList[i]));
}
TruckIdQ.asListItem().setChoices(choices);
}
And set it to be run when the form is opened:
After that I went back to my sheets and modified the automatic Responses sheet to have a more understandable name: "Bookings".
Now we need to create a shared calendar to put all this information on it.
I created one named "Truck Booking Calendar" in the following way:
I then created a new Script on the Forms responsible for populating the calendar with information.
function populateCalendar(e) {
var bookingCalendar = CalendarApp.getCalendarById("CALENDAR ID");
var questions = FormApp.getActiveForm().getItems();
var response = e.response.getItemResponses();
var eventDescription = "";
var truckname;
var fromDate, toDate;
var fromTime, toTime;
for (var i=0; i< questions.length; i++) {
eventDescription = eventDescription + questions[i].getTitle() + " : " + response[i].getResponse() + "\n";
switch (i) {
case 0:
//Truck Id
truckname = response[i].getResponse();
break;
case 1:
//From Date
fromDate = response[i].getResponse();
break;
case 2:
//To Date
toDate = response[i].getResponse();
break;
case 3:
//From Time
fromTime = response[i].getResponse();
break;
case 4:
//To Time
toTime = response[i].getResponse();
break;
}
}
var startDateTime = new Date(fromDate + " " + fromTime);
var endDateTime = new Date(toDate + " " + toTime);
var newEvent = bookingCalendar.createEvent("Booking "+truckname, startDateTime, endDateTime, {description:eventDescription});
newEvent.setTag("truck", truckname);
newEvent.setTag("responseId", e.response.getEditResponseUrl());
newEvent.setTag("responseUrl", e.response.getId());
}
And created a trigger for it like this:
Now, when I submit this into the form:
I get this entry on my calendar:
Hope this helps you!

How to create a counter in google sheets that would count how many times a calculated cell has changed value?

I am a beginner and need to write a script that will count the number of times that a cell, the value in which is formula-calculated (no user input) changed value over a day and then at midnight reset the count back to 0
I have tried to use the onEdit code, but it only works with user input changes and doesn't take into account when a formula changes the value of a cell, based on other values
Here is a link to a sample spreadsheet - https://docs.google.com/spreadsheets/d/1QfM764_cPbtN46oDSbGBFgVNYZ1R6dwxIs744cyRsS4/edit?usp=sharing
The column H has the Signal (Buy or Sell) which is calculated based on the prices and can change throughout the day.
The code should put the number of times the signal was on Buy or Sell throughout the day, and then reset at days end.
Any help would be really appreciated since I am very stuck on this.
EDIT
I have come up with this code, which works on one row of data:
function Counter(e) {
var ss=SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("Counter");
var r = s.getRange("H2");
var v= r.getValue();
var h = s.getRange("N2").getValue();
if(v !== h) {
var sCounter = s.getRange("I2");
var timestamprange = s.getRange("J2")
var formattedDate = Utilities.formatDate(new Date(), "GMT+5", "yyyy-MM-dd HH:mm:ss");
var counter = sCounter.getValue();
if(counter === 0) {
counter = 1;
} else {
counter ++;
}
sCounter.setValue(counter);
timestamprange.setValue(formattedDate)
;}
s.getRange(2, 14).setValue(v)
}
How can I adjust the code to make the same for the ranges "H2:H51", "I2:I51", "J2:J51" ?
EDIT 2:
I tried on my own and came up with this code, which doesn´t work:
function Test() {
var ss=SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("Counter");
var newvalues = s.getRange("H2:H51").getValues();
var oldvalues = s.getRange("N2:N51").getValues();
for(n=0;n<newvalues.length;++n){
var nv = newvalues[n][0] ;
var o = oldvalues[n][0] ;
if(nv !== o) {
var sCounter = s.getRange("I2:I51");
var timestamprange = s.getRange("J2:J51");
var formattedDate = Utilities.formatDate(new Date(), "GMT+5", "yyyy-MM-dd HH:mm:ss");
var counter = sCounter.getValues();
if(counter[n][0] === 0) {
counter[n][0] = 1;
} else {
counter[n][0] ++;
}
sCounter.setValues(counter[n][0]);
timestamprange.setValue(formattedDate);
}
}
s.getRange("N2:N51").setValues(newvalues)
}
Any ideas would be appreciated!
I have come up with an answer that works for me, I am sure that it is not optimal, but it gets the job done) Have set a trigger to run every minute. It also adds the date and time in the next column, if the counter changes value, to track the last change, if anybody should need it.
Upgrades to the code are more than welcome
The working code:
function Counter() {
var ss=SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("DataStructured");
var newvalues = s.getRange("H2:H51").getValues();
var oldvalues = s.getRange("N2:N51").getValues();
for(n=0;n<newvalues.length;++n){
var nv = newvalues[n][0];
var o = oldvalues[n][0];
if(nv !== o) {
var sCounter = s.getRange("I2:I51");
var timestamprange = s.getRange("J2:J51")
var formattedDate = Utilities.formatDate(new Date(), "GMT+5", "yyyy-MM-dd HH:mm:ss");
var counter = sCounter.getValues();
if(counter[n][0] === 0) {
counter[n][0] = 1;
} else {
counter[n][0] ++;
}
sCounter.setValues(counter);
s.getRange("J"+(n+2)).setValue(formattedDate);
}
}
s.getRange("N2:N51").setValues(newvalues)
}

Google App Script not firing every time onedit trigger is used

Google App script not firing all JavaScript pop up boxes using on edit trigger. Does not fire when a change is made to the sheet for multiple users. Also only works when it feels like it. I have set the trigger to onEdit(). My code:
function Error() {
var sheet = SpreadsheetApp.getActiveSheet();
if (sheet.getName() == "Protocal Check List 2"){
var ui = SpreadsheetApp.getUi(); // Same variations.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var active = ss.getActiveCell();
var getactive = ss.getActiveCell().getDisplayValue();
var column = ss.getActiveRange().getColumn();
var row = ss.getActiveRange().getRow();
var msg = '';
var section = sheet.getRange('C'+ row);
switch (column) {
case 9:
var msg = "error 1";
break;
case 10:
var msg = "Error 2";
break;
default:
msg = "Error";
break;
}
if(getactive == "TRUE"){
if(column >= 9 && column <= 60
){
var result = ui.alert(
"pika Says",
msg,
ui.ButtonSet.YES_NO);
// Process the user's response.
if (result == ui.Button.YES) {
// User clicked "Yes".
window.alert('Task Complete: \n\n' + msg);
active.setValue('True');
} else {
var i = 0;
while (i < 1) {
var result = ui.prompt(
'Please detail cause of the problem:',
ui.ButtonSet.OK);
var text = result.getResponseText();
var textcount = text.length;
if(textcount > 0) {
i++;
}}
var cell = "H" + row;
var emailAddress = "email#gmail.com";
var d = new Date();
var n = d.toDateString();
var t = d.toTimeString();
var staffname = ss.getRange(cell).getValues();
var message = "Date: " + n +"\n\nTime: " + t +"\n\nStaff: " + staffname + "\n\nError: " + msg + "\n\nProblem: " + text;
var subject = msg;
var thedate = n + " / " + t;
ss.getRange('A1').setValue(thedate);
ss.getRange('B1').setValue(staffname);
ss.getRange('C1').setValue(msg);
ss.getRange('D1').setValue(text);
var s1 = ss.getRange('A1:D1'); //assign the range you want to copy
var s1v = s1.getValues();
var tss = SpreadsheetApp.openById('1mOzdRgKxiP5iB9j7PqUWKKo5oymWuAeQZ1jJ1s6qL9E'); //replace with destination ID
var ts = tss.getSheetByName('AB Protocal'); //replace with destination Sheet tab name
ts.getRange(ts.getLastRow()+1, 1, 1,4).setValues(s1v); //you will need to define the size of the copied data see getRange()
MailApp.sendEmail(emailAddress, subject, message);
// User clicked "No" or X in the title bar.
//ui.alert("The following note has been sent to the Duty Manager: \n\n" + text);
active.setValue('FALSE');
}}}}
}
Any help would be appreciated. I need it to run every signal time for users who have access to the sheet.
You'll have to
assume that onEdit triggers are best-effort, but may not catch all
edits done to the spreadsheet.
Bug thread is here.
To get around the bug as mentioned by Edward implemente a dumb router.
// create a new file -> router.gs
function routerOnEdit(e) {
myOnEditHook1(e);
myOnEditHook2(e);
myOnEditHook3(e);
}
I have submitted an issue, which is the updated version of a long-running 7 year issue. They closed it in 2022, saying the feature is intended. They have now added a feature where onEdit can queue up to 2 trigger events. The issue I'm having is that the second edit still does not trigger. Despite what the documentation says.
Note: The onEdit() trigger only queues up to 2 trigger events.
View the new issue here: https://issuetracker.google.com/issues/221703754

Google Calendar Event ID Created Can't Find Event Listed -- App Script/Sheets

I have a script which has been running for almost 2 years. I update the sheet with dates and either the event is deleted/created or a new one is created.
This last time I went through and added my dates its normal it populates the sheet cell with the event id and I am on my merry way -- however when I go to the calendar nothing shows up for that date/time.
Is there something I am missing like a new permission -- there are no errors thrown -- nothing in the logs. I have an event id but I dont know how to check what is showing up as I cannot see it on the calendar -- Is there a way to check the event id and see what it contains.
The sheet (I separated with pipes)
Subject|Start Date|Start Time|End Date|End Time|All day event|Meeting Organizer|Description|Location|Reminder Date|Reminder Time|Show time as|Event ID|Status
Survey Edit: Science of HC Delivery|08/07/2017|12:00:00 AM|8/7/2017|12:00:00 PM|TRUE|Seamore Butz|||8/7/2017|9:00:00 AM|3 sg5a7jsakgbj8g5rejeos15lhc#google.com|y
function pushToCalendar()
{
//spreadsheet variables
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
/*
getRange (row,column,optNumRows,optNumColumns)
row --- int --- top row of the range
column --- int--- leftmost column of the range
optNumRows --- int --- number of rows in the range.
optNumColumns --- int --- number of columns in the range
*/
var range = sheet.getRange(2,1,lastRow,13);
var values = range.getValues();
//calendar variables
// xxxxxxxxxxxxxxxxxxxxxxxxxx#group.calendar.google.com
var calendar = CalendarApp.getCalendarById('xxxxxxxxxxxxxxxxxxxxx#group.calendar.google.com')
var numValues = 0;
for (var i = 0; i < values.length; i++)
{
//check to see if name and type are filled out - date is left off because length is "undefined"
if (values[i][0].length > 0)
{
//check if it's been entered before
if (values[i][13] == undefined)
{
//create event https://developers.google.com/apps-script/class_calendarapp#createEvent
var newEventTitle = values[i][0];
Logger.log(newEventTitle);
var dateStart = values[i][1];
var timeStart = values[i][2];
var dateFinish = values[i][3];
var timeFinish = values[i][4];
var startDateTime = new Date(dateStart+" "+timeStart);
startDateTime.setDate(startDateTime.getDate());
startDateTime.setMonth(startDateTime.getMonth());
startDateTime.setYear(startDateTime.getYear());
startDateTime.setTime(startDateTime.getTime());
var stopDateTime = new Date(dateFinish+" "+timeFinish);
stopDateTime.setDate(stopDateTime.getDate());
stopDateTime.setMonth(stopDateTime.getMonth());
stopDateTime.setYear(stopDateTime.getYear());
stopDateTime.setTime(stopDateTime.getTime());
var description = (values[i][7] == '' ? 'Test Description '+i : values[i][7]);
var location = (values[i][8] == '' ? 'Test Location '+i : values[i][8]);
Logger.log(description);
Logger.log(location);
//var newEvent = calendar.createAllDayEvent(newEventTitle, values[i][1]);
var newEvent = calendar.createEvent(newEventTitle, startDateTime, stopDateTime, {description:description,location:location});
//get ID
var newEventId = newEvent.getId();
//mark as entered, enter ID
sheet.getRange(i+2,14).setValue('y');
sheet.getRange(i+2,13).setValue(newEventId);
// in case of larger sheets we need to sleep the process
Utilities.sleep(1000);
}
else if (values[i][14] == 'u')
{
// can update event so need to delete and create again
// delete event
var event = calendar.getEventSeriesById(values[i][9]);
event.deleteEventSeries();
//create event
var newEventTitle = values[i][0];
//create event https://developers.google.com/apps-script/class_calendarapp#createEvent
var newEventTitle = values[i][0];
var dateStart = values[i][1];
var timeStart = values[i][2];
var dateFinish = values[i][3];
var timeFinish = values[i][4];
var startDateTime = new Date(dateStart+" "+timeStart);
startDateTime.setDate(startDateTime.getDate());
startDateTime.setMonth(startDateTime.getMonth());
startDateTime.setYear(startDateTime.getYear());
startDateTime.setTime(startDateTime.getTime());
var stopDateTime = new Date(dateFinish+" "+timeFinish);
stopDateTime.setDate(stopDateTime.getDate());
stopDateTime.setMonth(stopDateTime.getMonth());
stopDateTime.setYear(stopDateTime.getYear());
stopDateTime.setTime(stopDateTime.getTime());
var description = (values[i][7] == undefined ? 'Test Description '+i : values[i][7]);
var location = (values[i][8] == undefined ? 'Test Location '+i : values[i][8]);
//var newEvent = calendar.createAllDayEvent(newEventTitle, values[i][1]);
var newEvent = calendar.createEvent(newEventTitle, startDateTime, stopDateTime, {description:description,location:location});
//get ID
var newEventId = newEvent.getId();
//mark as entered, enter ID
sheet.getRange(i+2,14).setValue('y');
sheet.getRange(i+2,13).setValue(newEventId);
// in case of larger sheets we need to sleep the process
Utilities.sleep(1000);
}
else
{
Logger.log('I am groot');
sheet.getRange(i+2,14).setValue('y');
}
}
numValues++;
}
}
function onOpen()
{
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [];
menuEntries.push({name: "Grades & Evals", functionName: "pushToCalendar"});
sheet.addMenu("Sync to Academic Master", menuEntries);
}
I found the issue finally .. one of those tiny issue found after logging more and googling the Invalid Date response.
On line 16 this
var values = range.getValues();
needed to change to this
var values = range.getDisplayValues();
So thanks :)