Say I've got a function name in cell A1, like SUM, and some data in B1 and C1. Is there any way to define a formula in one cell such that it calls the formula that is defined in A1 and have it work on B1 and C1 as data?
So something like:
=A1(B1:C1) should be equal to =SUM(B1:C1) since A1 contains the word SUM in it.
Essentially, something like preprocessor macros in C, or function pointers maybe.
You could do it using vba by creating a user defined function in a module:
Public Function applyFunction(functionName As Range, argument As Range) As Variant
applyFunction = Evaluate(functionName & "(" & argument.Address & ")")
End Function
If you put SUM in A1, and 1, 2, 3 in B1, B2, B3, =applyFunction(A1,B1:B3) will return 6. It is equivalent to calling =SUM(B1:B3).
EDIT
If you really don't want to use VBA, you can create a name (insert name in excel 2003 I think, Define Name in Excel 2010):
Define a new name (let's say eval1)
in the refers to area, enter =EVALUATE(A1&"(B1:B3)"), where A1 contains SUM and B1:B3 is the range with the numbers
in a blank cell, type =eval1 and it should return the result
But this approach is less flexible.
If you want to use a formula instead, you could possibly use the SUBTOTAL() function. However, it is a little limited.
Check out the image. It uses the reference to the function number for subtotal. You can expand this by creating a vlookup function if you want to use the name of the function, but you also have to provide a way to determine to use the regular function num or the 101-type values which ignores hidden values in the data range.
Check out this link for more info:
http://office.microsoft.com/en-us/excel-help/subtotal-function-HP010062463.aspx
Related
I am posting this question because I had a hell of a time trying to find the answer myself.
Basically I have a cell that references a cell that references another cell with some data in it. For example, A3=A2 and A2=A1 and cell A1 contains the text Hello. So cell A2 and A3 also contain the same text. See picture below:
But let's say I actually want cell A3 to show data relative to the cell position that A2 is pointing to (Remember A3=A2). I need to use the OFFSET function to do this and one would think that A3=OFFSET(A2, 0, 1) might work (click here to see how OFFSET works). But OFFSET does not work by itself. It would return the data from the cell to the right of cell A2 (shown below), instead of realizing that A2 points to A1 and then returning the data to the right of A1.
So how then do we get cell A3=B1, indirectly, by going through cell A2?
We need to use a combination of functions, one of which is INDIRECT. click here to see how INDIRECT works. So in order to use INDIRECT we need the text found in cell A2. The FORMULATEXT function (more info) will extract =A1 from cell A2 when used like so in cell A3:
A3=FORMULATEXT(A2), shown below:
Now we just need to strip off the = from the text so that we have an actual text reference that INDIRECT can use. You can do this using either the RIGHT or MID functions (right, mid) in combination with the LEN function (length). You need LEN if the number of rows in your sheet goes from single digit numbers into double digits, and so on. You also need to pass in the FORMULATEXT function again so it can compute the length of the text =A1. If you don't, it will compute the length of Hello. You also need to be aware that LEN()-1 is the correct length you need, since you are throwing away the = from the text.
For example: A3=RIGHT(FORMULATEXT(A2),LEN(FORMULATEXT(A2))-1) giving us:
Put it all together and you can OFFSET the cell that A2 references from A3 with INDIRECT like so:
A3=OFFSET(INDIRECT(RIGHT(FORMULATEXT(A2),LEN(FORMULATEXT(A2))-1)),0,1)
I've created a relatively complicated formula that sums up a range defined by a start and the end:
=SUMIFS(INDIRECT("Purchases!$B"&INDIRECT("B"&ROW())):INDIRECT("Purchases!$B"&INDIRECT("C"&ROW())), INDIRECT("Purchases!$I"&INDIRECT("B"&ROW())):INDIRECT("Purchases!$I"&INDIRECT("C"&ROW())), "income")
I've defined the formula so that if I simply copy/paste it across other cells, it works perfectly.
Now if I define a name for the first cell where this complicated formula occurs, how can I refer in the other cells to this formula by name, without copy/pasting the formula?
I want some sort of INDIRECT that would execute the formula referenced by its expression; something like "=CALL(sumifrange)", where sumifrange is the name of the cell with the complicated formula.
UPDATE: Here's a macro-enabled spreadsheet that attempts chthonicdaemon's solution. It doesn't work - there's a #REF! error.
You can't do it exactly the way you describe it in Excel anymore. You used to be able to use the EVALUATE function to do roughly what you describe, except you would need your formula as a string. EVALUATE is no longer available to be called as a cell, but you can call it when you define a named range.
Procedure:
Create a cell which contains your formula as a string (so don't start your formula with an equals sign, just SUMIFS(INDIRECT(...
Create a name (let's say func) which has =EVALUATE($A$1) in its "Refers to" box (use absolute references and select the cell where you placed your formula)
In any cell where you need the formula to be evaluated, type =func
Your formula can be made non-volatile by exchanging the INDIRECT function's for the INDEX function and using the principal of Inferred Position (see my explanation here) for the boundary row numbers pulled from columns B and C.
=SUMIFS(INDEX(Purchases!$B:$B,$B:$B ):INDEX(Purchases!$B:$B,$C:$C ), INDEX(Purchases!$I:$I,$B:$B ):INDEX(Purchases!$I:$I,$C:$C), "income")
Using that Inferred Position, you should be able to set a pair of INDEX functions that will return any range you want depending on the position of the cell referring to them.
Using Formulas ► Defined Names ► Name Manager, define a named range (e.g. siIncome) that uses the following for the Refers to:
=SUMIFS(INDEX(Purchases!$B:$B,$B:$B ):INDEX(Purchases!$B:$B,$C:$C ), INDEX(Purchases!$I:$I,$B:$B ):INDEX(Purchases!$I:$I,$C:$C), "income")
Now anywhere you want the result of the formula (relative to the cell's position) you can use =siIncome instead.
In the OP's sample workbook, the following formula would go into 'SO 29997947'!H2,
=SUMIFS(INDEX('SO 29997947'!$B:$B,$F:$F ):INDEX('SO 29997947'!$B:$B,$G:$G ), INDEX('SO 29997947'!$D:$D,$F:$F ):INDEX('SO 29997947'!$D:$D,$G:$G), "income")
The Refers to: for sumcateg would be the same formula.
This is used in 'SO 29997947'!I2
Here is the workbook with working revisions. call-formula-by-cell-name.xlsx
In a Google Sheet, I would like to enter a number in a cell and have certain functions in that sheet use that number.
So if cell "A1" has the value 2 assigned to it I want a function to use =C+(the value in cell A1), which is 2. So the function displays the value of C2. When changing the number in cell A1 to 5, my function should change to C5 as well . Any recommendations?
It seems to be the same as Excel. I tested it.
=INDIRECT("C" & VALUE(A1))
or
=INDIRECT("C"&A1) which is simpler (thanks Nirk)
Possible duplicate: Dynamic cell access
In excel, say I am trying to find average of 5 cells, I can put a formula
=Average(C1:C5)
I would like to modify the formula such that
= Average(C1:CXXXX)
where XXXX comes from another cell.
Is there a way to achieve this?
You probably want to have a look at the INDIRECT function if you need it as a fomula in a cell - you can use it like this, assuming that D1 contains the row that you call XXXX in your question:
=AVERAGE(INDIRECT("C1:C"&D1))
If this is in vba, then you can use:
= Average(Range(Range("C1"),Range("C") & XXXX))
where XXXX is the row number, assuming that Average is a function that you have defined somewhere.
Use the INDIRECT function. Indirect returns the reference by a string. INDIRECT("A1") returns the cell A1.
Your values are in the C column. Let's say that the XXXX is in cell D1. The formula becomes
=AVERAGE(C1:INDIRECT("C" & D1)).
I have two excel sheets. The first contains a formula for calculation with one input cell (A1), and one output cell (B1). The formula for B1 could be B1 = A1 * 3 (example).
The second sheet contains various values in column A: A1 = 4; A2 = 9; A3 = 5 ... In corresponding column B of this sheet I'd like to get the result of B1 (first sheet) = A1 (second sheet) * 3 for each A (second sheet) input value.
Basically I'd like to treat the first sheet as a function, where A1 is the argument and B1 the result that is passed back to the second sheet's B column.
Sheet 2
A1 4 B1 12 (result from sheet 1)
A2 9 B2 27 (result from sheet 1)
...
Is it possible without macros?
This is built into Excel. In version 2003, use the Data, Table menu.
You can find many examples on the net. Here is one.
You can create such tables with either 1 or 2 entries (parameters).
I don't think so .....
If in B1 Sheet1 you have
3*A1
If you try this in Sheet2 B1
`=SUBSTITUTE(Sheet1!$B$1,"A1",A1)`
it will give
3*4, and Sheet2 B2 will be
3*9etc
But I don't see how you could coerce this to a numberic calculation with formulae without possibly some heavy duty formula string parsing to separate numbers from operators (which is unlikley to flex as desired if you change the entry in B1 Sheet 1)
[Update 2: but fwiw I have done it with a named range]
I used this range name
RngTest
=EVALUATE(3*INDIRECT("rc[-1]",FALSE))
This is a global range name so it will work on any sheet, more powerful than my prior OFFSET effort. It multiplies the cell to the immediate left by 3
so entering =RngTest in B1:B3 (and then in this new example C1:C3 as well)
gives the output you want
I think you want to use this in your sheet two column.
Sheet1!B1 * Sheet2!A1
Entirely without VBA: expect lots of pain, I won't go there. But...
To substantially reduce the amount of pain, you could actually use this one tiny VBA user-defined function (not technically a "macro"), basically just a wrapper to make VBA's Evaluate function available in worksheet formulas:
Function eval(myFormula As String)
eval = Application.Evaluate(myFormula)
End Function
You could then use it like this in cell B1 on sheet 2:
=eval(SUBSTITUTE(Sheet1!$B$1,"A1","A"&ROW()))
Note that this requires Sheet 1 cell B1 to contain A1*3 and not =A1*3, i.e. no equal sign. Maybe with a bit more fiddling around, it can be made to work even with the = sign there...
EDIT: Actually, if you format Sheet 1 cell B1 as Text before typing in the formula, this will work even if your formula starts with a =.
Is it possible without macros?
Yes!
You can now use =LAMBDA for this.
Define your function using the name manager, then reference it in your second sheet's formula.
See syntax at Introducing the LAMBDA function.
For more information about how to use the LAMBDA function, see the support documentation.