Is there a way to evaluate a formula that is stored in a cell?
Asked Answered
M

13

48

In a Google Docs spreadsheet, I'm looking for something like =EVAL(A1) where A1 is set to "=1+2".

I found out that in MS Excel there is an EVALUATE() function (which seems a bit tricky to use properly). But I could not find anything similar in Google Docs.

I also searched through the function list, but could not find anything helpful...

Monandry answered 30/4, 2013 at 15:34 Comment(4)
setFormula() and possibly an onEdit triggerMidweek
what does your concatenate function look like?- you can achieve all this without the need for scripting at all - you can join pieces of the function together dynamicallyKosse
@Aurielle: Thanks for the reply. I was able to join the pieces dynamically. I need help scripting its execution. This is how my concatenate looks like: =CONCATENATE("=GoogleFinance(""",A10,""",""","price"",date(",E3,"),date(",E6,")") With some basic scripting I was able to paste the formula as a text string in one of the cells. The only piece missing is execution. Pressing "Enter" twice should do that trick, though I am open to trying other alternatives.Cameo
@RobinGertenbach: setFormula + onEdit will definitely work. I'm trying to figure out how to get the updated string into the editor every time I change currencies. Isn't setFormula static?Cameo
H
34

No, there's no equivalent to Excel's EVALUATE() in Google Sheets.

There's long history behind this one, see this old post for instance.

If you're just interested in simple math (as shown in your question), that can be done easily with a custom function.

function doMath( formula ) {
  // Strip leading "=" if there
  if (formula.charAt(0) === '=') formula = formula.substring(1);
  return eval(formula)
}

For example, with your A1, put =doMath(A1) in another cell, and it will be 3.

Hanley answered 30/4, 2013 at 21:16 Comment(2)
Sadly it's not just simple math. But maybe i can work around that with a custom function (like the one you posted) plus INDIRECT().Monandry
@keks - You may find that you can adapt this library to Apps Script. I'd expected to find many in javascript, but no luck.Hanley
N
11

If you want to evaluate simple math(like A1: "(1+2)*9/3"), you can use query:

=query(,"Select "&A1&" label "&A1&" ''",0)

Basic math sent to query's select is evaluated by query.

Nitty answered 6/3, 2020 at 21:46 Comment(5)
I had cells with eg '=+1+1+1' which together with Replace(A1; 1; 1; "") worked to get the total - thanks!Kennet
Great (and only good) anwer -Thanks!! Can this also be used to compute a maximum among such expressions using, e.g., "select max( xk ) label " & A1:A9 & " xk" ? or rather =max(A1:A9, "select (...)...") ? I did not succeed in getting to work any of these.. :-( [If you have a good documentation page that could also help...]Jobber
@Jobber Without a data structure, it's hard to tell what you're trying to do. But it looks like you might need BYROWNitty
Well, I mean, if I have an array of cells with expressions like 1+2 or 3/4 in them, could I use this kind of query(...) somehow in order to find the minimum (numerical value) of these cells ? I actually used your idea to implement matrix computations [Gaussian elimination, to be specific] with results given as fractions (e.g. "1/ 6" rather than 0.1666667). But in some cases I would like to find the largest element in a row/col, which has entries of that form.Jobber
@Jobber Yes. You can use REDUCE: =REDUCE(2^99,A1:B2,LAMBDA(a,c,MIN(a, query(,"Select "&c&" label "&c&" ''",0) ))) This calculates the minimum in A1:B2Nitty
B
10

I know this an old post. I'm just wondering, why nobody suggested:

myCell.getValue();

This will give you the result of the formula in myCell (3 in your example).

If you want to write the result to the cell (instead of the formula), you could use:

function fixFormula(myCell) {
    myCell.setValue(myCell.getValue());
}
Breakfront answered 7/1, 2016 at 15:56 Comment(1)
this works if you've already written the formula to cell (and flushed the sheet), but it doesn't let you find out what the value of a formula will be prior to thatGastineau
D
8

Short answer

As was mentioned previously, Google Sheets doesn't have a built-in EVALUATE function, but Google Sheets could be extended to add this function. Fortunately some SocialCalc files could be used to make this easier.

Script

On Google spreadsheet I'm sharing my progress. At this time I added the SocialCalc files that I think that are required and a couple of functions, and several test cases.

NOTES:

  1. Google Sheets specific functions like FILTER, UNIQUE, among others are not available in SocialCalc as well as other functions like SIGN.
  2. I think that the SocialCalc file should be replaced by those on https://github.com/marcelklehr/socialcalc as it looks to be updated recently. H/T to eddyparkinson (see https://mcmap.net/q/358968/-is-there-a-way-to-evaluate-a-formula-that-is-stored-in-a-cell)

Uses

The EVALUATE function on the linked file could be used as a custom function.

Example 1

A1: '=1+2 (please note the use of an apostrophe to make the formula be treated by Google Sheets as a string.

B1 formula:

=EVALUATE(A1)

B1 display value:

3

Example 2

To "EVALUATE" a formula like =VLOOKUP(2,A1:B3,2), at this time we need to use the "advanced" parameters. See the following example:

B1: '=VLOOKUP(2,A1:B3,2)

C1 formula:

=EVALUATE(B1,"data","A1:B3")

C1 display value:

B

Code.gs

/**
 *
 * Evaluates a string formula
 *
 * @param {"=1+1"}  formula   Formula string 
 * @param {"Tests"} sheetName Target sheet. 
 * @param {"A1"}    coord     Target cell. 
 * 
 * @customfunction
 *
 */
function EVALUATE(formula,sheetName,coord){
  // SocialCalc Sheet object
  var scSheet = new SocialCalc.Sheet();
  if(sheetName && coord){
    // Pass values from a Google sheet to a SocialCalc sheet
    GS_TO_SC(scSheet,coord,sheetName);
  }
  var parseinfo = SocialCalc.Formula.ParseFormulaIntoTokens(formula.substring(1));
  var value = SocialCalc.Formula.evaluate_parsed_formula(parseinfo,scSheet,1); // parse formula, allowing range return
  if(value.type != 'e'){
    return value.value;
  } else {
    return value.error;
  }
}
/**
 *
 * Pass the Google spreadsheet values of the specified range 
 * to a SocialCalc sheet
 *
 * See Cell Class on socialcalc-3 for details
 *
 */
function GS_TO_SC(scSheet,coord,sheetName){
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  if(sheetName){
    var sheet = ss.getSheetByName(sheetName);
    var range = sheet.getRange(coord);
    } else {
      var range = ss.getRange(coord);
  }
  var rows = range.getNumRows();
  var columns = range.getNumColumns();
  var cell,A1Notation,dtype,value,vtype;
  // Double loop to pass cells in range to SocialCalc sheet
  for(var row = 1; row <= rows; row++){
    for(var column = 1; column <= columns; column++){
      cell = range.getCell(row,column);
      A1Notation = cell.getA1Notation();
      value = cell.getValue();
      if(cell.isBlank()){
        dtype = 'b';
        vtype = 'b';
      } else {
        switch(typeof value){
          case 'string':
            dtype = 't';
            vtype = 't';
            break;
          case 'date':
          case 'number':
            dtype = 'v'
            vtype = 'n';
            break;
        }
      }
      scSheet.cells[A1Notation] = {
        datavalue: value,
        datatype: dtype,
        valuetype: vtype
      }
    }
  }
}

formula1.gs

https://github.com/DanBricklin/socialcalc/blob/master/formula1.js

socialcalcconstants.gs

https://github.com/DanBricklin/socialcalc/blob/master/socialcalcconstants.js

socialcalc-3.gs

https://github.com/DanBricklin/socialcalc/blob/master/socialcalc-3.js

Diphyllous answered 22/11, 2016 at 4:20 Comment(0)
F
2

Copy and paste the formulas:

Maybe you can copy and paste the formulas you need from "jQuery.sheet". Moved to:

https://github.com/Spreadsheets/WickedGrid

Looks to be all "open source"

Wont fix the issue

Also: The issue "Enable scripts to use standard spreadsheet functions" is marked as "Wont fix", see https://code.google.com/p/google-apps-script-issues/issues/detail?id=26

Ethercalc there is a google like opensource spreadsheet called Ethercalc

GUI Code: https://github.com/audreyt/ethercalc

Formulas: https://github.com/marcelklehr/socialcalc

Demo - on sandstorm: https://apps.sandstorm.io/app/a0n6hwm32zjsrzes8gnjg734dh6jwt7x83xdgytspe761pe2asw0

Foreordination answered 2/5, 2013 at 2:21 Comment(0)
K
2

In the case of evaluating a function like

"=GoogleFinance("usdeur","price",date(2013,12,1),date(2013,12,16))

Where you want to just get usdeur from a cell,

This can be done this without evaluate by directly referring to other cells like this:

=GoogleFinance(A10,"price",E3,E6)

enter image description here

Kosse answered 29/2, 2016 at 5:35 Comment(0)
P
1

Simple hack to evaluate formulas in google spreadsheet:

  1. select cells or columns with formulas
  2. go Edit -> Find and replace...
  3. check "Also search in formulas"
  4. replace "=" to "=="
  5. replace back "==" to "="
  6. in the same "Find and replace" window uncheck "Also search in formulas"

formulas will evaluate! :)

Precursor answered 11/1, 2019 at 12:54 Comment(0)
S
1

Thank you for user3626588's workaround here and it does indeed work. Based off your instructions it looks like it can be simplified even further.

  1. In Cell B1 Enter the following:="=sum(A1:A5)"
  2. In Cell C1 Set a data validation and select B1 with dropdown option.

Now select C1 and select the formula from the dropdown, it will sum any values between A1 through A5 automatically.

I have a sheet where I was creating a complicated formula for multiple values and this process worked!

Thank you once again as I was trying to avoid a script since I have data that is being pulled by another program on my worksheet. Script function do not always run automatically in those situations.

Sacerdotalism answered 15/9, 2019 at 23:14 Comment(0)
L
0

Awesome work around for google not having evaluate(). I have looked all around and besides script have found no other way to have a formula as a string on one sheet then use that formula on another. In fact everything I've seen says you can't. Would be helpfull if anyone reading this could repost around if they come to an appropriate question since I must have read a half dozen posts saying it wasn't possible before I just rolled up my sleaves and done done it. :) It still has a little clunkyness since you need two cells in the spreadsheet you want the formula to execute, but here goes.

Ok, some set up. We'll call the spreadsheet with the formula as string SpreadsheetA, call the tab the formula is on TabAA, the Spreadsheet you want to call and execute said formula SpreadsheetB. I'll use a multi-tab example, so say you want the sum of A1:A5 on SpreadsheetB tab: TabBA to be calculated on SpreadsheetB tab: TabBB cell A1. Also call the URL of spreadsheet A: URLA

So, in Spreadsheet A Tab: TabAA cell A1 put ="=sum(TabBB!A1:A5)", therefore the cell will display: =sum(A1:A5). Note: you don't need any $ in formula. Then in Spreadsheet B, Tab: TabBB, cell A2 put: =Query(Importrange("URLA","TabAA!A1"),"select Col1 where Col1 <> ''"). That cell will now display =sum(TabBA!A1:A5). Next to that, cell A1 of Spreadsheet B tab: TabBB, create a dropdown of the cell with the formula in B2 (right click cell A1, select data validation, for Criteria select: List from range, enter B2 in box to right). That cell should now be summing SpreadsheetB, TabBA, range A1:A5

Hope that was clear, I'm rather novice at this. Also important, obviously you would only do this in cases where you wanted to choose from multiple formulas on spreadsheetA, instead of TabAA!A1 say you had another formula in A2 also so your query would be =Query(Importrange("URLA","TabAA!A1:A2"). I understand in the simplistic case given you would simply put the formula where you needed the sum.

Edit: Something I noticed, was when I wanted to use a formula with double quotes the above scenario didn't work because when you wrapped the formula with double quotes in double quotes you get an error since you need single quotes inside double quotes. The example I was trying: if(counta(iferror(query(B15:C,"select C where C = 'Rapid Shot' and B = true")))>0,Core!$C$18+$C$10&" / ",)&Core!$C$18+$C$10&if(Core!$C$18>5," / "&Core!$C$18-5+$C$10,)&if(Core!$C$18>10," / "&Core!$C$18-10+$C$10,)&if(Core!$C$18>15," / "&Core!$C$18-15+$C$10,) In that case I put another formula into Spreadsheet A TabAA cell A2 that read ="="&A1. Then, ajusted the importrange referance in spreadsheet B to reference that cell instead.

BTW, this absolutly works so if you can't get it let me know where your having problems, I don't do a lot of colaboration so maybe I'm not saying something clear or using the right / best terminollagy but again I've seen many posts saying this was impossible and no one saying they had found another way. Thanx ~ K to the D zizzle.

Laughing answered 23/7, 2019 at 15:47 Comment(2)
For future reference, Test formatting before posting.Nitty
Also, simplified answers are better received.Nitty
C
0

How about just converting a column of expressions which are not preceded by a "+"?

92/120 67/85

etc.

Carolynncarolynne answered 16/10, 2019 at 9:50 Comment(0)
F
0

Here is the trick. Insert formula in the required cell, then get retrieve that cell value and replace the already inserted formula with this new value.

function calculateFormula(row, col){
    var spreadsheet = SpreadsheetApp.getActive();
    var sheet = spreadsheet.getSheetByName("Sheet Name");
    sheet.getRange(row,col).setValue("=sum(D6,C12:C14)");
    sheetData = sheet.getDataRange().getValues();
    var newValue = sheetData[row-1][col-1];
    sheet.getRange(row,col).setValue(newValue);
}
Finland answered 21/8, 2021 at 6:58 Comment(0)
I
0

It's a bit of a hack, but this works

  1. get the formula from the cell;
  2. set the formula back again; then
  3. get the value from the cell.
var cell = sheet.getRange("A1");
var formula = cell.getFormula();

cell.setFormula(formula);
var fileCell = cell.getValue();
Igenia answered 6/2, 2022 at 0:3 Comment(0)
M
0

Here is the working trick to evaluate the concatenated formula string. Use the formula cell as a data validation source for the target cell. Maybe it is not a fully automated solution. But evaluating refreshed formulas has been stripped down to just one click. You just need to reselect the value from the validation box when it is necessary. Many thanks to @Aurielle Perlmann and @user3626588 for the idea.

As an example, when you have set up dynamic multiple concatenations of such below formula in another sheet, this will work well with selecting validation option.

In my case, pressing enter twice is not userfriendly.

=({FILTER(IMPORTRANGE("https://docs.google.com/spreadsheets/d/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/edit"; "EXPENSES!A2:P"); INDEX(IMPORTRANGE("https://docs.google.com/spreadsheets/d/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/edit"; "EXPENSES!A2:P"); 0; 1) <> ""); FILTER(IMPORTRANGE("https://docs.google.com/spreadsheets/d/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/edit"; "EXPENSES!A2:P"); INDEX(IMPORTRANGE("https://docs.google.com/spreadsheets/d/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/edit"; "EXPENSES!A2:P"); 0; 1) <> ""); FILTER(IMPORTRANGE("https://docs.google.com/spreadsheets/d/cccccccccccccccccccccccccccccccccccccccccc/edit"; "EXPENSES!A2:P"); INDEX(IMPORTRANGE("https://docs.google.com/spreadsheets/d/cccccccccccccccccccccccccccccccccccccccccc/edit"; "EXPENSES!A2:P"); 0; 1) <> "")})

[enter image description here]1 [enter image description here]2

Melendez answered 15/10, 2022 at 22:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.