I have the following Google Sheets Apps Script to extract calendar invites to a Google Sheet, however, I am trying to make some adjustments that I am struggling to find a solution for:
function getEvents() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet1");
var start_time = sheet.getRange("A2").getValue();
var end_time = sheet.getRange("B2").getValue();
var id_cal = sheet.getRange("P5").getValue();
var cal = CalendarApp.getCalendarById(id_cal);
var events = cal.getEvents(new Date(start_time), new Date(end_time));
for (var i = 0;i<events.length;i++){
var title = events[i].getTitle();
var start_time = events[i].getStartTime();
var end_time = events[i].getEndTime();
var des = events[i].getDescription();
var vis = events[i].getVisibility();
var guestlist = events[i].getGuestList();
sheet.getRange(i+5,1).setValue(title);
sheet.getRange(i+5,2).setValue(start_time);
sheet.getRange(i+5,3).setValue(end_time);
sheet.getRange(i+5,4).setValue(des);
sheet.getRange(i+5,5).setValue(vis);
sheet.getRange(i+5,6).setValue(guestlist);
}
Logger.log("Events have been added to the Spreadsheet");
}
How do I amend this script to:
Extract from several calendars that I have the email addresses in a range of cells (Z1:Z25) instead of just 1 calendar. I have attempted changing the range, but it only pulls the calendar from the top cell.
Include all accepted/pending attendees (including the organiser). I have attempted to add .getGuestList, but this returns 'EventGuest'
Include the calendar that event was taken from
I believe your goal is as follows.
You want to retrieve the events from multiple Calendars by the calendar IDs which are retrieved from the cells "Z1:Z25" of the Spreadsheet.
As the data, from Include all accepted/pending attendees (including the organiser)., you want to add the user's email addresses.
You want to add the calendar IDs as the additional value.
Modification points:
In your script, only one Calendar ID is used. In order to achieve your goal, it is required to retrieve the calendar IDs from the cells "Z1:Z25".
About I have attempted to add .getGuestList, but this returns 'EventGuest', the method of getGuestList() returns EventGuest object. I think that this is the reason for your issue.
In your script, setValue is used in a loop. In this case, the process cost becomes high. Ref
When these points are reflected in your script, it becomes as follows.
Modified script:
function getEvents() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet1");
var [start_time, end_time] = sheet.getRange("A2:B2").getValues()[0];
var dates = [new Date(start_time), new Date(end_time)]; // If the cell value is date object, you can also use [start_time, end_time]
var ids = sheet.getRange("Z1:Z25").getValues().reduce((ar, [z]) => {
if (z) ar.push(z);
return ar;
}, []);
var values = ids.flatMap(id_cal => {
var cal = CalendarApp.getCalendarById(id_cal);
if (!cal) return [];
var events = cal.getEvents(...dates);
return events.map(e => {
var title = e.getTitle();
var start = e.getStartTime();
var end = e.getEndTime();
var des = e.getDescription();
var vis = e.getVisibility().toString(); // or e.getVisibility()
var guestlist = e.getGuestList().map(f => f.getEmail()).join(",");
return [id_cal, title, start, end, des, vis, guestlist];
});
});
sheet.getRange(5, 1, values.length, values[0].length).setValues(values);
Logger.log("Events have been added to the Spreadsheet");
}
When this script is run, the calendar IDs are retrieved from "Z1:Z25" of "Sheet1". And, the events are retrieved, and the values are retrieved from each event. In this case, the calendar ID, event title, start time, end time, description, visibility, and guest email addresses are put on the sheet in order.
If you want to change the order of values, please modify return [id_cal, title, start, end, des, vis, guestlist];.
If you want to change the user's email to the user's name, please modify f.getEmail() to f.getName().
Note:
This modified script is a simple modification. So, please modify this for your actual situation.
References:
map()
Class EventGuest
Try something like this:
function getEvents() {
var ss = SpreadsheetApp.getActive();
var sh = ss.getSheetByName("Sheet1");
var start = sh.getRange("A2").getValue();
var end = sh.getRange("B2").getValue();
const ids = [];
CalendarApp.getAllCalendars().forEach(c => ids.push(c.getId()));
ids.forEach(id => {
let cal = CalendarApp.getCalendarById(id);
let events = cal.getEvents(new Date(start), new Date(end));
for (var i = 0; i < events.length; i++) {
var title = events[i].getTitle();
var start = events[i].getStartTime();
var end = events[i].getEndTime();
var des = events[i].getDescription();
var vis = events[i].getVisibility();
var guestlist = events[i].getGuestList();
let row = sh.getLastRow() + 1
sh.getRange(sh.getLastRow() + 1, 1,1,5).setValues([[title,start,end,des,vis,guestlist]]);
}
})
Logger.log("Events have been added to the Spreadsheet");
}
I'll leave it up to you to add the additional items as this is not a venue for getting free scripts.
I believe this will be a super easy question for you. I downloaded a YT script to automatically update YT views on Google Sheets which you can find here (https://developers.google.com/gsuite/solutions/youtube-tracker).
I have a spreadsheet with 12 tabs and the code has a function to go through every tab in the spreadsheet.
function markVideos() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
// Runs through process for each tab in Spreadsheet.
sheets.forEach(function(dataSheet) {
var tabName = dataSheet.getName();
var range = dataSheet.getDataRange();
var numRows = range.getNumRows();
var rows = range.getValues();
var headerRow = rows[0];
I want to change it to apply to a specific tab only, let's say "Sheet12", instead of running it for every tab.
function markVideos() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet12");
// Runs through process for each tab in Spreadsheet.
function NameOfTheFunction(dataSheet) {
var tabName = dataSheet.getName();
var range = dataSheet.getDataRange();
var numRows = range.getNumRows();
var rows = range.getValues();
var headerRow = rows[0];
I tried this but had no luck because it doesn't seem to be applying the function to the specific sheet. I believe this is super easy fix but I have no idea about programming.
Remove the forEach statement and use getSheetByName instead of getSheets:
function markVideos() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var tabName = 'Sheet12';
var dataSheet = ss.getSheetByName(tabName)
var range = dataSheet.getDataRange();
var numRows = range.getNumRows();
var rows = range.getValues();
var headerRow = rows[0];
}
Array ForEach() Method calls a function once for each element in an array. That is why a function must be defined that will take an array element function(dataSheet)
Since you only need to access 1 sheet based on its sheet name.
You don't need to define a function to access the properties of that sheet.
Sample:
Sample Code:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheetByName("Sheet1");
var tabName = sheets.getName();
var range = sheets.getDataRange();
var numRows = range.getNumRows();
var rows = range.getValues();
var headerRow = rows[0];
Logger.log(tabName);
Logger.log(numRows);
Logger.log(rows);
Logger.log(headerRow);
}
Logger Log Output:
References:
Class Sheet Methods
SpreadsheetApp Methods
I’m trying to use this script below to create a calendar event from dates and names entered in Sheets. I have one unresolved issue -- the code runs successfully, but the issue is that from the given range (A1:C17) only the last row (17) turns into a calendar event. I just don’t get this. Checked so far: Sheets range and formats, all APIs and authorizations, Calendar settings and almost everything I came to think of. I've also searched for documentation on this particular error/fault and have found none so far.
function CreateEvent () {
var spreadsheet = SpreadsheetApp.getActiveSheet();
var calendarId = 'primary'
var eventCal = CalendarApp.getCalendarById(calendarId);
var signups = spreadsheet.getRange('A1:C17').getValues();
for (x=0; x<signups.length; x++) {
var shift = signups[x];
var startTime = shift[0];
var endTime = shift[1];
var campaignname = shift[2];
}
eventCal.createEvent(campaignname, startTime, endTime);
}
My Sheets range A1:C17
My Calendar entry from May after running the script, all 16 entries before the last row are absent
function CreateEvent () {
var spreadsheet = SpreadsheetApp.getActiveSheet();
var calendarId = 'primary'
var eventCal = CalendarApp.getCalendarById(calendarId);
var signups = spreadsheet.getRange('A1:C17').getValues();
for (x=0; x<signups.length; x++) {
var shift = signups[x];
var startTime = shift[0];
var endTime = shift[1];
var campaignname = shift[2];
eventCal.createEvent(campaignname, startTime, endTime);
}
}
in Google Sheets I have to repeat a function because getSheetByName() does not accept an array of sheets, it only accepts one sheet.
Is there a way to have one function that loops through specified sheets (not all sheets)?
i.e.
("Sheet1", "Sheet2" ) etc.
function recordHistory_1() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet1");
var source = sheet.getRange("A2:B2");
var values = source.getValues();
values[0][0] = new Date();
sheet.appendRow(values[0]);
};
function recordHistory_2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet2");
var source = sheet.getRange("A2:B2");
var values = source.getValues();
values[0][0] = new Date();
sheet.appendRow(values[0]);
};
Reason I'm asking is because I have over 20 sheets, and so I have to write this function 20 times...
You can generalize / reuse the same function for 20 different calls as follows.
var sheetListArray = ["Sheet1", "Sheet2", "Sheet3"......"Sheet20"]
var ss = SpreadsheetApp.getActiveSpreadsheet();
for( var i = 1 ; i <= sheetListArray.length ; i++)
// You can call the below function 20 time with different Sheet name each time.
recordHistory(sheetListArray[i]);
}
function recordHistory(sheetName) {
var sheet = ss.getSheetByName(sheetName);
var source = sheet.getRange("A2:B2");
var values = source.getValues();
values[0][0] = new Date();
sheet.appendRow(values[0]);
}
You can also call the function once and loop through an array of sheetnames inside the function.
function recordHistory() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
["Sheet1", "Sheet2", "Sheet3"].forEach(function (s) {
var sheet = ss.getSheetByName(s);
var values = sheet.getRange('A2:B2').getValues()
values[0][0] = new Date();
sheet.appendRow(values[0]);
})
}
I am trying to add to my script to copy only certain cells from a template I have set up. Currently I have a menu item that creates a "copy" of the template sheet, but it is currently copying everything. I am also no pro at this and have only been trying to figure out this coding system for a couple of days. Any help would be wonderful. Below is the script I currently have.
function onOpen() {
var menu = [{name: "Copy Template", functionName: "newSheet"}];
SpreadsheetApp.getActiveSpreadsheet().addMenu("New Sheet", menu);
}
function newSheet() {
var user = Session.getEffectiveUser().getEmail().split("#")[0];
var sheetName = formatDate()+' '+user;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var templateSheet = ss.getActiveSheet();
ss.insertSheet(sheetName, 1, {template: templateSheet});
}
function formatDate() {
var month, day, d = new Date();
month = ('0'+(d.getMonth()+1)).slice(-2);
day = ('0'+d.getDate()).slice(-2);
return d.getFullYear()+'-'+month+'-'+day;
}
function onEdit() {
var user = Session.getEffectiveUser().getEmail().split("#")[0];
var ss, date;
ss = SpreadsheetApp.getActiveSpreadsheet();
date = new Date();
ss.getActiveSheet().getRange('j2').setValue(date).setNumberFormat('H:mm');
ss.getActiveSheet().getRange('i2').setValue(user);
}
You can probally use range:
function newSheet() {
var user = Session.getEffectiveUser().getEmail().split("#")[0];
var sheetName = formatDate()+' '+user;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var templateSheet = ss.getActiveSheet();
var getRange =SpreadsheetApp.getActiveSpreadsheet().getSheetByName([TEMPLATE_SHEET_NAME]).getRange('YOUR RANGE Ex A1:A10').getValues();
....
....
....
}
And after use again get the range where you want them and use SetValues(getRange)