Google Apps Script - Mysterious comma on value from Google Form / Sheet - google-apps-script

This is my scenario:
I have a Google Form, and the values are added to a SpreadSheet. I have an Apps Script started with function onFormSubmit(event)
I get the values from the Form with var Variable = event.namedValues["Question 1"];
I use the value of this variables with some "if statements".
This Apps Script has been running OK, but i'm still making changes to add new functionalities (adding more questions on the Form, new functions on the Script), but suddenly in one of the variables starts to appear a comma into the values from this variable.
After checking all the Script, i decided to copy all the script to a new one. And when I used this new scenario (same content of files), the mysterious comma disappeared. I continued with new developments, but after some new changes (newer ones) the comma started to appear on one of the variables in their values. And after some new changes the comma moved from adding at the begging of the value, started to appear at the end.
I have checked the values on the spreadsheet, and they appear with no comma, the comma only appears when i use the values of that variable on the script.
I print the value with Logger.log(Variable) after i save the value from the event, and the comma is there, so i don't think that my code is adding this comma.
Any idea why is this happening? Is there a way to check on the value of a variable a character (in this case the comma) inside the Script? Something like Replace(Variable,",",""), with this i can check all the values got from the event before i start using them inside the Script. Commas aren't used on the values of the variables.
THESE ARE THE LINES AFFECTED (The script has more than 500 lines):
function onFormSubmit(event){
var Variable = event.namedValues["Question 1"];
Logger.log("Value after event" + Variable);
if (Variable == "AAAA"){
// do "something";
}
else {
// do "something different"
}
}
As the comma appears the if statement never gets a TRUE because the value starts to be "AAAA," so the do "something" never happens.

Answers:
Any idea why is this happening?
There might be some typos out there that needs to be cleaned. It would be better if you could also provide your code or at least how you wrote it.
Is there a way to check on the value of a variable a character (in this case the comma) inside the Script?
You can check the presence of a character/string in a variable by using includes.
var string = "I am Iron man,";
var hasComma = string.includes(","); // True
If you want to replace all the instances of comma, then use replace
// Replace all commas with blank
var string = string.replace(",", ""); // "I am Iron man"
EDIT:
Since e.namedValues["Question 1"] returns an object, you need to change the variable into string and then use the replace function
Code:
var Variable = e.namedValues["Question 1"];
Variable = String(Variable).replace(",", "");
Logger.log("Value after event: " + Variable);
if (Variable == "AAAA"){
// do "something";
}
else {
// do "something different";
}
References:
includes
replace

Related

Is there a way to have a checkbox toggle the text color of a set range?

I have a Google Sheets document and there is a dynamic list that gets created in a certain range (J19:L26) that has some personal data in it. Is there a way to make a checkbox or something quick I can click (even a button?) that can set the text to white or background to black to hide it to onlookers? I currently have the checkbox in cell M17
I have the following code that executes fine but then when I check the box in M17 nothing happens. Maybe I missed a step somewhere? I am new to Google sheets coding. I just wrote the function, tested it Runs, then closed it. Maybe I am just missing a step(s) in implementing the function to my sheet or my function Runs but doesn't do what I need it to?
function Privacy() {
var TheBoard = SpreadsheetApp.getActiveSpreadsheet();
var TheRange = TheBoard.getRange("Board!J19:L26");
if(TheBoard.getRange("Board!M17") == "TRUE")
{
TheBoard.getRange(TheRange).setFontColor('white');
}
}
There are a few things to correct. Here's a list:
When getting the status of the checkbox you're using TheBoard.getRange("Board!M17"). The getRange() method returns a reference to the range, not the value. After getting the range you can use getValue() on it to retrieve the values, so it should be TheBoard.getRange("Board!M17").getValue(), which will return true or false depending on the status of the checkbox.
You're comparing the value of the checkbox to == "TRUE". That makes it a string, and the checkbox value returns a boolean. In Javascript you're supposed to declare booleans as true or false, lowercase without quotes. That means the comparison should be == true instead.
The line TheBoard.getRange(TheRange).setFontColor('white'); returns an error. This is because getRange() expects a range in A1 notation or the coordinates to the row and column, but you're plugging TheRange into it, which is already a Range object. You already defined TheRange, so you don't need to "get" it again. The line should be just TheRange.setFontColor('white');
If you want to make the script run automatically when you click the checkbox you need to set it up as an onEdit() trigger. Then within the trigger check if the field that was edited was the checkbox before proceeding.
It's probably better to create a separate variable for the Sheet to avoid having to specify it in every range call.
May be a nitpick, but capitalizing variables makes the formatting color them like Classes, which may become confusing so I advise not doing that.
That said, here's the script with all the corrections:
function onEdit(e) {
if (e.range.getA1Notation() == "M17") {
var theBoard = SpreadsheetApp.getActiveSpreadsheet();
var theSheet = theBoard.getSheetByName("Board")
var theRange = theSheet.getRange("J19:L26");
if (theBoard.getRange("M17").getValue() == true) {
theRange.setFontColor('white');
} else {
theRange.setFontColor('black');
}
}
}
I recommend you familiarize yourself with the official documentation to better understand how each method works and apply them correctly.
Sources:
Sheet Class
Range Class
Triggers

Google Apps script "like" in if statement? Wildcards?

I have some scripting to format cell color. I would like to use LIKE to search inside the string (cell value). I am having a hard time finding something that works. I am very much new to Google Apps Script\Java.
Basically I want an if statement for a cell value, if it contains the word "extra" with anything before or after it. So it would match for 1extra and extra1, with any number of characters before or after.
Thanks for any help!
If you just want to check if a certain string is present, then you can use match
Script:
function myFunction() {
var sheet = SpreadsheetApp.getActiveSheet();
var A1_A6 = sheet.getRange("A1:A6").getValues();
// loop values of A1:A6
A1_A6.forEach(x => {
// since x is in [x] form, we get its first and only element
cell = x[0];
// if cell value has "extra" in it
// added i modifier since you want to match "123Extra123"
if(cell.match(/.*extra.*/i))
Logger.log(`"${cell}" matches.`);
});
}
Sample Data:
Output:
Note:
.* surrounding "extra" means that any number of any character (it will match any string, be it very long, or none at all)
modifier i after /.*extra.*/ means it will match regardless of the case (case insensitive - e.g. will match even if we want is "extra" and the one in the string is "Extra"). If you want to only match the exact string "extra", remove the i.
Reference:
match

Google App Script to find a value in particular column only

I found below script from one of the Stackoverflow posts.. it is almost match my requirement but I need few changes... like.. I don't want to replace, I only want it to find my value in a particular column and also want it to go to that cell when it finds the value. Can someone help me out?
also.. I want a shortcut key to run the macro... instead of the sheet's Ctrl+F.. I want it to display the search prompt when I give Ctrl+F... is it possible??
function findingReplacing()
{
var s = SpreadsheetApp.getUi().prompt("Search String", "Please enter desired search string", SpreadsheetApp.getUi().ButtonSet.OK).getResponseText();
var rng = SpreadsheetApp.getActiveSheet().getRange('D:D');
var rngA = rng.getValues();
for(var i=1;i<rngA.length;i++)
{
if(rngA[i][0]==s)
{
rngA
As mentioned by #Marios, the easiest way is to use TextFinder in your selected range.
Here is a sample code:
function findingAndSelect()
{
var s = SpreadsheetApp.getUi().prompt("Search String", "Please enter desired search string", SpreadsheetApp.getUi().ButtonSet.OK).getResponseText();
var rng = SpreadsheetApp.getActiveSheet().getActiveRange();
Logger.log(s);
// Creates a text finder for the range.
var textFinder = rng.createTextFinder(s);
textFinder.matchEntireCell(true);
textFinder.matchCase(false);
// Returns the first occurrence of the string.
var result = textFinder.findAll();
if (result.length == 0){
/* string not found */
SpreadsheetApp.getUi().alert("Search String", "String not found",SpreadsheetApp.getUi().ButtonSet.OK);
}else{
result.forEach((range) => { range.setBackground('#d5f5df');});
}
}
How to use?
Select the entire column where you want to do the search.
Enter the string to be search.
Click OK.
What it does?
Ask for a string to be search.
Get active range/ selected range where to look for the string (in your case the whole column should be selected).
Create a text finder and look for the input string.
Check if the string was found. Then change the background color of all ranges where the string was found
Additional Information:
You can also specify the search preference you want in your text finder. Please check TextFinder to see available methods.
If you want to match the string to the entire cell, You can use matchEntireCell() and set to true.
// Match the entire content of a cell.
textFinder.matchEntireCell(true);
If you want to match the string based on its case, you can use matchCase() and set to true.
// Match the search text's case exactly
textFinder.matchCase(true);
Output:
Importing functions as macros
In the Google Sheets UI, select Tools > Macros > Import.
Select a function form the list presented and then click Add function.
Select clear to close the dialog.
Select Tools > Macros > Manage macros.
Locate the function you just imported in the list. Assign a unique keyboard shortcut to the macro. You can also change the macro name here; the name defaults to the name of the function.
Click Update to save the macro configuration.
Note: You can link a macro to a keyboard shortcut in the form Ctrl+Alt+Shift+Number

Range.map no longer working in Google Apps Script for Sheets?

I have a custom function in Google Sheets that used Range.map to check if the parameter was a multi-cell range vs a single value (or single cell range). I wrote it over a year ago and hadn't been back to this function in a while, but I noticed today it does not work. the rangeVariable.map returns undefined, as does rangeVariable.length.
I can't find documentation on what to replace these with if they're no longer working, or even if they're confirmed to no longer work
function FormattedEmail(DisplayName, Email, Separator) {
var sep = Separator == null ? ',' : Separator;
if (DisplayName.map && Email.map) { //Both DisplayName and Email are ranges
if (DisplayName.length != Email.length) { //DisplayName and Email ranges must match
Updated to include information from TheMaster:
Ranges passed as parameters to custom functions should be passed as Arrays, so any array methods should work, including .map. However the variable does not seem to be an Array, but an object. https://developers.google.com/apps-script/guides/sheets/functions#arguments
A custom function doesn't really take a Range. It's best explained in the arguments documentation
If you call your function with a reference to a range of cells as an argument (like =DOUBLE(A1:B10)), the argument will be a two-dimensional array of the cells' values. For example, in the screenshot below, the arguments in =DOUBLE(A1:B2) are interpreted by Apps Script as double([[1,3],[2,4]]). Note that the sample code for DOUBLE from above would need to be modified to accept an array as input.
What's less obvious is that passing in a single cell reference will not be interpreted as an array, but as a single value. Try this:
// =isArray(B4) == false
// =isArray(B4:B5) == true
function isArray(arg) {
if (arg.map) {
return true;
}
return false;
}
So, in your custom function, if either DisplayName or Email are not arrays, you won't get past that first if statement. That is likely the reason why the function isn't working for you: one or more of your inputs is invalid. You should be able to resolve that in your function.
I assume that by calling DisplayName.map, you're actually trying to check if DisplayName is an array. This works because calling map on an object without that method (like a string), will return undefined. But it's probably better to be more explicit and use Array.isArray().
function FormattedEmail(DisplayName, Email, Separator) {
var sep = Separator == null ? ',' : Separator;
if (Array.isArray(DisplayName) && Array.isArray(Email)) {
if (DisplayName.length != Email.length) {

How to remove manual line break

I am getting the data from a form and writing in a google Document. It has fields like Name, Age, Address and so on. Address is of type paragraph text. My question is that while writing the data in a google Doc through a on-submit trigger script, how do I remove manual line breaks in the Address as input by the person filling the form. i.e. I want address to be a continuous string, without the breaks that the person filling the form may have put while typing his address.
ok here are more details.. the Address field in my form is called 'Address', i have a onformsubmit triggered script that reads all the data entered by the person in the form and puts in a google Doc App.
i read the values typed in the form as :
for(var field in e.namedValues) {
message += field + ' :: ' + e.namedValues[field].toString().replace("\n",", ") + "\n";
}
But in my google doc, the lines for the value of Address sre still broken where the person filling the form has broken the lines. i want to eliminate these line breaks and substitute it with commas so the address is continuous.
Change part of the line with the replace function to
e.namedValues[field].toString().replace(/(\r\n|\n|\r)/gm, ", ");
It works!
Remove the line breaks by taking the string that has the text from the paragraph, and passing it through string.Replace("\n", ""); If that doesn't work, then you will need to provide more details.
Also you can work with the range class:
function editRow(r){
var sheet = SpreadsheetApp.getActiveSheet();
var relevantRange = sheet.getRange(r, 21, 1, 1);
artefactRange.setValue(relevantRange.getValue().replace(/(\n)/g, ', '));
}