Google script .setFormula() only working with explicit string - google-sheets

In Google sheets, I get a "formula parse error" in the cell this code edits:
var A1one = 'C4';
var A1two = 'B4';
var A1three = 'B4';
var wholeFormula = '=if(today()<D$1,,' + A1one + '+if(isNumber(' + A1two + '),' + A1three + ',0)';
var wholeFormulaA1 = '=if(today()<D$1,,C4+if(isNumber(B4),B4,0))';
trackCell1.setFormula(wholeFormula);
But if I change the code as follows it works fine (only change is in last line):
var A1one = 'C4';
var A1two = 'B4';
var A1three = 'B4';
var wholeFormula = '=if(today()<D$1,,' + A1one + '+if(isNumber(' + A1two + '),' + A1three + ',0)';
var wholeFormulaA1 = '=if(today()<D$1,,C4+if(isNumber(B4),B4,0))';
trackCell1.setFormula(wholeFormulaA1);
wholeFormula and wholeFormulaA1 should be identical. Why does Google Sheets treat them differently?
I assume this is some kind of recalculation error. If I run the first code example above, and the cell displays #ERROR!, I can fix it by double clicking the cell and hitting ENTER on the keyboard. This forces the sheet to recalculate (I guess?), and the proper result of the formula is displayed in the cell.
But how do I get Google Sheets to update the cell automatically when using the first code example?

I guess you missed ) at the end, try:
var try = '=if(today()<D$1,,' + A1one + '+if(isNumber(' + A1two + '),' + A1three + ',0))';
To force script recalculate the formula, use SpreadsheetApp.flush();
I can fix it by double clicking the cell and hitting ENTER on the
keyboard. This forces the sheet to recalculate (I guess?), and the
proper result of the formula is displayed in the cell.
I think when you reenter the formula manually, it checks if ) is missed and repairs this automatically. This won't happen when you enter the formula by script.

Related

Auto Email Google Form Submissions based on Keywords in a String Cell Value

I'm receiving a gmail from the below code, but NOT the form values that I want to be included. I'm trying have a Google Form (Sheet) send an email to me (a teacher) when a student would type an important or alarming keyword in one of the form's fields (col J).
Picture a Google form with essentially the following fields:
A - Date/time stamp
B - email address collection
C - Name (short answer text)
D - what did you learn or work on yesterday? (long answer text)
E - How are you generally feeling today? (multiple choice)
F - Are you tired today? (multiple choice)
G - Are you stressed out today? (multiple choice)
H - What have you going on today? (bunch of checkboxes)
I - What could be "cool" or "good" about today? (long answer text)
J - (optional) Feel free to tell me anything more (long answer text)
If the student types any alert words, like "die" or "drugs" and so on in the last column (column J), I'd like to get a gmail with a summary of all the info on the row. So far, I've set up a trigger and am only getting a gmail with a subject and message, but the message DOES NOT contain the concatenated vars values.
ALSO, the gmail's subject DOES NOT contain the concatenated studname, which would be helpful. I'm curious how you'd fix this code.
THANK YOU!!
function checkComments(){
var commentsRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2").getRange("J2");
var sheet = SpreadsheetApp.getActive().getSheetByName("Sheet2");
var lastrow = sheet.getLastRow();
var comments = sheet.getRange('J' + lastrow).getValue();
if (comments === '.*drug.*'||'.*die.*'||'.*emotion.*'||'.*suicide.*'||) //many more root key words will be added in here in this |OR| format
{
// Send Alert Email.
var timestamp = sheet.getRange('A' + lastrow).getValue();
var studname = sheet.getRange('C' + lastrow).getValue();
var studemail = sheet.getRange('B' + lastrow).getValue();
var feelings= sheet.getRange('E' + lastrow).getValue();
var tired= sheet.getRange('F' + lastrow).getValue();
var stressed= sheet.getRange('G' + lastrow).getValue();
var studwork = sheet.getRange('H' + lastrow).getValue();
var cool = sheet.getRange('I' + lastrow).getValue();
var results = timestamp + ' \n ' + studname + ' \n ' + studemail + ' \n ' + feelings + ' \n ' + tired + ' \n ' + stressed + ' \n ' + studwork + ' \n ' + cool + ' \n ' + comments;
var emailAddress = 'my email address';
var message = 'Alert from the daily survey!\n' + results;
var subject = 'Daily Survey Alert from ' + studname;
MailApp.sendEmail(emailAddress, subject, message);
}
}```
To match a keyword, replace the
if (comments === '.*drug.*'||'.*die.*'||'.*emotion.*'||'.*suicide.*'||)
with
if(!!comments.match(/drug|die|emotion|suicide/))
I've fixed a bit your code and it seems work for me:
function checkComments() {
var sheet = SpreadsheetApp.getSheetByName('Sheet2');
var lastRow = sheet.getLastRow();
// it works faster when you grab all the row at once
var row = sheet.getRange('A'+lastRow+':J'+lastRow).getValues().flat();
var comments = row[9];
var words = ['drug','die','emotion','suicide'];
if (words.filter(w => comments.includes(w)).length == 0) return;
var emailAddress = 'your#mail.com';
var subject = row[2];
var message = row.join('\n');
MailApp.sendEmail(emailAddress, subject, message);
}
Probably it makes sense to use RegEx to search these words in comments. But I'm not sure if you're ready to dive so deep.

Repeat cell 'x' number of times in Google Sheets

I have tried using/altering other forum's answers and can't seem to get the code right. I am wanting to repeat entire lines 'x' number of times (x being in column U). This will be a document that I use over and over again with changing data in the lines, and just need a macro to dictate how many times the line repeats. I am a total coding novice-- any advise helps!
Use the following code that shall copy range from A:U and copy is below:
function repeatrow() {
var ss = SpreadsheetApp.getActive();
var repeattime = ss.getRange('U3').getValue();
ss.getRange('A4:U').clearContent();
var value = ss.getRange('A3:U3').getValues();
for (i = 0; i <= repeattime - 1; i++) {
ss.getRange("A" + (i + 4) + ":U" + (i + 4)).setValues(value);
};
};

Print a certain range of a Google Spreadsheet using a script

I would like to create a button to print just a certain range of a Google Spreadsheet. I am playing arroud with .getRangeByName class but it wont work. Maybe someone can help me with some ideas?
I am playing arround with some code I found here on stackoverflow.
I am just stuck by replacing the columns and rows by a certain range name or namedRange.
All in all the result of the script below works fine for me so far.
Thanks and Regards!
function printPdf() {
SpreadsheetApp.flush();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var gid = sheet.getSheetId();
var pdfOpts = '&size=A4&fzr=false&portrait=false&fitw=true&gridlines=false&printtitle=false&sheetnames=false&pagenum=UNDEFINED&attachment=false&gid='+gid;
var last_row = sheet.getLastRow(); var printRange = '&c1=0' + '&r1=0' + '&c2=34' + '&r2='+last_row // B2:APn var url = ss.getUrl().replace(/edit$/, '') + 'export?format=pdf' + pdfOpts + printRange;
var app = UiApp.createApplication().setWidth(200).setHeight(50);
app.setTitle('Verze pro tisk');
var link = app.createAnchor('Zobrazit PDF', url).setTarget('_new');
app.add(link);
ss.show(app);
}

Retain message formatting from Google Spreadsheet email script

We are using a Google Spreadsheet script to send us reformatted email.
Problem: We are wondering if there is a way to retain minimal formatting such as line breaks for the "strEnquirerMessage" cell for the following script.
I have tried including htmlBody somehow but no luck so far. Any help is greatly appreciated. Thank you.
User emails this message in contact form:
Line 1
Line 2
Line 3
We currently receive this in the email from this script: Line 1 Line 2 Line 3
Goal is to receive this:
Line 1
Line 2
Line 3
var strEnquirerName = values[row][1];
var strEnquirerEmail = values[row][2];
var strEnquirerAddress = values[row][3];
var strTopic = values[row][4];
var strEnquirerProducts = values[row][5];
var strEnquirerMessage = values[row][6];
var strMessageBody = "<b>NAME:</b> " + strEnquirerName +
"<br/><br/><b>EMAIL:</b> " + strEnquirerEmail +
"<br/><br/><b>ADDRESS:</b> " + strEnquirerAddress +
"<br/><br/><b>TOPIC:</b> " + strTopic +
"<br/><br/><b>PRODUCTS:</b> " + strEnquirerProducts +
"<br/><br/><b>MESSAGE:</b> " + strEnquirerMessage;
MailApp.sendEmail("your#emailaddress.com", strEnquirerEmail, " Contact form from " + strEnquirerName + " - " + strEnquirerEmail + " Re: " + strTopic, strMessageBody);
Thanks to this post, I have found the answer. Below is the updated line from the above code:
var strEnquirerMessage = values[row][6].replace(/\n/g, '<br>');
Beside the cell value is code to replace Google Spreadsheet's new line character with a line break. Hope this helps others.

Google Spreadsheets: email notifications for single cell

I am looking to set up something where notifications are only sent out if a specific single cell is changed. I have little coding experience and have a general idea of what needs to be in place. From what I have gathered I have created a script but it has notifications for all cell changes. Any suggestions on changing to only notify on single cell would be appreciated.
function emailNotification() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var cell = ss.getActiveCell().getA1Notation();
var cellvalue = ss.getActiveCell().getValue().toString();
var recipient = "mail#mail.com";
var subject = 'Update to '+sheet.getName();
var body = sheet.getName() + ' has been updated. Visit ' + ss.getUrl() + ' to view the changes on cell: «' + cell + '» New cell value: «' + cellvalue + '»';
MailApp.sendEmail(recipient, subject, body);
};
Try changing
var cell = ss.getActiveCell().getA1Notation();
var cellvalue = ss.getActiveCell().getValue().toString();
to
var cell = ss.getRange(row, column); //Put in the row and column of your cell
var cellvalue = cell.getValue().toString();
assuming that with 'changes' you mean manual edits, in order to 'limit' the script to a certain sheet and/or a certain cell you will have to check what the currently edited cell is. For example: if you only want the script to fire off when cell A1 of Sheet1 is edited, try something like:
function emailNotification(e) {
var sheet = e.source.getActiveSheet();
if (sheet.getName() !== 'Sheet1' || e.range.getA1Notation() !== 'A1') return;
var recipient = "mail#gmail.com";
var subject = 'Update to ' + sheet.getName();
var body = sheet.getName() + ' has been updated.\nVisit ' + e.source.getUrl() + ' to view the changes on cell A1.\nNew cell value: «' + e.value + '»';
MailApp.sendEmail(recipient, subject, body);
};
Change the sheet name and cell to suit and see if this works ?
var cell = ss.getRange("F2:F50"); //Put in the row and column of your cell
I'm working with this as well. The script is still sending notification if any cell is edited, not just column F

Resources