How Can I Paste A Google Sheets Range with everything except Values? - google-sheets

Trying to copy a range and paste only formulas, formatting, and data validation (no values) at the end of my sheet so I can enter new values in the freshly pasted range. All is working except I can't figure out how to exclude values when pasting.
Here is my code:
function addCue() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// copy the first cue range as template
var copyCueRange = ss.getRange("A10:AA11");
// Find the end of the sheet and set pasteRange to match copyRange
var l = ss.getDataRange().getValues().length;
var pasteCueRange = ss.getRange( "A"+(l+1)+":AA"+(l+2) );
// This pastes all data, How do I paste without values?
copyCueRange.copyTo(pasteCueRange);
};
I am very new to coding and appreciate the help. Thank you.

Data Validation: the Range class has a couple of methods for getting and setting data validation rules, setDataValidations() and getDataValidations().
Formulas: just as data validation, Range also has get/set methods for formulas, setFormulas() and getFormulas().
Formatting: looks like the Range.copyTo() method has some options specified here. Try using the formatOnly additional parameter.
function addCue() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// copy the first cue range as template
var copyCueRange = ss.getRange("A10:AA11");
// Find the end of the sheet and set pasteRange to match copyRange
var l = ss.getDataRange().getValues().length;
var pasteCueRange = ss.getRange( "A"+(l+1)+":AA"+(l+2) );
//Getting data validation and formulas
var dataValidationRules = copyCueRange.getDataValidations();
var formulas = copyCueRange.getFormulas()
//Setting formatting, data validations, and formulas
copyCueRange.copyTo(pasteCueRange, {formatOnly:true});
pasteCueRange.setDataValidations(dataValidationRules);
pasteCueRange.setFormulas(formulas);
}

Related

searchRecord isn't rendering correct info or takes several times to display

I'm running a Apps Script to create a data entry form. Sometimes my searchRecord function works if I run it several times. Sometimes it doesn't pull any info, but never gives me the warning screen, sometimes it pulls the info from the last search. I'm not sure where the problem is. I have copied the code below.
//Function to Search the record
function searchRecord(){
var myGoogleSheet=SpreadsheetApp.getActiveSpreadsheet(); //declare a variable and set with active Google Sheet
var shUserForm=myGoogleSheet.getSheetByName("User Form"); //declare a variable and set with the User Form reference
var datasheet=myGoogleSheet.getSheetByName("Existing Customers"); //declare variable and set the reference of database sheet
var str=shUserForm.getRange("B2").getValue(); //get data input for search button
var values=datasheet.getDataRange().getValues(); //getting the entire values from the used range and assigning it to values variable
var valuesFound=false; //variable to store boolean value
for (var i=0; i<values.length; i++)
{
var rowValue=values[i]; //declare a variable and storing the value
//checking the first value of the record is equal to search item
if(rowValue[6]==str){
shUserForm.getRange("B12").setValue(rowValue[0]);
shUserForm.getRange("B15").setValue(rowValue[1]);
shUserForm.getRange("B23").setValue(rowValue[2]);
shUserForm.getRange("B17").setValue(rowValue[3]);
shUserForm.getRange("E17").setValue(rowValue[4]);
shUserForm.getRange("B8").setValue(rowValue[6]);
shUserForm.getRange("E8").setValue(rowValue[7]);
shUserForm.getRange("B19").setValue(rowValue[8]);
shUserForm.getRange("E19").setValue(rowValue[9]);
shUserForm.getRange("B21").setValue(rowValue[10]);
shUserForm.getRange("E21").setValue(rowValue[11]);
shUserForm.getRange("E23").setValue(rowValue[12]);
shUserForm.getRange("E12").setValue(rowValue[13]);
shUserForm.getRange("B25").setValue(rowValue[14]);
shUserForm.getRange("E25").setValue(rowValue[15]);
shUserForm.getRange("B27").setValue(rowValue[16]);
shUserForm.getRange("E27").setValue(rowValue[17]);
shUserForm.getRange("B29").setValue(rowValue[18]);
shUserForm.getRange("E29").setValue(rowValue[19]);
shUserForm.getRange("B31").setValue(rowValue[20]);
shUserForm.getRange("E10").setValue(rowValue[21]);
shUserForm.getRange("B33").setValue(rowValue[22]);
shUserForm.getRange("B35").setValue(rowValue[23]);
shUserForm.getRange("B37").setValue(rowValue[24]);
shUserForm.getRange("E31").setValue(rowValue[25]);
shUserForm.getRange("E35").setValue(rowValue[26]);
shUserForm.getRange("B39").setValue(rowValue[27]);
shUserForm.getRange("E39").setValue(rowValue[27]);
shUserForm.getRange("B41").setValue(rowValue[29]);
shUserForm.getRange("E15").setValue(rowValue[30]);
shUserForm.getRange("B43").setValue(rowValue[31]);
shUserForm.getRange("E43").setValue(rowValue[32]);
shUserForm.getRange("B45").setValue(rowValue[33]);
shUserForm.getRange("E45").setValue(rowValue[34]);
shUserForm.getRange("B47").setValue(rowValue[35]);
shUserForm.getRange("B49").setValue(rowValue[36]);
shUserForm.getRange("B10").setValue(rowValue[37]);
shUserForm.getRange("E37").setValue(rowValue[5]);
valuesFound=true;
return;//come out from the loop
}
if(valuesFound=false){
//to create the instance of the user-interface environment to use the alert function
var ui=SpreadsheetApp.getui();
ui.alert("No Record Found");}
}
}
Solution
There are different points in your code that could be improved, I attach the updated function correcting the basics:
Indentation: This is easy to fix, just press ctrl + shft + i to correctly indent the code.
Break statement: Use the word break to break a loop.
Wrong comparison operator: The second if has only one = instead of two ==. Check Expressions and operators
Structural logic: Inside the for loop there are two ifs. Only the second one depends on the value of the valuesFound variable, which when modified breaks the loop, so it is not really doing anything.
Readability: It is difficult to understand what the code is doing and so many setValue boxes with no apparent connection is confusing.
In addition, it is difficult to offer help if the behavior of the function is variable and the reason is not known. Apparently, it should always give the same result.
Updated code
function searchRecord() {
var ss = SpreadsheetApp.getActiveSpreadsheet(); //declare a variable and set with active Google Sheet
var shUserForm = ss.getSheetByName("User Form"); //declare a variable and set with the User Form reference
var datasheet = ss.getSheetByName("Existing Customers"); //declare variable and set the reference of database sheet
var str = shUserForm.getRange("B2").getValue(); //get data input for search button
var values = datasheet.getDataRange().getValues(); //getting the entire values from the used range and assigning it to values variable
var valuesFound = false; //variable to store boolean value
var ui = SpreadsheetApp.getui();
for (var i = 0; i < values.length; i++) {
var rowValue = values[i]; //declare a variable and storing the value
//checking the first value of the record is equal to search item
if (rowValue[6] == str) {
shUserForm.getRange("B12").setValue(rowValue[0]);
shUserForm.getRange("B15").setValue(rowValue[1]);
shUserForm.getRange("B23").setValue(rowValue[2]);
shUserForm.getRange("B17").setValue(rowValue[3]);
shUserForm.getRange("E17").setValue(rowValue[4]);
shUserForm.getRange("B8").setValue(rowValue[6]);
shUserForm.getRange("E8").setValue(rowValue[7]);
shUserForm.getRange("B19").setValue(rowValue[8]);
shUserForm.getRange("E19").setValue(rowValue[9]);
shUserForm.getRange("B21").setValue(rowValue[10]);
shUserForm.getRange("E21").setValue(rowValue[11]);
shUserForm.getRange("E23").setValue(rowValue[12]);
shUserForm.getRange("E12").setValue(rowValue[13]);
shUserForm.getRange("B25").setValue(rowValue[14]);
shUserForm.getRange("E25").setValue(rowValue[15]);
shUserForm.getRange("B27").setValue(rowValue[16]);
shUserForm.getRange("E27").setValue(rowValue[17]);
shUserForm.getRange("B29").setValue(rowValue[18]);
shUserForm.getRange("E29").setValue(rowValue[19]);
shUserForm.getRange("B31").setValue(rowValue[20]);
shUserForm.getRange("E10").setValue(rowValue[21]);
shUserForm.getRange("B33").setValue(rowValue[22]);
shUserForm.getRange("B35").setValue(rowValue[23]);
shUserForm.getRange("B37").setValue(rowValue[24]);
shUserForm.getRange("E31").setValue(rowValue[25]);
shUserForm.getRange("E35").setValue(rowValue[26]);
shUserForm.getRange("B39").setValue(rowValue[27]);
shUserForm.getRange("E39").setValue(rowValue[27]);
shUserForm.getRange("B41").setValue(rowValue[29]);
shUserForm.getRange("E15").setValue(rowValue[30]);
shUserForm.getRange("B43").setValue(rowValue[31]);
shUserForm.getRange("E43").setValue(rowValue[32]);
shUserForm.getRange("B45").setValue(rowValue[33]);
shUserForm.getRange("E45").setValue(rowValue[34]);
shUserForm.getRange("B47").setValue(rowValue[35]);
shUserForm.getRange("B49").setValue(rowValue[36]);
shUserForm.getRange("B10").setValue(rowValue[37]);
shUserForm.getRange("E37").setValue(rowValue[5]);
valuesFound = true;
break
}
if (valuesFound == false) {
//to create the instance of the user-interface environment to use the alert function
ui.alert("No Record Found");
}
}
}

Extract value from string Node red

how do I extract data within some brackets?
So msg.payload = 123(ABCD)4
What function will extract ABCD from this string?
You should try fiddle with the javaScript node and play with this, there are many ways to do that as well.
var str = "123(ABCD)4"
var first = str.split('(')
var second = first[1].split(')')
console.log(second[0])

Run Google Sheets script on insert

So, i have a google form, and based on the data of the submitted form, a response is generated, i want that response to be emailed to the person who completed the form
Is there a way to send an email when a new row is inserted in the answer sheets?
The way I've accomplished this in the past is to write a simple google docs script to listen to the onChange trigger of a spreadsheet and send an email with the contents of the row of said sheet. Here are the specific steps:
With your google sheet open go to Tools > Script editor...
This will bring you to the script associated to this file where you can write a simple function to send the contents of the last rows of your sheet. Something like the following would work:
function sendEmailOfLastEditedRow() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var lastRow = sheet.getLastRow();
var numRows = 1; // Number of rows to process
var cols = sheet.getLastColumn();
// Fetch the range of cells A2:D5
var dataRange = sheet.getRange(lastRow, 1, numRows, cols)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
// Fetch your row as an array
var lastRowData = data[0];
// Format data by separating values into comma separated list for email
var emailContent = lastRowData.join(",");
// Send an email (change this to your email)
MailApp.sendEmail('alex#simoes.com', 'Email subject', emailContent);
// Log contents for debugging
Logger.log(emailContent);
}
Add a trigger in the script editor to run this function when the google sheet is edited: Edit > Current project's triggers

Associate specific string to a number in google sheets

I am using a google forms to collect responses which I will then use to score people. Unfortunately some of those responses only make sense in a non numeric form, here is an example:
Q: What is your most common mode of transportation?
Car
Carpool
Public transportation
Bike
Walk
I want to be able to have google sheets automatically convert those string responses into a number, as in Car will be 20, carpool 15 and so on so that I can "grade" them and give them a score. Can this be done through google forms? Or maybe some sort of dictionary function?
Thank you!
Another method, requiring no coding, would be to make a worksheet with the encoding of the options and then use VLOOKUP to translate them.
Yep, this can be done through Google Forms. Have a look at https://developers.google.com/apps-script/reference/forms/duration-item#setPoints(Integer)
Using their code, you could go something like
var formResponses = FormApp.getActiveForm().getResponses();
// Go through each form response
for (var i = 0; i < formResponses.length; i++) {
var response = formResponses[i];
var items = FormApp.getActiveForm().getItems();
// Assume it's the first item
var item = items[0];
var itemResponse = response.getGradableResponseForItem(item);
if (itemResponse != null && itemResponse.getResponse() == 'Car') {
var points = item.asMultipleChoiceItem().getPoints();
itemResponse.setScore(points * 20);
// This saves the grade, but does not submit to Forms yet.
response.withItemGrade(itemResponse);
}
}
// Grades are actually submitted to Forms here.
FormApp.getActiveForm().submitGrades(formResponses);

Count number of values in a sum formula?

I have a sum cell and I want another cell to count the number of values that were added together. I am not sure if it is possible to read the formula text itself from within sheets or not.
=1+4+2
In another cell I would expect it to be 3.
Help appreciated
I don't think google can do this with a spreadsheet formula. It can be done with a user defined function. Assumes formulas are in column A. Try:
function countFormula() {
var ss=SpreadsheetApp.getActiveSpreadsheet()
var s=ss.getActiveSheet()
var cell=s.getActiveCell().getRow()
var f=s.getRange(cell,1).getFormula()
var args = f.replace("=","");
var x=args.split("+")
var count=x.length
return count
}
Or to remove any math symbol (+,-,/,*, etc.):
function countFormulaNumeric() {
var ss=SpreadsheetApp.getActiveSpreadsheet()
var s=ss.getActiveSheet()
var cell=s.getActiveCell().getRow()
var f=s.getRange(cell,1).getFormula()
var args = f.replace("=","");
var myString = f.replace(/\D/g,',');
var x=myString.split(",")
var count=x.length-1
return count
}
Just use the =count function on your range of cells!
=count(A1:A3)`
for example will yield a value of three.
If you have Excel 2013 or later, you can use FormulaText to examine the formula in a cell and so the answer would be
=LEN(FormulaText(A1))-LEN(SUBSTITUTE(FormulaText(A1),"+",""))+1
In google sheets there is no FormulaText, but this reference shows how to write one. The code is
function FORMULATEXT(A1Notation) {
  return SpreadsheetApp.getActive().getRange(A1Notation).getFormula();
}
then you can use it in a similar way to Excel (except with quotes around the cell references) like this
=len(FormulaText("A1"))-len(substitute(FormulaText("A1"),"+",""))+1
for:
=COLUMNS(SPLIT(FORMULATEXT(A1), "=+-*/^()"))
arrayformula:
=INDEX(IFNA(BYROW(IF(SPLIT(BYROW(A1:A5,
LAMBDA(x, FORMULATEXT(x))), "=+-*/^()"), 0, ),
LAMBDA(x, LEN(JOIN(, x))))))

Resources