Use setFormula method with appendRow - google-apps-script

I have a Google Apps Script web app that takes values from the request and inserts them in a new row using the appendRow method. Next to inserting the values, I also want to insert formulas in a few columns. Is it possible to do this within appendRow()? Or is there another way to get the row number of the row that was just added, get the cell via getRange and then use the setFormula method?
Please note that I need to keep using the appendRow method and not a workaround via getLastRow due to that multiple request can be made at the same time.

You're going to have to use getLastRow() if you need the last row unless you want to keep track of it yourself.
You can do something like this:
function testtest() {
const ss=SpreadsheetApp.getActive();
const sh=ss.getActiveSheet();
const lr=sh.getLastRow()+1;
const s=`=SUM(A${lr}:C${lr})`;
sh.appendRow([1,1,1,s]);//use whatever values you wish
}
Note: you must be using V8

Values starting with '=' get interpreted as formulas:
In order to set formulas via appendRow, you just need to provide the formula itself, starting with '='. It will get interpreted as a formula. It's the same behaviour than setValue(value):
Sets the value of the range. The value can be numeric, string, boolean or date. If it begins with '=' it is interpreted as a formula.
Example:
sheet.appendRow(["yourRegularValue", "=yourFormula"]);

Related

Format a Google Sheets cell in numerical formatting 000 via Apps Script

I'm looking to set a column to format 000, which will display the zeros at begenning.
So, if a cell displays "3", I want that the script will set it to display "003".
This column is located in BDD tab, 13th column starting from the second row.
function FormattingGpeTrait() {
const sheet = SpreadsheetApp.getActiveSheet().getSheetByName("BDD").getRange(2,13)
sheet.setNumberFormat('000')
Modification points:
The method of "getSheetByName" is for Class Spreadsheet. In your showing script, you try to use it to Class Sheet. By this, an error occurs. This has already been mentioned in the comment. Ref
From 13th column starting from the second row., I thought that you might have wanted to set the number format of 000 to "M2:M". In your showing script, the number format is set to only a cell "M2".
If you want to set the number format to the cells "M2:M" of the sheet name of "BDD", how about the following modification?
Modified script:
function FormattingGpeTrait() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("BDD");
sheet.getRange("M2:M" + sheet.getLastRow()).setNumberFormat('000');
}
When you run this script, the number format of "000" is set to the cells "M2:M" of "BDD" sheet.
If you want to set the number format to the "M2:M", please modify getRange("M2:M" + sheet.getLastRow()) to getRange("M2:M").
References:
getActiveSpreadsheet()
getSheetByName(name)
The easiest way to get a range on a named sheet is to include the sheet name in the range reference, like this:
function formattingGpeTrait() {
SpreadsheetApp.getActive().getRange('BDD!M3:M').setNumberFormat('000');
}
I think that you can't use the standard number formats as they all will only evaluate your value to a real number value where '003' in reality is equal to '3' from a numeric sense.
You have two real options which is to either store the value in a Text column as "003" or prepend the value with an apostrophe "'003" which is basically the same as storing it as Text but the column can remain numeric.
You can create a custom number format for a cell/column to also do this but I am not certain how to accomplish this programatically. Basically, this is still going to end up like the Text variations I mention above, only you have a named format you can call. The data will still be stored as Text.

Using named ranged in google sheets as variables in custom formulas

Not sure if this is going to make sense but here I go.
What I want to do is to create a formula that isn't linked to a cell directly. In example: if I want to calculate carryweight for a tabletop game like D&D I would need the formula (strengthBonus x 5). For my current attempt I renamed the range (cell rather) strengthBonus to MOD_STR so when I put the formula =(multiply(MOD_STR,5) it works like a charm. Then I named that range "CARRYWEIGHT" and then use it elsewhere.
What I would like to be able to do is to make a new variable, similar to the way that "Define Named Range" does, but instead of relying on the variables being somewhere on the spreadsheet they would process from an internal formula. For example, if I type =carryweight into a cell it would run the equation =MULTIPLY(MOD_STR,5) in that cell and output the answer. I know nothing about code yet but have just been pointed in the direction of tutorials but I'm also asking for help here.
The code I have tried is
function CARRYWEIGHT(MOD_STR){
return MOD_STR*2}
and something else, I can't remember what but I got it to at least accept it in the spreadsheet. When I type it in I get an error stating that the outcome isn't a number.
I have no idea where to go from here.
Thank you in advanced for your help.
The difference between sheets formulas and Apps Script is that in Apps Script you need to retrieve the value of the range corresponding to the name of a named range
You cannot simply multiply the name of the range (which is a string!) with a number
Here is a sample of how to retrieve a range by name and make calculations wiht the value stored in it:
function CARRYWEIGHT(MOD_STR){
// retrieve all named ranges in the spreadsheet
var namedRanges = SpreadsheetApp.getActive().getNamedRanges();
//loop through all the results
for (var i = 0; i < namedRanges.length; i++){
var range = namedRanges[i];
//if the range with the name equal to the value of MOD_STR is found, get the cell content of this range
if(range.getName()==MOD_STR){
var value = range.getRange().getValue();
// perform the calculation with the cell content of the named range
return value*2;
}
}
}
From the cell, call the function as =CARRYWEIGHT("paste here the name of the range of interest"), do not forget the quotes (unless it is a cell reference)!
I hope this helped you to get started, for further understanding plese consult the following references.
References
Named Ranges
Loops
Conditional statements
Ranges
getValue()

How to evaluate a spreadsheet formula within a custom function?

In a spreadsheet I can enter =SIN(45)+123 in a cell, and it will be evaluated.
How can I evaluate spreadsheet functions within a custom function, something like an "eval"
function that would work like this :
function myFunc() {
return Sheet.eval("=SIN(45)+123")
}
is it possible ?
Note that I don't care about the SIN function in particular, what I want is to have access to the complete arsenal of spreadsheet functions (PMT, QUERY, NPER, etc..)
Spreadsheet functions from Apps-Script
Not possible - This has been asked many times. Suggest you check the google-apps-script issue list to see if anything has changed. But last I checked, there is no way to do it, and they have no plan to add it. https://code.google.com/p/google-apps-script-issues/issues/list
Ethercalc - java script spreadsheet formulas
If you need to, you can always copy the code from "ethercalc" as it has a java script versions of the spreadsheet formulas.
https://github.com/audreyt/ethercalc
I know this is an old question, but it might help someone.
just assign the formula to a range, then grab the value.
//asign a formula to the range
var range = sheet.getRange("A1").setFormula("=SUM(D1:D100)");
//get the result
var result = range.getValue();
//clean up
range.setFormula("");
I got this working. Using set value will do the trick. Thus something like this:
function MyFun1(){
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange('A1').setValue(Myfun2())
}
function MyFun2(){
return "=SIN(45)+123"
}
Hope this helps!
I think you need to divide this issue up into two different concerns.
Do you want to grab data that is already on the spreadsheet, perform a calculation, and then print a result, or do you want to use the sin() function on calculations in code unrelated to the data in the spreadsheet?
If you are trying to do the latter, you should be able to reference spreadsheet functions by using Math.sin() in your Google Apps Script. For more information on using the sin() function in JavaScript, check this post out: http://www.w3schools.com/jsref/jsref_sin.asp
If you are trying to do the former, then what you should do is use a readRows() function (more information available here: http://gassnippets.blogspot.com/2012/11/create-your-first-google-apps-script.html) to load your spreadsheet data into a variable (or variables) in memory, perform your calculations, and print the final result out to the spreadsheet using a similar function.
Let me know if this helps.
I came across this question in an attempt to find a way to evaluate part of a function like it is possible in Excel.
Here is my dirty workaround - instead of outputting the result in an msgbox, you could simply store the value or displayvalue of the activecell in a variable and use it to your liking.
Notice however, that the function will temporarily overwrite whatever you have in your currently selected cell and it will need to recalculate the sheet before the result is available. Hence it's not a viable solution if you need to evaluate multiple cell values.
function evalPart() {
var ui = SpreadsheetApp.getUi();
myPart = Browser.inputBox("Enter formula part:", ui.ButtonSet.OK_CANCEL);
if (myPart != "cancel") {
myActiveCell = SpreadsheetApp.getActiveSpreadsheet().getActiveCell();
myBackup = myActiveCell.getFormula();
myActiveCell.setFormula(myPart);
Browser.msgBox("Result of \\n \\n" + myPart + " \\n \\n " + myActiveCell.getDisplayValue());
myActiveCell.setFormula(myBackup);
}
}
I don't know if it's possible with high-level functions. However, it's possible with some common and easy-to-understand functions like (sum, subtract etc).
Following is the code I used to set values after the calculation is done in scripting itself.
function MyFun1() {
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange('A1').setValue(MyFun2());
}
function MyFun2() {
var one = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Dashboard");
var two = one.getRange('A2').getValue();
var three = one.getRange('A3').getValue(); return two*three;
}
Don't forget to add a trigger "onEdit" on Myfun1() to automatically update the return value.

Google Apps Script in Spreadsheet storing decimal values instead of Integer in Project Properties

This is my first post. I tried searching via Google and this site but really couldn't find any info about typecasting or converting numerical values within GAS specifically in this scenario. So here the problem:
I have a very basic script attached to a Google Spreadsheet. The script simply keeps track of the last row that was populated, increments the value by one, so that the next row can be populated. I'm storing the "last row used" as a Project Property. For some reason, the script keeps writing the value back into Project Properties as a decimal value, which throws off the whole script since it seems I can't use a decimal value to reference a cell location.
Here is the code snippet:
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var value = ss.getSheetByName("Sheet1").getRange("D13").getValue().toString();
var last = ScriptProperties.getProperty("last");
var therowx = parseInt(ScriptProperties.getProperty("therow"));
Browser.msgBox("The last row is: " + therowx);
if( value != last ) {
ScriptProperties.setProperty("last", value);
ScriptProperties.setProperty("therow", therowx + 1);
}
}
Assuming that I've pre-set the Property to 1 before running the script, once this method fires, it sets it to 2.0 instead of just 2. I've tried wrapping the method call with the Number() and parseInt() functions but they don't seem to make a difference.
I'm open to suggestions, as I'm sure I'm doing something wrong but just not quite sure what.
It would appear that you are using a value from the spreadsheet with var value = ss.getSheetByName("Sheet1").getRange("D13").getValue().toString();
This is were you are getting the decimal as Google spreadsheets will default to one decimal place. You will need to highlight the column or cell and change the format to Number>Rounded to get rid of it.
I am sure i am missing some components of your full script here, however have you tried the "getLastRow" function? There are some scripts in the tutorials that use it and it is a tried tested and true method of finding the last row of the sheet.

Is it possible to define a new function in Google-docs spreadsheet?

Is it possible to define a function in Google Spreadsheets that can be used in any cell?
It would be helpful if I could define and use functions that refer to other cells in the same way that I can use native functions, e.g. by entering =myfunction(C1, C2, C3)
Yes - there's a tutorial. Just use javascript functions by name in your spreadsheet. Define them using Tools > Script editor.
Watch out for name restrictions; I was confused by the behavior of functions that I created with names like "function x10() {}" not being found. Renaming to a longer name fixed it. There are probably documented rules for what isn't allowed, but I don't know where they are.
I am a "newbee". But is is my experience that you can only access a "cell"
via the "range" object. You must define the range as a single cell.
For example "A1:A1", will give you access the the cell at "A1".
A RANGE is an object associated to a "SHEET".
A SHEET is an object associated to a "SPREADSHEET".
Here is some sample code to access cell A1 in the current active sheet:
var cell_A1 = SpreadsheetApp.getActiveSheet().getRange("A1:A1");
From here you can pass the object like any other parameter.
myFunction(cell_A1);
The receiving function must "know" that it is dealing with a "range".
It can only access its values by calling "methods" associated to the
"range" object.
Be careful! A "range" can consist of more than one cell. Your called
function should test to see that it is working with a single cell.
If you pass a range of more than one cell, your function might not
act in the way you expect.
The two methods of a range object: "getNumRows()" and "getNumColumns()"
returns the numbers of Rows and Columns in a range object.
In general, if you use methods that are limited to changing or accessing
a single cell, and operate on a larger range set, the function will only be
performed on the upper-left cell member. But be careful. While you
might assume a method will only change a single cell, it may actually
affect all cells in the range. Read the documentation closely.
There is another method to obtain a range of a single cell. Its instruction
looks like this:
var cell_B2 = SpreadsheetApp.getActiveSheet().getRange(2, 2, 1, 1).
The first two parameters tell the "getRange" function the location of the
cell (in row, column format). The second two parameters define the number of
"rows" and "columns" to associated with the range. By setting them both to
"1", you access a single cell.
Hope this helps.