Get Sheet By Name not working - only accepts one sheet - google-apps-script

I have a spreadsheet connected to a google form, however I have another tab "sheet3" which uses array formula from "Form Responses 1".
The script I am using which sends all questions and answers to other emails does not take the info from "sheet3", only from "Form responses 1".
I have tried so many different things and nothing. Here's my script:
function sendFormAnswers(data) {
Logger.log("sendEmail");
var values = SpreadsheetApp.getActiveSheet();
var row = values.getLastRow();
var s = SpreadsheetApp.getActive().getSheetByName("sheet3").activate();
var headers = s.getRange(1,2,1,s.getLastColumn()-1).getValues()[0];
var values = s.getRange(s.getLastRow(),1,s.getLastRow(),s.getLastColumn()-1).getValues()[0];
var row = values[0];
var timestap = values[0];
var ABS = values[1];
var OPS = values[2];
many thanks

Related

getValues and getBackgrouds not returning data in Google Apps Script

I'm trying to create a code that checks to see if a cell has a checkbox checked (or unchecked) and then copies data from a corresponding cell on that row onto another "Summary" sheet. The "if checked then copy data" portion has not been included below.
The problem I'm having is that neither getValues nor getBackgound seems to be returning data.
When I run my code, the Logger shows that every checkbox value is "false" (even though some are checked and I have their values set to 1 (checked) and 0 (unchecked) using the data validation in the spreadsheet settings.
If I switch to getBackgrounds, the Logger shows that every cell's background is white "#ffffff", even though the cells are red.
[[I want my code to iterate over every sheet, row, and column. It seems to be iterating fine, but not retrieving the data.]]
What I am doing wrong? Here's my full code:
function MAPSuccess() {
var app = SpreadsheetApp;
var ss = SpreadsheetApp.openByUrl(
'https://docs.google.com/spreadsheets/d/1UUdiLsz2OvKdqnr2KB0Tx74gzrGx0m4XUA5oNMUB06k/edit');
var allsheets = ss.getSheets();
var s = ss.getNumSheets();
var master = app.getActiveSpreadsheet().getSheetByName("Master");
var masterLastRow = master.getLastRow();
for (var s = 2; s < allsheets.length; s++) {
var sheet = app.getActiveSpreadsheet().getActiveSheet();
var r = sheet.getCurrentCell().getRow();
var lastrow = sheet.getLastRow();
var lastcol = sheet.getLastColumn();
var temail = sheet.getRange(1,2);
var tSJCOE = sheet.getRange(2,2);
var c = sheet.getActiveCell().getColumn();
for(var r = 4;r<=lastrow;r++){
var name= sheet.getRange(r,1).getValue();
var lname= sheet.getRange(r,2).getValue();
var email= sheet.getRange(r,3).getValue();
var pemail= sheet.getRange(r,4).getValue();
var info = [
[name, lname, email, pemail]
]
var range = sheet.getRange(r,1,1,lastcol);
var rowValues = range.getValues();
var cell = [
[s,r,c]
];
Logger.log(rowValues);
Logger.log(name);
// Logger.log(checkRow);
Logger.log(cell);
It looks like you are always performing your actions on the active sheet, instead of accessing the sheets in "allsheets".
var sheet = app.getActiveSpreadsheet().getActiveSheet();
should be
var sheet = allsheets[s];
You may also be misusing "getCurrentCell" on the next line, since that will return whichever cell is currently selected in the spreadsheet, of which there is always only one, regardless of which sheet you are accessing.

How to find a column value within an active row

How do I find the data in a column within an active row that is already defined in Google Apps Script?
I have an on edit function that sends an email when a column f is edited to a specific value. I need to find out the value in column b in order to include the value in the body of the message.
I have tried to use a range, but I am not understanding how i can define the second column for the active range that is already defined in the row variable. Here is what my code looks like. var called Values is the row of code I need help with. The row var is looking at the correct row. Any help is greatly appreciated.
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var sheetName = sheet.getName();
var cell = sheet.getActiveCell().getA1Notation();
var row = sheet.getActiveRange().getRow();
var cellvalue = sheet.getActiveCell().getValue().toString();
var values = row.getcell()[0,2].getvalue().toString();
var recipients = "kel...#trafficbuilders.us";
var message = '';
if(cellvalue === '✔'){
message = 'All Items have been received for .';
var subject = 'All Items have been received for ' ;
var body = message + ' Visit ' + ss.getUrl() + ' to view the changes';
MailApp.sendEmail(recipients, subject, body);
}
}
To fetch a certain data/value from a certain cell, here's what you can do:
First identify the cell where data is located using getRange(). There are several ways to use getRange.
Sample from the docs:
// Get a range A1:D4 on sheet titled "Invoices"
var ss = SpreadsheetApp.getActiveSpreadsheet();
var range = ss.getRange("Sheet!A1:D4");
// Get cell A1 on the first sheet
var sheet = ss.getSheets()[0];
var cell = sheet.getRange("A1");
To actually fetch the content/data, use getValues() or getValue()
sample snippets:
// The code below gets the values for the range C2:G8
// in the active spreadsheet. Note that this is a JavaScript array.
var values = SpreadsheetApp.getActiveSheet().getRange(2, 3, 6, 4).getValues();
Logger.log(values[0][0]);
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
// Passing only two arguments returns a "range" with a single cell.
var range = sheet.getRange(1, 1);
var values = range.getValues();
Logger.log(values[0][0]);

GAS - Select (Get) Spreadsheet per GForm input

My 1st question in Stack Overflow.
I have a Google Spreadsheet with 4 individual sheets.
Sheet1 is responses from GForm. Sheet2,3,4 have same data but in 3 languages English, Tamil, Hindi and named English, Tamil, Hindi.
At present the Script takes cell value date from Sheet1, matches the data in the language Tamil sheet, mail merges with the correct language Tamil GDoc and emails it.
Now, I cannot figure out how to make the Script pick a different language Gsheet, one of the 3, depending upon the evalues4 from Form input, which is a Radio Button.
Can someone help me to figure it out?
Select appropriate language
Gsheet using ss.getSheetByName and
GDoc using DriveApp.getFileById
based on Form response evalues4.
Here is the code and which works fine, if I input just one language by name/sheetID/DocID.
//Get information from the form and set as variables
function onFormSubmit(e)
{
var Time = e.values[0];
var email = e.values[1];
var fog = e.values[2];
var mog = e.values[3];
var lang = e.values[4];
var do_date = e.values[5];
//Match chosen date from data sheet & get Row Number
function findInColumn() {
var data = do_date;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName("Tamil");
var range = sheet1.getRange(1,1,sheet1.getLastRow(),1);
var values= range.getValues();
var row = 0;
while ( values[row] && values[row][0] !== data ) {
row++;
}
if (values[row][0] === data)
return row+1;
else
return -1;
}
//Use above Row number to load in Range, get values, assign to variable cells
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet3 = ss.getSheetByName("Tamil");
// Get range of cells in All columns and All rows with entries
var dataRange = sheet3.getRange(findInColumn(), 1, 1, sheet3.getLastColumn());
// Get entries for each row in the Range.
var data = dataRange.getValues();
// Set each value to a unique variable
for (i in data) {
var cell = data[i];
// Get document template, copy it as a new doc with Name and email, and save the id
var copyId = DriveApp.getFileById("1Nxxxxxxxxxxxxxx2k")
Sorry, completely forgot that I had asked the question here. I solved it the same weekend, by using the If - else [Note: Instead of var ss I used var ssn, and instead of var sheet3 I used var tocopyID in the rewrite]
//Use above Row number to load in Range, get values, assign to variable cells
var ss = SpreadsheetApp.getActiveSpreadsheet();
if (lang === "Tamil"){
var ssn = ss.getSheetByName("Tamil");
var tocopyId = DriveApp.getFileById("1NxxxxTamil");
}
else if (lang === "Hindi"){
var ssn = ss.getSheetByName("Hindi");
var tocopyId = DriveApp.getFileById("Hindi");
}
else if (lang === "English"){
var ssn = ss.getSheetByName("English");
var tocopyId = DriveApp.getFileById("1NxxxxEnglish");
}
You could use you lang variable to get the correct sheet, since they've got the same name. Like :
var sheet1 = ss.getSheetByName(lang); // where lang = "Tamil" for example
For using the correct template, you can store the id of your template with the Properties like:
var templateId = PropertiesService.getScriptProperties().getProperty(lang); // where lang = "Tamil" for example
var copyId = DriveApp.getFileById(templateId);
Where you have properties set with the language name you want. You can set them with code :
PropertiesService.getScriptProperties().setProperty('Tamil', '1Nxxxxxxxxxxxxxx2k');

Sum up numeric inputs in a Google Form

SOF friends,
I have a form which has a bunch of numeric fields among some date and string fields.
How to add up the numeric values and include the total as a column in the spreadsheet where it saves the responses? Where do I write the script for this? At the form level or at the spreadsheet level?
Here's what I have at this time, as a trigger on form submit which doesn't work:
function myFunction() {
Logger.log("Spreadsheet: %s", SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName());
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
//sheet.setActiveSelection("M1:M").clear();
var range = sheet.getDataRange();
var values = range.getValues();
var lastrow = range.getLastRow();
var lastcolumn = range.getLastColumn();
Logger.log(lastrow);
Logger.log(lastcolumn);
Logger.log(values[lastrow][10]);
var coll = values[lastrow][6];
var drv = values[lastrow][7];
var clnr = ((values[lastrow][8] != "")? values[lastrow][8]:0);
var dsl = values[lastrow][10];
var gen = values[lastrow][11];
var tot = coll + drv + clnr + dsl + gen;
var singlecell = sheet.getRange(lastrow, 13);
singlecell.setValue(tot);
Logger.log(tot);
}
Code
Example of code to be added to a project bounded to a spreadsheet.
function sumFormResponseItems(e) {
var firstSummand = parseInt(e.namedValues['First summand'][0],10);
var secondSummand = parseInt(e.namedValues['Second summand'][0],10);
var range = e.range;
var row = range.getRow();
var lastColumn = range.getLastColumn();
range.getSheet().getRange(row,lastColumn+1).setValue(firstSummand + secondSummand )
}
After you add the code, add an on form submit trigger to make it work.
Explanation
The above code sums only the values of the submitted response instead of doing the same for the whole sheet data range that potentially could return you an exceeded execution time limit error because your codes uese an open ended reference.
Regarding if adding the script to a spreadsheet or to a form, without more details any answer will be opinion based.
References
https://developers.google.com/apps-script/guides/triggers/events

Is it possible to get the destination sheet from app script

I am trying to identify the destination sheet for a google form. I can get the spreadsheet using:
function getDataSheet(){
var form = FormApp.getActiveForm();
var id = form.getDestinationId();
var ss = SpreadsheetApp.openById(id);
var sheet = ""; // how do I get the sheet that the data will go to?
}
The problem is how can I get the sheet that the form results will go to? I can guess that it is [0], but that is not a guarantee.
var form = FormApp.getActiveForm();
var formId = form.getId();
var sheets = ss.getSheets();
for(i=0; i<sheets.length; i++){
var sheetFormURL = sheets[i].getFormUrl();
if(sheetFormURL) {
if(sheetFormURL.indexOf(formId)!=-1) {
var sheet = sheets[i];
break;
}
}
}
if(typeof sheet !== 'undefined'){
//do what you need to do in the sheet
}
Currently, there is no "built-in" way to get the sheet tab of the Form destination.
If the user of the spreadsheet has not changed the default sheet name given, then you can loop through all the sheets, get the sheet name, and check for a name that includes the text: "Form Responses".
The first default name given is:
Form Responses 1
Then, if more destinations are added, the number at the end is increased.
If the user changes the name, then obviously, you can not use that strategy. If you can get the sheet tab name as soon as the new destination is created, then store the sheet tab ID in the documents properties, that would ensure that you have the information available. Having the sheet tab ID is better than having the sheet tab destination name, that way, if the destination sheet tab name gets changed, you can still find the correct sheet tab by looking the ID up from the document properties, then using the ID to get the sheet tab.
If the spreadsheet has multiple Form Responses X sheets, and you wanted to get the last destination added, you would need to get the number off the end, and find out what the highest number is.
There should be a way to get the destination sheet tab. I don't know if there is a feature request for that or not.
This is what I am doing as a workaround. It will try and find the datasheet, and should work for most forms. It is not very efficient, but should hopefully work to get most forms.
function getDestinationSheet(ss){
if(!ss){
var form = FormApp.getActiveForm();
var id = form.getDestinationId();
ss = SpreadsheetApp.openById(id);
}
var possibleDS = [];
var allSheetNames =[];
var dsName = {};
var locale = ss.getSpreadsheetLocale();
var text = "Timestamp";
if(locale != "en_US"){
text = LanguageApp.translate(text, "en_US", locale);
}
var sheets = ss.getSheets();
for(i in sheets){
var s = sheets[i];
var sName = s.getName();
allSheetNames.push(sName);
var a1 = s.getRange("A1").getValue();
if (a1 == text){ possibleDS.push(sName) }
}
var l = possibleDS.length;
switch (l){
case 0:
dsName.name = "Error";
dsName.error = "No matches found";
dsName.sheets = allSheetNames;
break;
case 1:
dsName.name = possibleDS[0];
dsName.error = "Sucess";
break;
default:
dsName.name = "Error";
dsName.error = "Unable to determine destination sheet using timestamp";
dsName.sheets = possibleDS;
break;
}
return dsName;
}