Google Form creates Google Slides from template Script - javascript

I have a script that on Form submit takes the data from the spreadsheet and creates a copy of a template and populates the google docs. I am trying to accomplish the same thing from google form to google slides.
First script I use for the google forms to google docs. The second script is my attempt of using the same principles and applying to google slides. My issue is I'm getting an error saying TypeError: values.forEach is not a function (line 109, file "Code") in relation to values.forEach(function(page). Any suggestions on how I could go about solving this?
Google Form to Google Sheets
function autoFillGoogleDocFromForm(e) {
var timestamp = e.values[0];
var address = e.values[1];
var image = e.values[2];
var price = e.values[3];
var summary = e.values[4];
var type = e.values[5];
var year_built = e.values[6];
var bed = e.values[7];
var bath = e.values[8];
var home_size = e.values[9];
var lot_size = e.values[10];
var occupancy = e.values[11];
var templateFile = DriveApp.getFileById("xxxxxxxx");
var templateResponseFolder = DriveApp.getFolderById("yyyyyyyyyy")
var copy = templateFile.makeCopy( address , templateResponseFolder);
var doc = DocumentApp.openById(copy.getId())
var body = doc.getBody();
body.replaceText("{{address}}", address);
body.replaceText("{{price}}", price);
body.replaceText("{{summary}}", summary);
body.replaceText("{{type}}", type);
body.replaceText("{{year_built}}", year_built);
body.replaceText("{{beds}}", bed);
body.replaceText("{{baths}}", bath);
body.replaceText("{{home_size}}", home_size);
body.replaceText("{{lot_size}}", lot_size);
body.replaceText("{{occupancy}}", occupancy);
doc.saveAndClose;
}
Google Form to Google Slides
function generateLandingPagesReport(){
var dataSpreadsheetUrl = "https://docs.google.com/spreadsheets/xxxxxxxxx/edit"
var Presentation_ID = "xxxxxxxxxxxxxx";
var ss = SpreadsheetApp.openByUrl(dataSpreadsheetUrl);
var deck = SlidesApp.openById(Presentation_ID);
var sheet = ss.getSheetByName('Sheet1');
var values = sheet.getRange('A1:J17').getValues;
var slides = deck.getSlides();
var templateSlide = slides[1];
var presLength = slides.length;
values.forEach(function(page){
values.forEach(function(page){
if(page[0]){
var landingPage = page[0];
var sessions = page[1];
var newSessions = page[2];
}
templateSlide.duplicate(); // duplicate the template page
/*slides = deck.getSlides(); // update the slides array for indexes and length*/
newSlide = slides[2]; // declare the new page to update
var shapes = (newSlide.getShapes());
shapes.forEach(function(shape){
shape.getText().replaceAllText('{{landing page}}', landingPage);
shape.getText().replaceAllText('{{sessions}}', sessions);
shape.getText().replaceAllText('{{new sessions}}',newSessions);
});
presLength = slides.length;
newSlide.move(presLength);
//end our condition statement
}); //close our loop of values
//remove template slide
templateSlide.remove();
});
}

You're missing the parenthesis when calling the getValue() method.
Change this:
var values = sheet.getRange('A1:J17').getValues;
To this:
var values = sheet.getRange('A1:J17').getValues();

Not exactly what I was looking for but this uses the first Row to identify the tag inside the Google slides template like {{title}} and replaces that with the value in the second row of the sheet
function createPresentation() {
var templateFile = DriveApp.getFileById("1YVEA4WtU1Kf6nZRgHpwnKBIR-V6rRN6s9zCdOQDkWNI");
var templateResponseFolder = DriveApp.getFolderById("1k7rcfXODij4o4arSULuKZUHbit1m_X64");
var copy = templateFile.makeCopy("New" , templateResponseFolder);
var Presentation = SlidesApp.openById(copy.getId());
var values = SpreadsheetApp.getActive().getDataRange().getValues();
values.forEach(function(row) {
var templateVariable = row[0];
var templateValue = row[1];
Presentation.replaceAllText(templateVariable, templateValue);
});
}

After you have copy the template page, you work on it and try to do replace.
However, change may be pending such that newSlide = slides[2]; give undefined.
You may need to try saveAndClose() before performing any actions.
templateSlide.duplicate(); // duplicate the template page
/*slides = deck.getSlides(); // update the slides array for indexes and length*/
/* flush the presentation */
deck.saveAndClose();
deck = SlidesApp.openById(Presentation_ID);
slides = deck.getSlides();
newSlide = slides[2]; // declare the new page to update
var shapes = (newSlide.getShapes());
shapes.forEach(function(shape){
shape.getText().replaceAllText('{{landing page}}', landingPage);
shape.getText().replaceAllText('{{sessions}}', sessions);
shape.getText().replaceAllText('{{new sessions}}',newSessions);
});

Related

Copy values to next column(if blank) in the same row. If not blank, copy to the second column(if blank) in same row. Repeat

Disclaimer: Im very new to google scripts. I jumbled together this code with mixed success.
When I run the script, it works fine with the first two attempts. Then it doesnt work after that because column Q now has values in other cells within the column and the script is technically correct but not running at intended. I need to ignore column Q cells that are not blank and still run the script to copy P values to the other cells in column Q.
Also, when column Q with in the same row is not blank, I need to copy the value from column P to column R (if blank). Rinse and Repeat script...
function copyVals () {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange ("Sheet1!P2:P");
var destSheet = ss.getSheetByName("Sheet1");
var destRange = destSheet.getRange('Q2:Q')
var destRange2 = destSheet.getRange('R2:R')
if (destRange.isBlank()) {
source.copyTo (destRange, {contentsOnly: true});
source.clear ();
}
if (destRange2.isBlank()) {
source.copyTo (destRange2, {contentsOnly: true});
source.clear ();
}
}
You need to do the blank check for each cell separately
However, if you do it wiht the Apps Script method isBlank() - this will make your code a bit slow.
I suggest you to
retreive the existing values both in the source and destination ranges with getValues
check for each of the destinations values either those are empty and replace the empty values through source values
assign the modified values back to the sheet with setValues
Sample code:
function copyVals () {
var ss = SpreadsheetApp.getActiveSpreadsheet ()
var sheet = ss.getSheetByName("Sheet1")
var lastRow = sheet.getLastRow()
var source = sheet.getRange ("P2:P" + lastRow)
var destSheet = sheet
var destRange = destSheet.getRange('Q2:Q' + lastRow)
var destRange2 = destSheet.getRange('R2:R' + lastRow)
var sourceValues = source.getValues().flat()
var destValues = destRange.getValues()
var dest2Values = destRange2.getValues()
sourceValues.forEach(function(value, i){
console.log("i" + i)
if (destValues[i][0] == "") {
destValues[i][0] = value
}
if (dest2Values[i][0] == "") {
dest2Values[i][0] = value
}
})
destRange.setValues(destValues)
destRange2.setValues(dest2Values)
source.clear ();
}
UPDATE
If you want to copy to column Q and R alternately, you can use script properties to save the run count of the script and execute different code blocks for odd and even number.
Sample:
function copyVals () {
var ss = SpreadsheetApp.getActiveSpreadsheet ()
var sheet = ss.getSheetByName("Sheet1")
var lastRow = sheet.getLastRow()
var source = sheet.getRange ("P2:P" + lastRow)
var destSheet = sheet
var destRange = destSheet.getRange('Q2:Q' + lastRow)
var destRange2 = destSheet.getRange('R2:R' + lastRow)
var sourceValues = source.getValues().flat()
var destValues = destRange.getValues()
var dest2Values = destRange2.getValues()
var scriptProperties = PropertiesService.getScriptProperties()
var myProperty = scriptProperties.getProperty('timesCalled')
if (!myProperty){
myProperty = "1"
}
myProperty = JSON.parse(myProperty)
var isOdd = myProperty % 2
if(isOdd){
sourceValues.forEach(function(value, i){
console.log("i" + i)
if (destValues[i][0] == "") {
destValues[i][0] = value
}
})
destRange.setValues(destValues)
} else{
sourceValues.forEach(function(value, i){
if (dest2Values[i][0] == "") {
dest2Values[i][0] = value
}
})
destRange2.setValues(dest2Values)
}
source.clear ()
myProperty++
scriptProperties.setProperty('timesCalled', JSON.stringify(myProperty))
}

Google Slides API / Apps Script - find URLs and make them into hyperlinks

My script pulls rows from a form-populated spreadsheet and applies the values to a slide template.
They submit a Title, Description, and a Link to the resource they are submitting.
I need the "Link", which should be submitted as an URL, to automatically become a hyperlink when the slide is created. Everything I've tried has returned an error. I want to run .setLinkUrl(link) on the previously inserted link text. I just cant get it to stick. Any help would be appreciated.
--below is the function I'm trying to run--
function dataInjectionNN() {
var dataSpreadsheetUrl = "...spreadsheeturl.urlytypestuff..."
var ss = SpreadsheetApp.openByUrl(dataSpreadsheetUrl);
var deck = SlidesApp.getActivePresentation();
var mathCluster = deck.getName();
// Logger.log(mathCluster)
var sheet = ss.getSheetByName(mathCluster);
var lastR = sheet.getLastRow();
var range =sheet.getDataRange();
// Logger.log(range.getLastRow() + " Is the last Column.");
var values = range.getValues();
// Logger.log(values);
var slides = deck.getSlides();
var presLength = slides.length;
var templateSlide = slides[1];
values.forEach(function(page){
// run if the presentation has less slides that the number of form entries
if((presLength-2) < lastR){
if(page[3] = mathCluster){
var title = page[9];
var link = page[10];
var desc = page[11];
templateSlide.duplicate();//Duplicate the template page
slides = deck.getSlides();//update the slides array for indexes and length
newSlide = slides[2]; //declare the new page to update
var shapes = (newSlide.getShapes());
shapes.forEach(function(shape){
shape.getText().replaceAllText('<<Title>>',title);
shape.getText().replaceAllText('<<Link>>',link);
shape.getText().replaceAllText('<<Description>>',desc);
presLength = slides.length;
newSlide.move(presLength);
})
}
}
});
}

Filter CVS before importing to Google Spreadsheet

I have a Script in a Google Spreadsheet, the script downloads a zipped CSV from an URL and then import it to the spreadsheet. Actually, the CVS is too big and I don't need all the data from it. My question is, How can I filter the data before importing it to the spreadsheet? For example filter Column A with X value.
This is the code I have so far:
function descargarzip()
{
var urldescarga = "http://187.191.75.115/gobmx/salud/datos_abiertos/datos_abiertos_covid19.zip"
var url = urldescarga
var zipblob = UrlFetchApp.fetch(url).getBlob();
zipblob.setContentTypeFromExtension();
var unzipblob = Utilities.unzip(zipblob);
var unzipstr=unzipblob[0].getDataAsString();
var csv = Utilities.parseCsv(unzipstr);
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
ss.getRange(1, 1, csv.length, csv[0].length).setValues(csv);
}
Thank you in advance!
Try this:
function descargarzip() {
var urldescarga = "http://187.191.75.115/gobmx/salud/datos_abiertos/datos_abiertos_covid19.zip"
var url = urldescarga
var zipblob = UrlFetchApp.fetch(url).getBlob();
zipblob.setContentTypeFromExtension();
var unzipblob = Utilities.unzip(zipblob);
var unzipstr=unzipblob[0].getDataAsString();
var csv = Utilities.parseCsv(unzipstr);
var x = 'You enter the contents x';
csv.forEach(function(r,i){
if(r[0]==x) {
r[0]='';//You have to put something back in there because the csv has to be a rectangular array for setValues();
}
});//You could remove an entire line or an entire column
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
ss.getRange(1, 1, csv.length, csv[0].length).setValues(csv);
}
If #TheMaster is correct then try this:
function descargarzip() {
var urldescarga = "http://187.191.75.115/gobmx/salud/datos_abiertos/datos_abiertos_covid19.zip"
var url = urldescarga
var zipblob = UrlFetchApp.fetch(url).getBlob();
zipblob.setContentTypeFromExtension();
var unzipblob = Utilities.unzip(zipblob);
var unzipstr=unzipblob[0].getDataAsString();
var csv = Utilities.parseCsv(unzipstr);
var x = 'You enter the contents x';
var d=0;
//I tested this on some of my data and I believe it works
for(var i=0;(i-d)<csv.length;i++) {
if(csv[i-d][0]==x) {
csv.splice(i-d++,1);//I think this is correct but I could be wrong in here because I mostly use this approach for deleting rows not portions of the array. So if you have problems the please share your csv data and I will debug it.
}
}
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
ss.getRange(1, 1, csv.length, csv[0].length).setValues(csv);
}

Trouble creating events in Google Agenda from Google Sheets with a script

I created a script in a Google Sheet to create events in Google Agenda, in order to study.
My goal is to create many events like this : if i study on D0, the first event must be at D+3, then D+10 , D+30, D+60.
I get many problems :
the script write "AJOUTE" in each box of the column (which means in french that the events are added to Agenda) , even if they are not completed with dates (I want to update for each chapter when it's done, and I do not do a whole chapter the same day!)
the script doesn't care if the events are already created, so i get multiple events for the same thing...
My script is the following :
var EVENT_IMPORTED = "AJOUTE";
var ss = SpreadsheetApp.getActiveSpreadsheet();
function onOpen() {
var menuEntries = [{name: "Ajouter les événements à l'agenda", functionName: "importCalendar"}];
ss.addMenu("Agenda", menuEntries);
}
function importCalendar() {
var sheet = SpreadsheetApp.getActiveSheet();
var startcolumn = 1
var numcolumns = 30
var dataRange = sheet.getRange(startcolumn, 1, numcolumns, 6)
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var column = data[i];
var titre = column[1];
var DateJ3 = column[2];
var DateJ10 = column[3];
var DateJ30 = column[4];
var DateJ60 = column[5];
var eventImported = column[6];
var setupInfo = ss.getSheetByName("agenda");
var calendarName = setupInfo.getRange("A1").getValue();
if (eventImported != EVENT_IMPORTED && titre != "") {
var cal = CalendarApp.openByName(calendarName);
cal.createAllDayEvent(titre, new Date(DateJ3));
cal.createAllDayEvent(titre, new Date(DateJ10));
cal.createAllDayEvent(titre, new Date(DateJ30));
cal.createAllDayEvent(titre, new Date(DateJ60));
sheet.getRange(startcolumn + i, 7).setValue(EVENT_IMPORTED);
SpreadsheetApp.flush();
}
}
}
Thank you in advance, i'm despair, i searched for hours but found nothing to help...

Looping through a list of Google Calendar Users

I have a list of Google Email users in a google sheet(named Master, column E). Each user also has a blank sheet named after that email address (User#Whatever.com).
What I'm aiming to do it go through the user list, retrieve the calendar entries for today for each user, and enter them into their relevant sheet. So far I have the following code, but it's returning
TypeError: Cannot call method "getEventsForDay" of null. (line 15,
file "Calendar Update")
Code is below:
var employeeDataRange = SpreadsheetApp.getActiveSpreadsheet().getRange("Master!E2:E");
var employeeObjects = employeeDataRange.getValues();
for (var j=0; j<employeeObjects.length; j++) {
var cal = CalendarApp.getCalendarById(employeeObjects[j]);
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(employeeObjects[j])
var today = new Date();
var events = CalendarApp.getCalendarById(cal).getEventsForDay(today);
for (var i=0;i<events.length;i++) {
var details=[[events[i].getTitle(), events[i].getStartTime(), events[i].getEndTime(), events[i].getAllTagKeys()]];
var row=i+1;
var range=sheet.getRange(row,1,1,4);
range.setValues(details);
}
}
}
Cheers,
Dan
Are you sure that you have all permissions to see those calendars and their events?
Moreover, you have this row
var cal = CalendarApp.getCalendarById(employeeObjects[j]);
where employeeObjects[j] is the calendar id and cal is the relative calendar.
Two rows after you have
var events = CalendarApp.getCalendarById(cal).getEventsForDay(today);
but cal is a calendar, not its id. Why you don't use cal.getEventsForDay(today)?
I Figured it out:
var calendar = SpreadsheetApp.getActiveSpreadsheet().getRange("Master!E2:E");
var employeeObjects = calendar.getValues();
for (var j=0; j<employeeObjects.length; j++) {
var cal = CalendarApp.getCalendarById(employeeObjects[j]);
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(employeeObjects[j])
var today = new Date();
var events = CalendarApp.getCalendarById(employeeObjects[j]).getEventsForDay(today);
for (var i=0;i<events.length;i++) {
var details=[[events[i].getTitle(), events[i].getStartTime(), events[i].getEndTime(), events[i].getAllTagKeys()]];
var row=i+1;
var range=sheet.getRange(row,1,1,4);
range.setValues(details);
}
}
}

Categories

Resources