The code below is extracting data from different calendars and writing formulas in the sheet with formulas.push(rowFormulas).
The problem I have is that I can't figure out how to do the loop for the lastrow in the script.
Every time the user change, the lastRow restart at row 8 instead of continuing. Can someone help me to correct my loop? thanks a lot
function export_gcal_to_gsheetLast8(){
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Extraction - Principal");
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
var lastRow = sheet.getLastRow()+8;
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);
// 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)'
]
lastRow = lastRow +1;
formulas.push(rowFormulas)
}
}
}
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');
}
I had to move var lastRow = sheet.getLastRow()+8 outside the loop because lastRow was getting reinitialized every loop. (I also had to initialize lastRow to 8: var lastRow = 8)
Here is the correct script:
function export_gcal_to_gsheetPrincipal(){
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Extraction - Principal");
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
var lastRow = 8;
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)'
]
lastRow = lastRow +1;
formulas.push(rowFormulas)
}
}
}
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');
}
Related
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');
}```
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');
}```
I am using as a master tracking spreadsheet so all new details added after the calendar event import get mixed up when a new event is added to the sheet. HELP. I need to keep the events and new columns of data in the same row. I have 14 rows of data.
function importCalendar(){
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Calendar Import'); //Target sheet for events
var calendarName = sheet.getRange('C2').getValue(); //name of calendar ex. calendar#gmailcom
var start = sheet.getRange('C3').getValue(); //to date
var end = sheet.getRange('C4').getValue(); //from date
var calendar = CalendarApp.getCalendarById(calendarName);
if(calendar) {var calendarId = calendar.getId();}
if(!calendar) {
var calendar = CalendarApp.getCalendarsByName(calendarName)[0];
var calendarId = calendarName;
}
var events = calendar.getEvents(start, end);
var eventDetails = [];
for(var i = 0; i<events.length; i++){
eventDetails.push([events[i].getLocation(), events[i].getTitle(), events[i].getStartTime(),
events[i].getDescription()]);
}
//write calendar details to spreadsheet and where my problem is//
var startRow = 8;
var startCol = 2;
for(var j = 0; j<eventDetails.length; j++){
var tempRange = sheet.getRange(startRow+j, startCol, 1, eventDetails[j].length);
var eventArray = Array(eventDetails[j]);
tempRange.setValues(eventArray);
}
return eventDetails;
}
attempting to extract all day events from Google calenders (three in total), into three sheadsheet pages each with two set of three column data. Max is about 100 rows in a month takeout. the entries are searchable by name event as well.
help, runs sort of okay, but gives me a time out, which may be to much information, also error pops up with getTitle not found.
anyone with suggestions to improve code and prevent time out, or any other suggestions to tidy up code would be of help. My thanks in advance.
This is what I have so far.
function export_gcal_to_gsheet() {
// This selects events only from calendars in date and list out
// Export Google Calendars Events to a Google Spreadsheet
// This code retrieves events between 2 dates for the specified calendar.
// It logs the results in the current spreadsheet starting at cell A6 listing the events,and date
// I do re-write the spreadsheet header in Row 6 with every run, as I found it faster to delete then entire sheet content,
// 1. Please modify the value for mycal to be YOUR calendar email address or one visible on your MY Calendars section of your Google Calendar
// 2. Please modify the values for events to be the date/time range you want and any search parameters to find or omit calendar entires
// Note: Events can be easily filtered out/deleted once exported from the calendar
// from an original file export_gcal_to_gsheet
// Reference Websites:
// https://developers.google.com/apps-script/reference/calendar/calendar
// https://developers.google.com/apps-script/reference/calendar/calendar-event
var mycal="";
var mySite="canv";
switch (mySite) {
case "canv" : mycal = "*****orqjiaaosl0dt0qp0g#group.calendar.google.com"; break;
case "salf" : mycal = "*****juiigo83ich4iga7sttlpa4#group.calendar.google.com"; break;
case "hart": mycal = "*****qblepqp88utr69vv434s#group.calendar.google.com"; break;
}//end switch
//var mycal = "*****hkdorqjiaaosl0dt0qp0g#group.calendar.google.com";
var cal = CalendarApp.getCalendarById(mycal);
// Optional variations on getEvents
// var events = cal.getEvents(new Date("January 3, 2014 00:00:00 CST"), new Date("January 14, 2014 23:59:59 CST"));
// var events = cal.getEvents(new Date("January 3, 2014 00:00:00 CST"), new Date("January 14, 2014 23:59:59 CST"), {search: 'word1'});
//
// Explanation of how the search section works (as it is NOT quite like most things Google) as part of the getEvents function:
// {search: 'word1'} Search for events with word1
// {search: '-word1'} Search for events without word1
var eventsbell = cal.getEvents(new Date("May 1, 2014 00:00:00 GMT"), new Date("May 10, 2014 23:59:59 GMT"), {search: 'bell'});
var eventspers = cal.getEvents(new Date("May 1, 2014 00:00:00 GMT"), new Date("May 2, 2014 23:59:59 GMT"), {search: 'pers'});
//var sheet = SpreadsheetApp.getActiveSheet();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(mySite);
// Uncomment this next line if you want to always clear the spreadsheet content before running - Note people could have added extra columns on the data though that would be lost
sheet.clearContents();
// Create a header record on the current spreadsheet in cells A5:C5,E5:G5 - Match the number of entries in the "header=" to the last parameter
// of the getRange entry below
var header = [["Delivery Branch test", "Customer and Site test", "Delivery Date test"]]
var rangebell = sheet.getRange(5,1,1,3);
rangebell.setValues(header);
var rangepers = sheet.getRange(5,5,1,3);
rangepers.setValues(header);
// Loop through all calendar events found and write them out starting on calculated ROW 6 (i+6)
for (var i=0;i<eventsbell.length;i++) {
var row=i+6;
for (var i=0;i<eventspers.length;i++) {
var row=i+6;
// Matching the "header=" entry above, this is the detailed row entry "details=", and must match the number of entries of the GetRange entry below
var detailsbell = [[ mycal,eventsbell[i].getTitle(),eventsbell[i].getStartTime()]];
var rangebell = sheet.getRange(row,1,1,3);
rangebell.setValues(detailsbell);
var detailspers = [[ mycal,eventspers[i].getTitle(),eventspers[i].getStartTime()]];
var rangepers = sheet.getRange(row,5,1,3);
rangepers.setValues(detailspers);
}
}
}
I wrote such a script some time ago and use it all the time without issues. Here is a simplified version of it that you could try to see if it eventually works for you.
The code is a bit long but the operation is all but simple so I guess there is probably no way to make it really shorter.
I know that some methods used in this code are being deprecated (getTimeZone for example) but it will be easy to update when they become unavailable... for now it works as it is, I'll update when I get some time to do it.
Here is the link to a test sheet (in view only, make a copy to use)
var FUS1=new Date().toString().substr(25,6)+":00";
var tz = SpreadsheetApp.getActiveSpreadsheet().getSpreadsheetTimeZone();
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [
{name: "ImportCalendars", functionName: "Cal_to_sheetM"},
];
ss.addMenu("import cals", menuEntries);
}
function Cal_to_sheetM() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
var app = UiApp.createApplication().setTitle("Import Calendars");
app.setHeight(365).setWidth(600);
// Create a grid with 3 text boxes and corresponding labels
var grid = app.createGrid(6, 2);
var wait = app.createImage('https://dl.dropboxusercontent.com/u/211279/loading3.gif').setVisible(false);
grid.setWidget(0, 0, app.createLabel("Cal Names :"));
var list = app.createListBox(true).setVisibleItemCount(5);
list.setName('calendar');
grid.setWidget(0, 1, list);
var calendars = CalendarApp.getAllCalendars();
for (var i = 0; i < calendars .length; i++) {
list.addItem(calendars[i].getName());
}
list.setItemSelected(0, true);
grid.setWidget(1, 0, app.createCheckBox("add cal Name to events").setName('addName').setValue(false))
.setWidget(2, 0, app.createLabel('start Date :'))
.setWidget(2, 1, app.createDateBox().setId("start").setValue(new Date(PropertiesService.getScriptProperties().getProperty('startDate'))))
.setWidget(3, 0, app.createLabel('End Date :'))
.setWidget(3, 1, app.createDateBox().setId("end").setValue(new Date(PropertiesService.getScriptProperties().getProperty('endDate'))))
.setWidget(4,0, app.createCheckBox("create new sheet").setName('newsheet').setValue(false));
var panel = app.createVerticalPanel();
panel.add(grid);
var button = app.createButton('Import');
var handler = app.createServerClickHandler('importEventsMulti');
handler.addCallbackElement(grid);
var cHandler = app.createClientHandler().forTargets(wait).setVisible(true).forEventSource().setEnabled(false);
button.addClickHandler(handler).addClickHandler(cHandler);
grid.setWidget(5, 1,button).setWidget(4,1, wait);
app.add(panel.add(grid));
doc.show(app);
}
function importEventsMulti(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var calendar_name = e.parameter.calendar.split(',');
var addName = e.parameter.addName=='true';
var newsheet = e.parameter.newsheet=='true';
var empty = ''
var startDate = new Date(e.parameter.start);
var endDate = new Date(e.parameter.end);
var sheetName = calendar_name.join('&');
if(newsheet){
try{
var sheet = ss.insertSheet(sheetName,0);
}catch(error){
FUS1=new Date().toString().substr(25,6)+":00";
var sheet = ss.insertSheet(sheetName+'-'+Utilities.formatDate(new Date(), FUS1, "HH:mm:ss"),0);
}
}else{
var allSheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
var sheetNames = '';
for(var s in allSheets){sheetNames+=allSheets[s].getName()};
if(sheetNames.indexOf(sheetName)>-1){
var newsheetName = sheetName+'-'+Utilities.formatDate(new Date(), FUS1, "HH:mm:ss")
}else{
var newsheetName = sheetName
}
var sheet = ss.getActiveSheet().setName(newsheetName);
}
var eventArray = new Array();
for(n=0;n<calendar_name.length;++n){
//Logger.log(calendar_name[n])
var Calendar = CalendarApp.getCalendarsByName(calendar_name[n]);
var events = Calendar[0].getEvents(startDate , endDate, {max: 4000});
if (events[0]){
for (i = 0; i < events.length; i++) {
var line = new Array();
FUS1=events[i].getStartTime().toString().substr(25,6)+":00";
var title = events[i].getTitle()
if(addName){title+=(' ('+calendar_name[n]+')')}
line.push(title);
line.push(Utilities.formatDate(events[i].getStartTime(), FUS1, "dd-MM-yyyy")+' # ' +Utilities.formatDate(events[i].getStartTime(), FUS1, "HH:mm"));
line.push(Utilities.formatDate(events[i].getEndTime(), FUS1, "dd-MM-yyyy")+' # ' +Utilities.formatDate(events[i].getEndTime(), FUS1, "HH:mm"));
line.push(events[i].getLocation());
line.push(' -- ')
line.push(((events[i].getEndTime() - events[i].getStartTime())/ 3600000).toString().replace('.',','));
line.push(' ')
eventArray.push(line);
}
}else {
var startstring = Utilities.formatDate(e.parameter.start, FUS1, "dd-MM-yyyy");
var endstring = Utilities.formatDate(e.parameter.end, FUS1, "dd-MM-yyyy");
empty += calendar_name[n]+' - ';
}
}
if(empty.length>1){
Browser.msgBox('No events between ' + startstring + ' and ' + endstring +' in these calendars :'+empty);
}
//Logger.log(eventArray)
eventArray.sort(function(x,y){
var xp = new Date(x[1].substr(6,4)+'/'+x[1].substr(3,2)+'/'+x[1].substr(0,2)+' '+x[1].substr(13,2)+':'+x[1].substr(16,2)+':00').getTime();
var yp = new Date(y[1].substr(6,4)+'/'+y[1].substr(3,2)+'/'+y[1].substr(0,2)+' '+y[1].substr(13,2)+':'+y[1].substr(16,2)+':00').getTime();
return xp == yp ? 0 : xp > yp ? 1 : -1;
});
// now check for any double entry starting from the end
var eventArrayN = [];
var doublons = [];
for(i in eventArray){
var row = eventArray[i];
var duplicate = false;
for(j in eventArrayN){
if(row.join() == eventArrayN[j].join()){
duplicate = true;
}
}
if(!duplicate){
eventArrayN.push(row);
}else{
doublons.push(row);
}
}
var titre = ['calendars '+calendar_name.join(' + '),'starting ','ending','Ressources','--','duration','totals'];
eventArrayN.unshift(titre);
//Logger.log(eventArrayN.length);
// ss.setActiveSheet(ss.getSheets()[1]);
var lastRow = sheet.getLastRow();
sheet.getDataRange().clearContent().setBorder(false,false,false,false,false,false).setBackgroundColor('#ffffff')
sheet.getRange(1,1,eventArrayN.length,eventArrayN[0].length).setValues(eventArrayN);
sheet.setColumnWidth(1, 450).setColumnWidth(2, 150).setColumnWidth(3, 150).setColumnWidth(4, 250).setColumnWidth(5, 120).setColumnWidth(6, 75).setColumnWidth(7, 450);;
sheet.setFrozenRows(1)
sheet.getRange(1,1,1,eventArrayN[0].length).setBorder(true,true,true,true,true,true).setBackgroundColor('#cccccc').setFontWeight('bold').setHorizontalAlignment('center');
sheet.getRange('G' + (eventArrayN.length+1)).setValue('Total (global)').setBorder(true,true,true,true,true,true).setBackgroundColor('#cccccc');
sheet.getRange('F' + (eventArrayN.length+1)).setFormula('=SUM(F2:F' + (eventArrayN.length)+ ')').setBorder(true,true,true,true,true,true).setBackgroundColor('#cccccc');
var max = sheet.getMaxColumns();
var cstart = sheet.getLastColumn();
var n ;
for(n=max;n>cstart;--n){sheet.deleteColumn(n)}
var app = UiApp.getActiveApplication();
app.close();
if(doublons.length>0){
Browser.msgBox("There are duplicates in "+sheetName+", see log sheet");
var sheet = ss.insertSheet('LOG-'+Utilities.formatDate(new Date(), FUS1, "HH:mm:ss"),1);
Utilities.sleep(1500);
var titre = ['calendar : '+calendar_name.join(' + '),'start ','end','Ressources','--','Duration',' comments '];
doublons.unshift(titre);
sheet.getRange(1,1,doublons.length,doublons[0].length).setValues(doublons)
sheet.setColumnWidth(1, 450).setColumnWidth(2, 150).setColumnWidth(3, 150).setColumnWidth(4, 250).setColumnWidth(5, 120).setColumnWidth(6, 75).setColumnWidth(7, 450);;
sheet.setFrozenRows(1)
sheet.getRange(1,1,1,eventArrayN[0].length).setBorder(true,true,true,true,true,true).setBackgroundColor('#cccccc').setFontWeight('bold').setHorizontalAlignment('center');
sheet.getRange('G' + (eventArrayN.length+1)).setValue('Total global').setBorder(true,true,true,true,true,true).setBackgroundColor('#cccccc');
sheet.getRange('F' + (eventArrayN.length+1)).setFormula('=SUM(F2:F' + (eventArrayN.length)+ ')').setBorder(true,true,true,true,true,true).setBackgroundColor('#cccccc');
var max = sheet.getMaxColumns();
var cstart = sheet.getLastColumn();
var n ;
for(n=max;n>cstart;--n){sheet.deleteColumn(n)}
}
PropertiesService.getScriptProperties().setProperty('startDate',startDate);
PropertiesService.getScriptProperties().setProperty('endDate',endDate);
return app;
}
I figured out how to add an event to a calendar, but then spent a good 8 hours trying to figure out how to edit an existing event (or delete it, either way would get the job done). Here's what I've got:
function UpdateEventTime() {
var cal = CalendarApp.getCalendarById("semehjawioe#group.calendar.google.com");
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 1; // First row of data to process
var numRows = 1; // Number of rows to process
var dataRange = sheet.getRange(startRow, 5, numRows, 5);
var data = dataRange.getValues();
// var oldtstart = SpreadsheetApp.getActiveSheet().getRange('G2');
// var oldtstop = SpreadsheetApp.getActiveSheet().getRange('H2');
// ??????????????????????????????????????????????????
// ?? How do I call up and delete the old event? ??
// ??????????????????????????????????????????????????
for (i in data) {
var row = data[i];
var title = row[0]; // First column
var desc = row[1]; // Second column
var tstart = row[2];
var tstop = row[3];
var loc = row[4];
cal.createEvent(title, tstart, tstop, {description:desc,location:loc});
SpreadsheetApp.getActiveSheet().getRange('G2').setValue(tstart);
SpreadsheetApp.getActiveSheet().getRange('H2').setValue(tstop);
}
}
From what I can tell in the online documentation, you can't pull up an event, you can only pull up all the events in a date range. So at the end of the code I try to store the start time and stop time in a spreadsheet, and then refer back to it next time the script is executed. The commented out section in the middle is where I'm lost. That's where I'm trying to call up the event that I added last time I ran the script. I need to either edit it, or delete it.
Please help.
It would be better if you manage to save the event Ids in spreadsheet along with those details.
If you need to modify or delete those event, just fetch the event by id and do the things.
Modified code
For saving
var event = cal.createEvent(title, tstart, tstop, {description:desc,location:loc});
var eventid = event.getId();
SpreadsheetApp.getActiveSheet().getRange('I2').setValue(eventid);
To fetch the event back at later time
var id = SpreadsheetApp.getActiveSheet().getRange('I2');
var cal = CalendarApp.getCalendarById("semehjawioe#group.calendar.google.com");
var event = cal.getEventSeriesById(id);
//Now modify or delete the event
event.addEmailReminder(minutesBefore);
event.addGuest(email);
event.deleteEvent();
.
.
.
Hope this will help you
Here's a work in progress I put together. 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: "Sync Spreadsheet to Calendar", functionName: "calsync"}];
//{name: “Sync”, functionName: “myimport”}];
ss.addMenu(“Calendar Sync”, menuEntries);
}
function calsync()
{
// This function should be executed from the
// spreadsheet you want to export to the calendar
var mySpreadsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(“Test123″);
var myCalendar = CalendarApp.openByName(“Test”);
//calendar event array
var events = myCalendar.getEvents(new Date(“January 1, 2011 EST”),
new Date(“January 1, 2014 EST”));
if (events[0]) {
var eventarray = new Array();
var line = new Array();
line.push(‘Title’);
line.push(‘Start Date’);
line.push(‘End Date’);
line.push(‘Description’);
line.push(‘Last Modified’);
eventarray.push(line);
var i = 0;
for (i = 0; i < 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('nothing between ' + startDate + ' till ' + endDate);
}
var dataRange = mySpreadsheet.getRange("A2:E53");
var data = dataRange.getValues();
if (data[0]) {
var dataarray = new Array();
var line2 = new Array();
var j = 0;
for (j = 0; j < 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('nothing between ' + startDate + ' till ' + 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("Test123");
// sheet.clearContents();
// sheet.getRange(1, 1, filtered.length, filtered[0].length).setValues(filtered);
}
function UpdateSpreadsheet(data) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Test123");
sheet.clearContents();
sheet.getRange(1, 1, data.length, data[0].length).setValues(data);
}
function UpdateCalendar(data)
{
var myCalendar = CalendarApp.openByName("Test");
// optional – delete existing events
var events = myCalendar.getEvents(new Date("January 1, 2011 EST"),
new Date("January 1, 2013 EST"));
for (var i = 0; i 0) {
if (typeof columnIndex != “number” || columnIndex > data[0].length) {
throw ‘Choose a valide column index’;
}
var r = new Array();
var areDates = true;
for (var i = 0; i < data.length; i++) {
var date = new Date(data[i][columnIndex]);
if (isNaN(date.getYear()) && data[i][columnIndex] != '') areDates = false;
else if (data[i][columnIndex] != '') data[i][columnIndex] = date;
r.push(data[i]);
}
return r.sort(function (a, b) {
if (ascOrDesc) return ((a[columnIndex] b[columnIndex]) ? 1 : 0));
return ((a[columnIndex] > b[columnIndex]) ? -1 : ((a[columnIndex] < b[columnIndex]) ? 1 : 0));
});
}
else {
return data;
}
}
EDIT : I was writing my answer while Waqar was posting his answer... so it's kind of a repetition but I'll just post it so you get an example...
You can access events using their IDs, here is an example that adds guests to calendar events. It also updates a log sheet that shows the results.
function sendinvites(e) {
var ss = SpreadsheetApp.openById('0AnZ5_Sh________UJnVlFtNDM2NUE')
var sh = ss.getSheets()[0]
var logsheet = ss.getSheets()[1]
var last = ss.getLastRow();
var FUS1=new Date().toString().substr(25,8);
var calendar_name = 'test'
var group = GroupsManager.getGroup('groupemail');
var members = group.getAllMembers();
var startDate = new Date(e.parameter.start);
var endDate = new Date(e.parameter.end);
var Calendar = CalendarApp.getCalendarsByName(calendar_name);
var sheetName = calendar_name + "-du-" + Utilities.formatDate(e.parameter.start, FUS1, "dd-MMM-yyyy")
+ "-au-" + Utilities.formatDate(e.parameter.end, FUS1, "dd-MMM-yyyy")
//
var events = Calendar[0].getEvents(startDate , endDate);
if (events[0]) {
var eventarray = new Array();
var line = new Array();
line.push('Titre : '+calendar_name,'Début ','Fin','Localisation','Durée','invités');
eventarray.push(line);
for (i = 0; i < events.length; i++) {
var ID = events[i].getId()
var lr = logsheet.getLastRow();
logsheet.getRange(lr+1,1).setValue(events[i].getTitle()+' / '+Utilities.formatDate(events[i].getStartTime(), FUS1, "dd-MMM-yyyy"));
for(nn=0;nn<members.length;++nn){
logsheet.getRange(lr+1,nn+2).setValue(members[nn]);
Calendar[0].getEventSeriesById(ID).addGuest(members[nn])
}
line = new Array();
line.push(events[i].getTitle());
line.push(Utilities.formatDate(events[i].getStartTime(), FUS1, "dd-MMM-yyyy")+' à ' +Utilities.formatDate(events[i].getStartTime(), FUS1, "HH:mm"));
line.push(Utilities.formatDate(events[i].getEndTime(), FUS1, "dd-MMM-yyyy")+' à ' +Utilities.formatDate(events[i].getEndTime(), FUS1, "HH:mm"));
line.push(events[i].getLocation());
line.push((events[i].getEndTime() - events[i].getStartTime()) / 3600000);
var invitelist='';
var list = Calendar[0].getEventSeriesById(ID).getGuestList()
for(nn=0;nn<list.length;++nn){invitelist+=list[nn].getName()+', '}
line.push(invitelist)
eventarray.push(line);
}
Logger.log(eventarray)
var sheet = SpreadsheetApp.getActiveSpreadsheet().insertSheet(sheetName);
sheet.getRange(1,1,eventarray.length,eventarray[0].length).setValues(eventarray);
sheet.getRange(1,1,1,eventarray[0].length).setBackgroundColor('#ffffcc');
sheet.setColumnWidth(1, 450);sheet.setColumnWidth(2, 150);sheet.setColumnWidth(3, 150);sheet.setColumnWidth(4, 250);sheet.setColumnWidth(5, 75);sheet.setColumnWidth(6, 450);;
sheet.setFrozenRows(1)
} else {
var startstring = Utilities.formatDate(e.parameter.start, FUS1, "dd-MMM-yyyy");
var endstring = Utilities.formatDate(e.parameter.end, FUS1, "dd-MMM-yyyy");
Browser.msgBox('Aucun événement entre le ' + startstring + ' et le ' + endstring +' dans votre agenda :'+calendar_name);
}
}
In case people are looking for this in the future, here's my final code after integrating Waqar's suggestions. It works. When it creates a new event, it grabs the eventID and stores it in the spreadsheet in cell I2. It "updates" existing events by finding the event based on that eventID, deleting it, and replacing it with a new one.
function CreateOrReplaceEvent() {
var cal = CalendarApp.getCalendarById("xxxxxxxxxxxxx#group.calendar.google.com");
var id = SpreadsheetApp.getActiveSheet().getRange('I2').getValue();
if(id != 0){
var event = cal.getEventSeriesById(id);
event.deleteEventSeries();
}
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 1; // First row of data to process
var numRows = 1; // Number of rows to process
var dataRange = sheet.getRange(startRow, 5, numRows, 5);
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
var title = row[0]; // First column
var desc = row[1]; // Second column
var tstart = row[2];
var tstop = row[3];
var loc = row[4];
var event = cal.createEvent(title, tstart, tstop, {description:desc,location:loc});
var eventid = event.getId();
SpreadsheetApp.getActiveSheet().getRange('I2').setValue(eventid);
}
}