How to target a particular tab (page) in my goggle worksheet - tabs

I have a google worksheet with multiple sheets, what do I add to this script to target a particular sheet in that worksheet only? At the moment it's just going to the far left-hand sheet. I've tried "getSheetByName("Calendar")", but I get errors so obviously there is more I need to do.
function export_gcal_to_gsheet() {
var mycal = "email";
var cal = CalendarApp.getCalendarById(mycal);
var events = cal.getEvents(new Date("July 01, 2022 00:00:00 UTC"), new Date ());
var sheet = SpreadsheetApp.getActiveSheet();
sheet.clearContents();
var header = [["Calendar Address", "Event Title", "Event Description", "Event Location", "Event Start", "Event End", "Calculated Duration", "Visibility", "Date Created", "Last Updated", "MyStatus", "Created By", "All Day Event", "Recurring Event"]]
var range = sheet.getRange(6, 1, 1, 14);
range.setValues(header);
for (var i = 0; i < events.length; i++) {
var row = events.length + 6 - i;
var myformula_placeholder = '';
var details=[[mycal,events[i].getTitle(), events[i].getDescription(), events[i].getLocation(), events[i].getStartTime(), events[i].getEndTime(), myformula_placeholder, ('' + events[i].getVisibility()), events[i].getDateCreated(), events[i].getLastUpdated(), events[i].getMyStatus(), events[i].getCreators(), events[i].isAllDayEvent(), events[i].isRecurringEvent()]];
var range=sheet.getRange(row,1,1,14);
range.setValues(details);
var cell=sheet.getRange(row,7);
cell.setFormula('=(HOUR(F' +row+ ')+(MINUTE(F' +row+ ')/60))-(HOUR(E' +row+ ')+(MINUTE(E' +row+ ')/60))');
cell.setNumberFormat('.00');
}
}

Use the function getActiveSpreadsheet() before using getSheetByName()
I have tried your script on my side and changed:
var sheet = SpreadsheetApp.getActiveSheet();
to:
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Calendar");
and your script worked fine and populated the desired sheet with the data provided by the script. I assumed you forgot to use the getActiveSpreadsheet() function which resulted in your script returning an error.
Reference
getSheetByName()

Related

Importing Colours from GCal into GSheets

Is there a way to export the colours used in GCal into Gsheets? This is the script I use at the moment to take data from Google Calendar and I want to incorporate a code to bring colours over as well, I'm just not sure if it's possible.
function export_gcal_to_gsheet() {
var mycal = "Email";
var cal = CalendarApp.getCalendarById(mycal);
var events = cal.getEvents(new Date("July 01, 2022 00:00:00 UTC"), new Date ());
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Calendar2023");
sheet.clearContents();
var header = [["Calendar Address", "Event Title", "Event Description", "Event Location", "Event Start", "Event End", "Calculated Duration", "Visibility", "Date Created", "Last Updated", "MyStatus", "Created By", "All Day Event", "Recurring Event"]]
var range = sheet.getRange(6, 1, 1, 14);
range.setValues(header);
for (var i = 0; i < events.length; i++) {
var row = events.length + 6 - i;
var myformula_placeholder = '';
var details=[[mycal,events[i].getTitle(), events[i].getDescription(), events[i].getLocation(), events[i].getStartTime(), events[i].getEndTime(), myformula_placeholder, ('' + events[i].getVisibility()), events[i].getDateCreated(), events[i].getLastUpdated(), events[i].getMyStatus(), events[i].getCreators(), events[i].isAllDayEvent(), events[i].isRecurringEvent()]];
var range=sheet.getRange(row,1,1,14);
range.setValues(details);
var cell=sheet.getRange(row,7);
cell.setFormula('=(HOUR(F' +row+ ')+(MINUTE(F' +row+ ')/60))-(HOUR(E' +row+ ')+(MINUTE(E' +row+ ')/60))');
cell.setNumberFormat('.00');
}
}
Although I'm not sure whether I could correctly understand I want to incorporate a code to bring colours over as well, in your situation how about the following 2 patterns?
In these patterns, the retrieved event color is put to the column "O" as the hex value.
In order to retrieve the color code as the hex, Calendar API is used. So, before you use this script, please enable Calendar API at Advanced Google services.
Pattern 1:
In this pattern, your showing script is simply modified.
function export_gcal_to_gsheet() {
var mycal = "Email";
var cal = CalendarApp.getCalendarById(mycal);
var events = cal.getEvents(new Date("July 01, 2022 00:00:00 UTC"), new Date());
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Calendar2023");
sheet.clearContents();
var calColor = cal.getColor();
var colors = Calendar.Colors.get().calendar;
var header = [["Calendar Address", "Event Title", "Event Description", "Event Location", "Event Start", "Event End", "Calculated Duration", "Visibility", "Date Created", "Last Updated", "MyStatus", "Created By", "All Day Event", "Recurring Event", "Color"]]
var range = sheet.getRange(6, 1, 1, 15);
range.setValues(header);
for (var i = 0; i < events.length; i++) {
var color = events[i].getColor();
var row = events.length + 6 - i;
var myformula_placeholder = '';
var details = [[mycal, events[i].getTitle(), events[i].getDescription(), events[i].getLocation(), events[i].getStartTime(), events[i].getEndTime(), myformula_placeholder, ('' + events[i].getVisibility()), events[i].getDateCreated(), events[i].getLastUpdated(), events[i].getMyStatus(), events[i].getCreators(), events[i].isAllDayEvent(), events[i].isRecurringEvent(), colors[color] ? colors[color].background : calColor]];
var range = sheet.getRange(row, 1, 1, 15);
range.setValues(details);
var cell = sheet.getRange(row, 7);
cell.setFormula('=(HOUR(F' + row + ')+(MINUTE(F' + row + ')/60))-(HOUR(E' + row + ')+(MINUTE(E' + row + ')/60))');
cell.setNumberFormat('.00');
}
}
Pattern 2:
In your script, setValues and setFormula are used in a loop. In this case, the process cost will become high. Ref So, in this pattern, your showing script is modified by reducing the process cost.
function export_gcal_to_gsheet2() {
var mycal = "Email";
var cal = CalendarApp.getCalendarById(mycal);
var events = cal.getEvents(new Date("July 01, 2022 00:00:00 UTC"), new Date());
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Calendar2023");
sheet.clearContents();
var calColor = cal.getColor();
var colors = Calendar.Colors.get().calendar;
var header = ["Calendar Address", "Event Title", "Event Description", "Event Location", "Event Start", "Event End", "Calculated Duration", "Visibility", "Date Created", "Last Updated", "MyStatus", "Created By", "All Day Event", "Recurring Event", "Color"];
var offset = 6;
var { v, c } = events.reverse().reduce((o, e, i) => {
var color = e.getColor();
var row = offset + i + 1;
var c = colors[color] ? colors[color].background : calColor;
var f = `=(HOUR(F${row})+(MINUTE(F${row})/60))-(HOUR(E${row})+(MINUTE(E${row})/60))`;
o.v.push([mycal, events[i].getTitle(), events[i].getDescription(), events[i].getLocation(), events[i].getStartTime(), events[i].getEndTime(), f, ('' + events[i].getVisibility()), events[i].getDateCreated(), events[i].getLastUpdated(), events[i].getMyStatus(), events[i].getCreators(), events[i].isAllDayEvent(), events[i].isRecurringEvent(), c]);
o.c.push([c]);
return o;
}, { v: [], c: [] });
var values = [header, ...v];
sheet.getRange(6, 1, values.length, values[0].length).setValues(values);
sheet.getRange(7, 7, v.length - 1).setNumberFormat('.00');
sheet.getRange(7, 15, c.length).setBackgrounds(c);
}
In this patten, the column "O" has the hex value and the background colors using the retrieved hex values.
Reference:
Colors: get

Minimize Call to other service - optimisation of my code to avoid Exceeded maximum execution time

I have this code that extracts calendars from a list of Google calendars.
I have a problem with the maximum execution time.
function export_gcal_to_gsheetLast1(){
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Extraction 1 - Calendrier");
var sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Id Calendriers - Dates Debut et Fin"); //Sheet name where you will have the list of calendar ID's, startDate and endDate
sheet.clear() // If you'll be runnning the script several times, the data will be duplicated so I added this line to clear the sheet before adding the data
// other option would be to create a script to check if data already exists before adding it to the sheet
// Set filters
var startDate = sheet2.getRange('k1').getValue(); //Range for startDate
var endDate = sheet2.getRange('k2').getValue(); //Range for endDate
var users = sheet2.getRange('b3:B').getValues(); //Range where you have the calendar ID's
// Create a header record on the current spreadsheet in cells A1:N1 - Match the number of entries in the "header=" to the last parameter
// of the getRange entry below
var header = [["Titre", "Description", "Location", "Début", "Fin", "Heures effectives","Extraction 2","Extraction 3","Heures Planifiées", "Vacances", "Maladie","Congé légal", "Absence"]]
var range = sheet.getRange(7,1,1,13);
range.setValues(header);
for (var j = 0; j< users.length; j++){
//here we do the things we do once per calander
if (users[j] == ""){
break;
}
else{
var cal = CalendarApp.getCalendarById(users[j]);
var events = cal.getEvents(startDate, endDate);
// Loop through all calendar events found and write them out starting on the next empty row
for (var i=0;i<events.length;i++) {
var myformula_placeholder = '';
var details=[
[events[i].getTitle(), events[i].getDescription(), events[i].getLocation(), events[i].getStartTime(), events[i].getEndTime(),
myformula_placeholder,myformula_placeholder,myformula_placeholder,myformula_placeholder,myformula_placeholder,myformula_placeholder,myformula_placeholder,myformula_placeholder]
];
var lastRow = sheet.getLastRow()+1;
var range=sheet.getRange(lastRow,1,1,13);
range.setValues(details);
let formulas = []
for(let i = 0; i < 7; i++){formulas.push('=(HOUR(RIGHT(b' +lastRow+';5))+(MINUTE(RIGHT(b' +lastRow+ ';5))/60))-(HOUR(LEFT(b' +lastRow+ ';5))+(MINUTE(LEFT(b' +lastRow+ ';5))/60))')}}
sheet.getRange(lastRow,6).setFormulas(formulas)
//var cell=sheet.getRange(lastRow,6);
//cell.setFormula('=(HOUR(RIGHT(b' +lastRow+';5))+(MINUTE(RIGHT(b' +lastRow+ ';5))/60))-(HOUR(LEFT(b' +lastRow+ ';5))+(MINUTE(LEFT(b' +lastRow+ ';5))/60))')
cell.setNumberFormat('.00');
var cell=sheet.getRange(lastRow,7);
cell.setFormula('=IFERROR(TEXT(INDEX(SPLIT(A'+lastRow+';" ");2);"hh:mm");"")')
var cell=sheet.getRange(lastRow,8);
cell.setFormula('=IFERROR(TEXT(INDEX(SPLIT(A'+lastRow+';" ");3);"hh:mm");"")')
var cell=sheet.getRange(lastRow,9);
cell.setFormula('=IF(OR(G'+lastRow+'="Maladie";G'+lastRow+'="Congé";G'+lastRow+'="Absence";G'+lastRow+'="00:00";G'+lastRow+'="Vacances");0;(HOUR(H'+lastRow+')+(MINUTE(H'+lastRow+')/60))-(HOUR(G'+lastRow+')+(MINUTE(G'+lastRow+')/60)))')
var cell=sheet.getRange(lastRow,10);
cell.setFormula('=IF(IFNA(VLOOKUP(D'+lastRow+'; feries;1;FALSE);1)<>1;0;IF(AND(G'+lastRow+'="00:00";H'+lastRow+'="Vacances");0.5;IF(G'+lastRow+'="Vacances";1;0)))')
var cell=sheet.getRange(lastRow,11);
cell.setFormula('=IF(G'+lastRow+'="Maladie";1;0)')
var cell=sheet.getRange(lastRow,12);
cell.setFormula('=IF(G'+lastRow+'="Congé";1;0)')
var cell=sheet.getRange(lastRow,13);
cell.setFormula('=IF(G'+lastRow+'="Absence";1;0)')
}
}
}
One of the problems is that I'm using methods like setFormula or getRange inside of a loop, this causes a massive call to Spreadsheet service.
This is not recommended by the best practices guides Minimize Call to other service.
So, in order to solve this problem I have to use another recommendation from Best Practices guide, using batch operation.
Instead of using setFormula use setFormulas and delegate to Javascript all the tasks to build the formulas.
I have recived this advice:
All the lines that start with:
var cell=sheet.getRange(lastRow,6); cell.setFormula('=(HOUR(RIGHT(b' +lastRow+';5))+(MINUTE(RIGHT(b' +lastRow+ ';5))/60))-(HOUR(LEFT(b' +lastRow+ ';5))+(MINUTE(LEFT(b' +lastRow+ ';5))/60))')
Should move to something like that:
let formulas = [] for(let i = 0; i < 7; i++){formulas.push(FORMULAS)} sheet.getRange(x,y,nx,ny).setFormulas(formulas)
I have try to change my code using this but without success.
Can someone please give me an example using my code on how I can do this change ?
Thanks a lot !!
You create arrays and push the data in there. Then like you said, you can bulk update it all. Would be something like below. I did not test it and maybe the range is off. But this will get you in the right direction.
function export_gcal_to_gsheetLast1(){
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Extraction 1 - Calendrier");
var sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Id Calendriers - Dates Debut et Fin"); //Sheet name where you will have the list of calendar ID's, startDate and endDate
sheet.clear() // If you'll be runnning the script several times, the data will be duplicated so I added this line to clear the sheet before adding the data
// other option would be to create a script to check if data already exists before adding it to the sheet
// Set filters
var startDate = sheet2.getRange('k1').getValue(); //Range for startDate
var endDate = sheet2.getRange('k2').getValue(); //Range for endDate
var users = sheet2.getRange('b3:B').getValues(); //Range where you have the calendar ID's
// Create a header record on the current spreadsheet in cells A1:N1 - Match the number of entries in the "header=" to the last parameter
// of the getRange entry below
const data = []
const formulas = [];
const headers = [["Titre", "Description", "Location", "Début", "Fin", "Heures effectives","Extraction 2","Extraction 3","Heures Planifiées", "Vacances", "Maladie","Congé légal", "Absence"]]
for (var j = 0; j< users.length; j++){
//here we do the things we do once per calander
if (users[j] == ""){
break;
}
else{
var cal = CalendarApp.getCalendarById(users[j]);
var events = cal.getEvents(startDate, endDate);
// Loop through all calendar events found and write them out starting on the next empty row
for (var i = 0; i < events.length; i++) {
var details=
[
events[i].getTitle(),
events[i].getDescription(),
events[i].getLocation(),
events[i].getStartTime(),
events[i].getEndTime()
];
data.push(details);
const rowFormulas =
[
'=(HOUR(RIGHT(b' +lastRow+';5))+(MINUTE(RIGHT(b' +lastRow+ ';5))/60))-(HOUR(LEFT(b' +lastRow+ ';5))+(MINUTE(LEFT(b' +lastRow+ ';5))/60))',
'=IFERROR(TEXT(INDEX(SPLIT(A'+lastRow+';" ");2);"hh:mm");"")',
'=IFERROR(TEXT(INDEX(SPLIT(A'+lastRow+';" ");3);"hh:mm");"")',
'=IF(OR(G'+lastRow+'="Maladie";G'+lastRow+'="Congé";G'+lastRow+'="Absence";G'+lastRow+'="00:00";G'+lastRow+'="Vacances");0;(HOUR(H'+lastRow+')+(MINUTE(H'+lastRow+')/60))-(HOUR(G'+lastRow+')+(MINUTE(G'+lastRow+')/60)))',
'=IF(IFNA(VLOOKUP(D'+lastRow+'; feries;1;FALSE);1)<>1;0;IF(AND(G'+lastRow+'="00:00";H'+lastRow+'="Vacances");0.5;IF(G'+lastRow+'="Vacances";1;0)))',
'=IF(G'+lastRow+'="Maladie";1;0)',
'=IF(G'+lastRow+'="Congé";1;0)',
'=IF(G'+lastRow+'="Absence";1;0)'
]
formulas.push(rowFormulas)
}
}
}
sheet.getRange(7,1,1,headers.length, headers[0].length).setValues(headers)
sheet.getRange(8,1,data.length,data[0].length).setValues(data);
sheet.getRange(8,data[0].length + 1,formulas.length, formulas[0].length).setFormulas(formulas);
sheet.getRange(8,6,sheet.getLastRow()).setNumberFormat('.00');
}
Thank you again to RemcoE33 for his code. I fixe two mistakes, lastrow was missing and the getRange had an error. Now it is working very well. Thanks a lot !!
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Extraction 8 - Calendrier");
var sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Id Calendriers - Dates Debut et Fin"); //Sheet name where you will have the list of calendar ID's, startDate and endDate
sheet.clear() // If you'll be runnning the script several times, the data will be duplicated so I added this line to clear the sheet before adding the data
// other option would be to create a script to check if data already exists before adding it to the sheet
// Set filters
var startDate = sheet2.getRange('k15').getValue(); //Range for startDate
var endDate = sheet2.getRange('k16').getValue(); //Range for endDate
var users = sheet2.getRange('b3:B').getValues(); //Range where you have the calendar ID's
// Create a header record on the current spreadsheet in cells A1:N1 - Match the number of entries in the "header=" to the last parameter
// of the getRange entry below
const data = []
const formulas = [];
const headers = [["Titre", "Description", "Location", "Début", "Fin", "Heures effectives","Extraction 2","Extraction 3","Heures Planifiées", "Vacances", "Maladie","Congé légal", "Absence"]]
for (var j = 0; j< users.length; j++){
//here we do the things we do once per calander
if (users[j] == ""){
break;
}
else{
var cal = CalendarApp.getCalendarById(users[j]);
var events = cal.getEvents(startDate, endDate);
var lastRow = sheet.getLastRow()+8;
// Loop through all calendar events found and write them out starting on the next empty row
for (var i = 0; i < events.length; i++) {
var details=
[
events[i].getTitle(),
events[i].getDescription(),
events[i].getLocation(),
events[i].getStartTime(),
events[i].getEndTime()
];
data.push(details);
const rowFormulas =
[
'=(HOUR(RIGHT(b' +lastRow+';5))+(MINUTE(RIGHT(b' +lastRow+ ';5))/60))-(HOUR(LEFT(b' +lastRow+ ';5))+(MINUTE(LEFT(b' +lastRow+ ';5))/60))',
'=IFERROR(TEXT(INDEX(SPLIT(A'+lastRow+';" ");2);"hh:mm");"")',
'=IFERROR(TEXT(INDEX(SPLIT(A'+lastRow+';" ");3);"hh:mm");"")',
'=IF(OR(G'+lastRow+'="Maladie";G'+lastRow+'="Congé";G'+lastRow+'="Absence";G'+lastRow+'="00:00";G'+lastRow+'="Vacances");0;(HOUR(H'+lastRow+')+(MINUTE(H'+lastRow+')/60))-(HOUR(G'+lastRow+')+(MINUTE(G'+lastRow+')/60)))',
'=IF(IFNA(VLOOKUP(D'+lastRow+'; feries;1;FALSE);1)<>1;0;IF(AND(G'+lastRow+'="00:00";H'+lastRow+'="Vacances");0.5;IF(G'+lastRow+'="Vacances";1;0)))',
'=IF(G'+lastRow+'="Maladie";1;0)',
'=IF(G'+lastRow+'="Congé";1;0)',
'=IF(G'+lastRow+'="Absence";1;0)'
]
formulas.push(rowFormulas)
lastRow=lastRow+1
}
}
}
sheet.getRange(7,1,headers.length, headers[0].length).setValues(headers)
sheet.getRange(8,1,data.length,data[0].length).setValues(data);
sheet.getRange(8,data[0].length + 1,formulas.length, formulas[0].length).setFormulas(formulas);
sheet.getRange(8,6,sheet.getLastRow()).setNumberFormat('.00');
}```

Extraction of multiple calendars to Google sheet

I'm having a hard time making a loop to extract more than one calendar to a google sheet. The calendars' IDs are in cell P1, the start date is in P7, and the end date is in P8.
The code works fine for one calendar, but when I try to add the j loop on more calendars, my extraction is empty. Can someone figure out what I'm doing wrong?
Thanks for your help.
Here is the code:
var sheet = SpreadsheetApp.getActiveSheet();
// Set filters
var startDate = sheet.getRange('p7').getValue();
var endDate = sheet.getRange('p8').getValue();
var mycal = sheet.getRange('p1').getValue().toString();
var cal = CalendarApp.getCalendarById(mycal);
// Create a header record on the current spreadsheet in cells A1:N1 - Match the number of entries in the "header=" to the last parameter
// of the getRange entry below
var header = [["Calendar Address", "Event Title", "Event Description", "Event Location", "Event Start", "Event End", "Calculated Duration", "Visibility", "Date Created", "Last Updated", "MyStatus", "Created By", "All Day Event", "Recurring Event"]]
var range = sheet.getRange(1,1,1,14);
range.setValues(header);
var row=2
for (var j = 0; j< mycal.lengh; j++){
//here we do the things we do once per calander
var cal = CalendarApp.getCalendarById(mycal[j]);
var events = cal.getEvents(startDate, endDate);
// Loop through all calendar events found and write them out starting on calulated ROW 2 (i+2)
for (var i=0;i<events.length;i++) {
var row=i+2;
var myformula_placeholder = '';
var details=[[mycal,events[i].getTitle(), events[i].getDescription(), events[i].getLocation(), events[i].getStartTime(), events[i].getEndTime(), myformula_placeholder, ('' + events[i].getVisibility()), events[i]. getDateCreated(), events[i].getLastUpdated(), events[i].getMyStatus(), events[i].getCreators(), events[i].isAllDayEvent(), events[i].isRecurringEvent()]];
var range=sheet.getRange(row,1,1,14);
range.setValues(details);
var cell=sheet.getRange(row,7);
cell.setFormula('=(HOUR(F' +row+ ')+(MINUTE(F' +row+ ')/60))-(HOUR(E' +row+ ')+(MINUTE(E' +row+ ')/60))');
cell.setNumberFormat('.00');
row++;
}
}
}
As #Cooper mentioned, lengh is not an attribute. I made that correction and other changes to the script. Also, I created another sheet where I have a list of calendar ID's, the startDate and endDate. See the script below, I added some comments to explain the changes I made. Make sure to change ranges based on where you have your data.
function calendarFunction() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2"); //Sheet name where you will have the list of calendar ID's, startDate and endDate
sheet.clear() // If you'll be runnning the script several times, the data will be duplicated so I added this line to clear the sheet before adding the data
// other option would be to create a script to check if data already exists before adding it to the sheet
// Set filters
var startDate = sheet2.getRange('B1').getValue(); //Range for startDate
var endDate = sheet2.getRange('B2').getValue(); //Range for endDate
var users = sheet2.getRange('A1:A').getValues(); //Range where you have the calendar ID's
// Create a header record on the current spreadsheet in cells A1:N1 - Match the number of entries in the "header=" to the last parameter
// of the getRange entry below
var header = [["Calendar Address", "Event Title", "Event Description", "Event Location", "Event Start", "Event End", "Calculated Duration", "Visibility", "Date Created", "Last Updated","MyStatus", "Created By", "All Day Event", "Recurring Event"]]
var range = sheet.getRange(1,1,1,14);
range.setValues(header);
for (var j = 0; j< users.length; j++){
//here we do the things we do once per calander
if (users[j] == ""){
break;
}
else{
var cal = CalendarApp.getCalendarById(users[j]);
var events = cal.getEvents(startDate, endDate);
// Loop through all calendar events found and write them out starting on the next empty row
for (var i=0;i<events.length;i++) {
var myformula_placeholder = '';
var details=[
[users[j].toString(),events[i].getTitle(), events[i].getDescription(), events[i].getLocation(), events[i].getStartTime(), events[i].getEndTime(),
myformula_placeholder, ('' + events[i].getVisibility()), events[i].getDateCreated(), events[i].getLastUpdated(), events[i].getMyStatus(),
events[i].getCreators().toString(), events[i].isAllDayEvent(), events[i].isRecurringEvent()]
];
var lastRow = sheet.getLastRow()+1;
var range=sheet.getRange(lastRow,1,1,14);
range.setValues(details);
var cell=sheet.getRange(lastRow,7);
cell.setFormula('=(HOUR(F' +lastRow+ ')+(MINUTE(F' +lastRow+ ')/60))-(HOUR(E' +lastRow+ ')+(MINUTE(E' +lastRow+ ')/60))');
cell.setNumberFormat('.00');
}
}
}
}
Thanks to the help of this amazing community, I was able to have a script that run so much faster.
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Extraction 8 - Calendrier");
var sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Id Calendriers - Dates Debut et Fin"); //Sheet name where you will have the list of calendar ID's, startDate and endDate
sheet.clear() // If you'll be runnning the script several times, the data will be duplicated so I added this line to clear the sheet before adding the data
// other option would be to create a script to check if data already exists before adding it to the sheet
// Set filters
var startDate = sheet2.getRange('k15').getValue(); //Range for startDate
var endDate = sheet2.getRange('k16').getValue(); //Range for endDate
var users = sheet2.getRange('b3:B').getValues(); //Range where you have the calendar ID's
// Create a header record on the current spreadsheet in cells A1:N1 - Match the number of entries in the "header=" to the last parameter
// of the getRange entry below
const data = []
const formulas = [];
const headers = [["Titre", "Description", "Location", "Début", "Fin", "Heures effectives","Extraction 2","Extraction 3","Heures Planifiées", "Vacances", "Maladie","Congé légal", "Absence"]]
for (var j = 0; j< users.length; j++){
//here we do the things we do once per calander
if (users[j] == ""){
break;
}
else{
var cal = CalendarApp.getCalendarById(users[j]);
var events = cal.getEvents(startDate, endDate);
var lastRow = sheet.getLastRow()+8;
// Loop through all calendar events found and write them out starting on the next empty row
for (var i = 0; i < events.length; i++) {
var details=
[
events[i].getTitle(),
events[i].getDescription(),
events[i].getLocation(),
events[i].getStartTime(),
events[i].getEndTime()
];
data.push(details);
const rowFormulas =
[
'=(HOUR(RIGHT(b' +lastRow+';5))+(MINUTE(RIGHT(b' +lastRow+ ';5))/60))-(HOUR(LEFT(b' +lastRow+ ';5))+(MINUTE(LEFT(b' +lastRow+ ';5))/60))',
'=IFERROR(TEXT(INDEX(SPLIT(A'+lastRow+';" ");2);"hh:mm");"")',
'=IFERROR(TEXT(INDEX(SPLIT(A'+lastRow+';" ");3);"hh:mm");"")',
'=IF(OR(G'+lastRow+'="Maladie";G'+lastRow+'="Congé";G'+lastRow+'="Absence";G'+lastRow+'="00:00";G'+lastRow+'="Vacances");0;(HOUR(H'+lastRow+')+(MINUTE(H'+lastRow+')/60))-(HOUR(G'+lastRow+')+(MINUTE(G'+lastRow+')/60)))',
'=IF(IFNA(VLOOKUP(D'+lastRow+'; feries;1;FALSE);1)<>1;0;IF(AND(G'+lastRow+'="00:00";H'+lastRow+'="Vacances");0.5;IF(G'+lastRow+'="Vacances";1;0)))',
'=IF(G'+lastRow+'="Maladie";1;0)',
'=IF(G'+lastRow+'="Congé";1;0)',
'=IF(G'+lastRow+'="Absence";1;0)'
]
formulas.push(rowFormulas)
lastRow=lastRow+1
}
}
}
sheet.getRange(7,1,headers.length, headers[0].length).setValues(headers)
sheet.getRange(8,1,data.length,data[0].length).setValues(data);
sheet.getRange(8,data[0].length + 1,formulas.length, formulas[0].length).setFormulas(formulas);
sheet.getRange(8,6,sheet.getLastRow()).setNumberFormat('.00');
}```

Date picker for Calender to Sheets Script

Below is a script I found and modified to track events by grabbing event information from our Calendar(s) and populating a spreadsheet (with mild reformatting) based on a selected date range.
Currently I have to manually change the dates within the script each week to get the events that I need. I would like to have a date picker pop up when I open a new sheet and have the selected dates input to the script, but I haven't been able to figure it out yet. Any help would be greatly appreciated.
function main(){
var sheet = SpreadsheetApp.getActiveSheet();
sheet.clearContents();
var header = [["Calendar Address", "Calendar Name", "Event Title", "Event Location", "Event Start", "Event Description" ]]
var range = sheet.getRange(1,1,1,6);
range.setValues(header);
sheet.setFrozenRows(1);
// var mycals is an array of google calendar id's; for gsuite, this is the email address of the user which calendar you will be viewing.
var mycals = ['9ss30f8ktuvbedmemka1ve8jss#group.calendar.google.com','8nmutqctujaetrnt5kfvi56kuo#group.calendar.google.com','ae1d2v0sqtktc183546u6cenps#group.calendar.google.com','ilr8eqk2l0ua9pr50t5307ivq8#group.calendar.google.com','5qubvv7mj5vjf7h1hhc23515h8#group.calendar.google.com', 'p2a9plkjd3vv9c87kb5kirapqk#group.calendar.google.com', '9ubfnjrb83tiqgi5l1nitaodp0#group.calendar.google.com', 'l6ouqfpktn05hstmokj8jhr1s4#group.calendar.google.com' ]
for (var j=0;j<mycals.length;j++) {
var cal = CalendarApp.getCalendarById(mycals[j]);
// error handling in case you don't have access to any specified calendar
if (!cal) { continue; }
var events = cal.getEvents(new Date("12/30/2019 00:00:00 EST"), new Date("1/3/2020 23:59:59 EST"));
for (var i=0;i<events.length;i++) {
var row = sheet.getLastRow() + 1
var details=[[events[i].getOriginalCalendarId(),,events[i].getTitle(), events[i].getLocation(), events[i].getStartTime(), events[i].getDescription()]];
var range=sheet.getRange(row,1,1,6);
range.setValues(details);
sheet.getRange(i+2, 5).setNumberFormat("mm/dd/yyyy h:mm Am/PM");
}
sheet.sort(1);
}
var lr= sheet.getLastRow();
for(var k=0+1; k<lr+1;k++){
var workingCell = sheet.getRange(k,1).getValue();
if(workingCell == '9ss30f8ktuvbedmemka1ve8jss#group.calendar.google.com'){
sheet.getRange(k,2).setValue("ATG_Cert");
}
else if(workingCell == '8nmutqctujaetrnt5kfvi56kuo#group.calendar.google.com'){
sheet.getRange(k,2).setValue("Functionality_Test");
}
else if(workingCell == 'ae1d2v0sqtktc183546u6cenps#group.calendar.google.com'){
sheet.getRange(k,2).setValue("Tightness_Test");
}
else if(workingCell == 'ilr8eqk2l0ua9pr50t5307ivq8#group.calendar.google.com'){
sheet.getRange(k,2).setValue("Pre_or_Post_Bury");
}
else if(workingCell == '5qubvv7mj5vjf7h1hhc23515h8#group.calendar.google.com'){
sheet.getRange(k,2).setValue("LLD");
}
else if(workingCell == 'p2a9plkjd3vv9c87kb5kirapqk#group.calendar.google.com'){
sheet.getRange(k,2).setValue("PMI");
}
else if(workingCell == '9ubfnjrb83tiqgi5l1nitaodp0#group.calendar.google.com'){
sheet.getRange(k,2).setValue("Stage_II_DeComm_Test");
}
else if(workingCell == 'l6ouqfpktn05hstmokj8jhr1s4#group.calendar.google.com'){
sheet.getRange(k,2).setValue("Other");
}
}
sheet.getRange(1,1,lr,6).setFontSize(14)
sheet.hideColumns(1);
sheet.autoResizeColumns(1, 6);
sheet.getRange(1, 1, lr, 6).setHorizontalAlignment("left")
}
Assuming that the rest of your code works then try this modification:
function main(){
var sheet = SpreadsheetApp.getActiveSheet();
sheet.clearContents();
var header = [["Calendar Address", "Calendar Name", "Event Title", "Event Location", "Event Start", "Event Description" ]]
var range = sheet.getRange(1,1,1,6);
range.setValues(header);
sheet.setFrozenRows(1);
var mycals = ['9ss30f8ktuvbedmemka1ve8jss#group.calendar.google.com','8nmutqctujaetrnt5kfvi56kuo#group.calendar.google.com','ae1d2v0sqtktc183546u6cenps#group.calendar.google.com','ilr8eqk2l0ua9pr50t5307ivq8#group.calendar.google.com','5qubvv7mj5vjf7h1hhc23515h8#group.calendar.google.com', 'p2a9plkjd3vv9c87kb5kirapqk#group.calendar.google.com', '9ubfnjrb83tiqgi5l1nitaodp0#group.calendar.google.com', 'l6ouqfpktn05hstmokj8jhr1s4#group.calendar.google.com' ]
var today=new Date();//added
var day=today.getDay();//added
var start=new Date(today.getFullYear(),today.getMonth(),today.getDate()-day+8);//added
var end=new Date(today.getFullYear(),today.getMonth(),today.getDate()-day+12);//added
for (var j=0;j<mycals.length;j++) {
var cal = CalendarApp.getCalendarById(mycals[j]);
// error handling in case you don't have access to any specified calendar
if (!cal) { continue; }
var events = cal.getEvents(start,end);
It looked like you want to view next weeks events between monday and friday. If not then make it a bit clearer what you are looking for.

Extract multiple Google calendars to single Google sheet

I'm using a Google script to extract data from a resource calendar. The script works as intended to extract a single calendar, but I would like to extract multiple resource calendars into 1 sheet. Can someone point me in the right direction? I've looked at creating an array to include multiple calendars into 'mycal', but I couldn't get it to run. Thanks
function export_gcal_to_gsheet(){
var mycal = "engelska.se_xxxx#resource.calendar.google.com";
var cal = CalendarApp.getCalendarById(mycal);
var today = new Date();
var events = CalendarApp.getCalendarById(mycal).getEventsForDay(today);
var sheet = SpreadsheetApp.getActiveSheet();
sheet.clearContents();
var header = [["Calendar Address", "Event Title", "Event Description", "Event Location", "Event Start", "Event End", "Calculated Duration", "Visibility", "Date Created", "Last Updated", "MyStatus", "Created By", "All Day Event", "Recurring Event"]]
var range = sheet.getRange(1,1,1,14);
range.setValues(header);
for (var i=0;i<events.length;i++) {
var row=i+2;
var myformula_placeholder = '';
var details=[[mycal,events[i].getTitle(), events[i].getDescription(), events[i].getLocation(), events[i].getStartTime(), events[i].getEndTime(), myformula_placeholder, ('' + events[i].getVisibility()), events[i].getDateCreated(), events[i].getLastUpdated(), events[i].getMyStatus(), events[i].getCreators(), events[i].isAllDayEvent(), events[i].isRecurringEvent()]];
var range=sheet.getRange(row,1,1,14);
range.setValues(details);
var cell=sheet.getRange(row,7);
cell.setFormula('=(HOUR(F' +row+ ')+(MINUTE(F' +row+ ')/60))-(HOUR(E' +row+ ')+(MINUTE(E' +row+ ')/60))');
cell.setNumberFormat('.00');
}
}
If you make mycal into an array you will need a second loop to step thru that array and the variable assignment based on mycal will need to be in that loop. the events loop you already have will also need to be inside that loop. Because the number of events in each calendar could be different the best way to maintain the row counter is to declare it before both loops and increment it after you write to a row.
function export_gcal_to_gsheet(){
var mycal = ["engelska.se_xxxx#resource.calendar.google.com",
"calenderaddress2",
"calenderaddress3",
"calenderaddress4"];//note , between address, no , after last
//here we do all the things that need to be done only once.
var today = new Date();
var sheet = SpreadsheetApp.getActiveSheet();
sheet.clearContents();
var header = [["Calendar Address", "Event Title", "Event Description", "Event Location", "Event Start", "Event End", "Calculated Duration", "Visibility", "Date Created", "Last Updated", "MyStatus", "Created By", "All Day Event", "Recurring Event"]]
var range = sheet.getRange(1,1,1,14);
range.setValues(header);
var row=2;// this needs to be outside the loops in order to use it as a counter in nested loops
for (var j = 0; j< mycal.lengh; j++){
//here we do the things we do once per calander
var events = CalendarApp.getCalendarById(mycal[j]).getEventsForDay(today);//refer to the calender in mycal based on loop counter
var cal = CalendarApp.getCalendarById(mycal[j]);//refer to the calender in mycal based on loop counter
//incerting a header for each calander would be done here. make sure to increment row
for (var i=0;i<events.length;i++) {
var myformula_placeholder = '';
var details=[[mycal,events[i].getTitle(), events[i].getDescription(), events[i].getLocation(), events[i].getStartTime(), events[i].getEndTime(), myformula_placeholder, ('' + events[i].getVisibility()), events[i].getDateCreated(), events[i].getLastUpdated(), events[i].getMyStatus(), events[i].getCreators(), events[i].isAllDayEvent(), events[i].isRecurringEvent()]];
var range=sheet.getRange(row,1,1,14);
range.setValues(details);
var cell=sheet.getRange(row,7);
cell.setFormula('=(HOUR(F' +row+ ')+(MINUTE(F' +row+ ')/60))-(HOUR(E' +row+ ')+(MINUTE(E' +row+ ')/60))');
cell.setNumberFormat('.00');
row++; //increment row counter.
}
}
}