I am using Excel to calculate a string value where Evaluate() works fine but I am not allowed to use evaluate() in the Name Manager and I am not allowed to use it in VB A because the file gets converted to .xls. Here is the issue.
I have 100 s of a long formula example:
($F$10+0)+($F$11+0.125)+($F$10+0.0625)
which i need to evaluate the values between the brackets separately.
I am able to separate the formula to
A1 is ($F$10+0)
A2 is ($F$11+0.125)
A3 is ($F$10+0.0625)
I would like to put an "=" sign in front of this string and calculate the values of A1, A2, and A3.
However I am not allowed to use function EVALUATE() in the File Manager, it does not work in the cells and I am not allowed to use VB A to code the formula.
is there any replacement for evaluate that I can use?
thanks
Welcome to the dark side of Excel.
If you cannot use:
1) VBA
2) Macros
3) Evaluate()
4) File Manager / Define Name
Then there are no simple formulas that can help you (plus you can't make your own). Microsoft has purposely not addressed this issue for many many years.
So you are left to your own devices to create your own parser in Excel cells.
This can be very difficult if you have varying types of formulas that can change signs, or amount of addressed cells, or any number of other craziness that formulas can take.
However... if you have a minimum number of deviations for how the formula is expressed... you can write something that will do the trick.
This comes with a caveat... the formula must be provided with the same parameters each time. And what you gave as examples, has the structure defined exactly the same for each formula.
So therefore, using your examples, you can write this code in column A2:
=INDIRECT(MID(A1,SEARCH("$",A1),SEARCH("+",A1)-SEARCH("$",A1)),TRUE)+MID(A1,SEARCH("+",A1)+1,LEN(A1)-SEARCH("+",A1)-1)
Then you can copy that code over to B2 and C2.
This will give you the correct math as if it was a formula.
The structural parameters that are needed for this to work are:
1) The cell address must always start with a dollar sign $
2) The cell address must be immediately followed by a plus sign +
3) Only a single addition is done as the formula
4) The operand after the plus sign must be numeric
5) The formula must end with a Parenthesis )
6) It can't hurt to begin with a Parenthesis either (
And since all of your formulas adhere to this structure... the formula I provided will work.
If you need to change item 3 to also allow for 'subtraction', then you are going to need to add if statements to the formula and it's going to become complicated very quickly. Impossible? No. But a huge mess? Yes.
Anyway, this should work with all of your restrictions that you have. That is... if your formulas don't deviate from the structure that has been provided. If you have different formula structures, you'd need to let us know about them... or better yet, write your own code.
Hope this helped. :)
Related
I am a programmer, so please bear with me. I understand that Excel isn't necessarily what I am used to in other domains, but I'm cracking my head open on how to accomplish something that seems somewhat simple.
I have a column of numbers that are themselves the basis of a formula. I want to filter those cells based on some criteria and pass them to another function to perform a calculation.
I understand that this can be done with "filters" in the excel sense. This would mean I would have to click multiple times for each calculation, filter the results, copy the value and paste it where I need it to be. If the data ever changes, I will have to do it all again.
What I am looking for is the equivalent of filtering in a programming language, here's an example:
let range = [1,2,3,4,0,-1,-2,-3,-4];
let subrange = range.filter(function (cell) { return cell > 0; });
subtotal(1,subrange);
So what my excel is like.
I have a column G, that has 12,000+ results in it, each one of these columns is like this:
=(En-Bn)/Bn
These are copied down, n means the row number from 5-12,000+
Now I would like to create a cell, M2 such that it contains:
=SUBTOTAL(1,[ Gn in G5:G12000 where Gn > 0 ])
The goal is that I do not want to have to point and click, because actually, there are many more cells I need to create (about 20) with similar kinds of "filter" predicates.
It would be nice, as much as possible, if I also don't have to specify the n...n-1 range of the column, as ideally that can change. Could be 10, could be 20,000, shouldn't matter.
The best formula or solution would be like:
SUBTOTAL(1, [ Gn in G0:GLENGTH where Gn > SOMECELL ])
Any pointers, or suggestions where to read, or a solution would be awesome. I've been searching on google, and it seems that I lack the right understanding to find the answer in the material presented.
Also, please excuse me for using programmer speak, I know that Excel formulas are not necessarily a 1:1, I'm just looking for a way to save time. Answers in VBA or using Macros are welcome, the main thing is to find a way to do it...
Best,
Jason
Update
I should specify that it needs to be a bit backwards compatible, so I can't use the FILTER function that is only available in >= 365
I'm not at all sure that your attempts at saving time by talking in programming language instead of English really saves either time or space. My best effort determines that you got us all confused. Please tell me why the simple formula below doesn't work.
=AVERAGEIF(G2:G15000,">"&A1,G2:G15000)
This formula requires A1 to hold a number and the formula supplies the > sign. A variation would have A1 contain both, number and comparison, like >1.2`
=AVERAGEIF(G2:G15000,A1,G2:G15000)
The above formulas start the range at G2. Change to G5 if that is what you need. G15000 is a random number intended to be larger than anything you will ever need. The function ignores blanks. However, if you are worried about having a sheet with 16000 rows just on the day you forgot where to adjust the formula I would recommend the use of a named range which you could format to be dynamic.
Named ranges are neater to handle than range addresses and names can be given descriptively, such as HourlyReadings. The above formula would then look like this:-
=AVERAGEIF(HourlyReadings, ">"&A1,HourlyReadings)
Theoretically, the formula by which HourlyReadings is defined could also be written into the worksheet formula but it would become unwieldy. As shown above, you would have to look into the Name Manager to know if the range is dynamic or not but, of course, once defined you can use the same name in many functions and formulas which saves a lot of maintenance time.
This is for Excel 365, using worksheet formulas. With data in column G starting in G5, in another cell enter:
=SUM(FILTER(G:G,G:G>0))
How about an array?
=SUM(IF(G:G>0,G:G,""))
put cursor in 'function bar' with formula. Then press CTRL+SHIFT+ENTER (in that order while holding them all down. {} will appear around formula.
Let me know if further assistance is needed.
Matt
I'm having trouble trying to figure out a way to have two columns, one to show the entire formula that can be editable and the second to actually perform the formula.
Ideally, I would like my sheet to be set up like this:
Formula | Value
=5+2 | 7
=3-2 | 1
I would like to be able to change the Formula column and have it automatically update the Value column.
I've tried using the GetFormula() function but I don't think that's what I want to do as I would end up in a circular reference based on what I want to do. The closest I've got is using a Right() function and Text in the formula column or a space and removing the space. However, I end up with the text and not the solved formula instead.
Using =RIGHT(A2, LEN(A2)-1)
Formula | Value
=5+2 | =5+2
I have also tried using =RIGHT(A2,LEN(A2)-1) but without the "=" and can't figure out how to convert the "5+2" into text that I can use to solve. I'm hoping to do this with a formula and without a macro/VBA.
Here is how to do it.
1
Open the Name Manager. Control-F3 from the worksheet, and then click the New button.
2
For the Name field in the dialog, enter EVALA. I just picked this name; it stands for "Evaluate A". But you can pick whatever name you like.
3
For the Refers to field, enter this
=EVALUATE($A1)
4
Click OK and then Close.
5
In B1 enter this formula:
=EVALA
That's it.
You can now use this formula on any row in the worksheet and it will evaluate whatever is in the column A cell of the row where you enter the formula.
You can make a user defined function easily enough with VBA, but if you don't regularly use VBA then an alternative method is to create a Name object. Name objects can access certain functions not typically available in a cell's formula. One of these functions is "Evaluate" which will evaluate a string as a mathematical expression. Here's a demonstration how to do this.
NOTE: Pay special attention to the use of $. Chances are you don't want any $ in your name definition since that will prevent it from behaving in a relative manner. Also, Sheet1! means that this will not work on another sheet.
Update I just want to give credit for this method to the following sources. This is pretty neat stuff, so for anyone interested give it a read. The last link in particular gives a neat example of creating a chart with no data points.
MSDN Evaluating Defined Names
The power of evaluate (ozgrid)
XL4 Macro Functions in Names - JKP
Evaluate and Indirect
More unique functionality of Defined Names
This is probably the best solution for the OP, since it asks to avoid using VBA; however, this method is somewhat limited. It requires manual set-up on every sheet to be used. Much preferable I think is to create a very simple UDF like this...
Function Eval(Expr As String)
Eval = Application.Evaluate(Expr)
End Function
This can be added to any accessible add-in, making it available to any instance of Excel. A little more set-up, but less maintenance.
Just put a single ' before the formula in your A column:
'=5+2 will show in your cell as "=5+2". Then in the B column, just do the formula as normal, =5+2.
So I could really use a modular operator in one of my Excel cells, just to try out different things and mess around a bit.
So in the one cell there'd be for example
=A1(operation in B1)A2
Thus when I'd write a "plus" ('+') sign in B1 I get an addition, but if I write a "star" ('*') I get a multiplication.
Same could go for
=(name of function in B1)(A1; A2)
And in B1 I could write either MIN or MAX.
Of course I could do it with IFs, but my question is about building a cell formula with text from another cell and then interpreting it (thus not limiting myself to a few IF cases). Just like INDIRECT does, but not just with cell references. Any idea ? Thanks in advance.
I think you need to be consistent in your approach: either a function name, or an operator, but not both (+ and * can be replaced with SUM and PRODUCT respectively, so this is not an issue).
If you go to Name Manager and define a new name, Operation say, as:
=EVALUATE($B$1&"("&$A$1&","&$A$2)
(Replace the "," with ";" if your version uses the semi-colon as argument separator in formulas and not the comma.)
Exit Name Manager.
Then, in any cell:
=Operation
Test with various strings in B1, e.g. SUM, PRODUCT, MAX, MIN. Of course, this will only work with functions whose syntax is of the form:
=FUNCTION(Arg1,Arg2)
And it also requires that you save the workbook as macro-enabled.
Regards
I would like to create a succinct Excel formula that SUMS a column based on a set of AND conditions, plus a set of OR conditions.
My Excel table contains the following data and I used defined names for the columns.
Quote_Value (Worksheet!$A:$A) holds an accounting value.
Days_To_Close (Worksheet!$B:$B) contains a formula that results in a number.
Salesman (Worksheet!$C:$C) contains text and is a name.
Quote_Month (Worksheet!$D:$D) contains a formula (=TEXT(Worksheet!$E:$E,"mmm-yy"))to convert a date/time number from another column into a text based month reference.
I want to SUM Quote_Value if Salesman equals JBloggs and Days_To_Close is equal to or less than 90 and Quote_Month is equal to one of the following (Oct-13, Nov-13, or Dec-13).
At the moment, I've got this to work but it includes a lot of repetition, which I don't think I need.
=SUM(SUMIFS(Quote_Value,Salesman,"=JBloggs",Days_To_Close,"<=90",Quote_Month,"=Oct-13")+SUMIFS(Quote_Value,Salesman,"=JBloggs",Days_To_Close,"<=90",Quote_Month,"=Nov-13")+SUMIFS(Quote_Value,Salesman,"=JBloggs",Days_To_Close,"<=90",Quote_Month,"=Dec-13"))
What I'd like to do is something more like the following but I can't work out the correct syntax:
=SUMIFS(Quote_Value,Salesman,"=JBloggs",Days_To_Close,"<=90",Quote_Month,OR(Quote_Month="Oct-13",Quote_Month="Nov-13",Quote_Month="Dec-13"))
That formula doesn't error, it just returns a 0 value. Yet if I manually examine the data, that's not correct. I even tried using TRIM(Quote_Month) to make sure that spaces hadn't crept into the data but the fact that my extended SUM formula works indicates that the data is OK and that it's a syntax issue. Can anybody steer me in the right direction?
You can use SUMIFS like this
=SUM(SUMIFS(Quote_Value,Salesman,"JBloggs",Days_To_Close,"<=90",Quote_Month,{"Oct-13","Nov-13","Dec-13"}))
The SUMIFS function will return an "array" of 3 values (one total each for "Oct-13", "Nov-13" and "Dec-13"), so you need SUM to sum that array and give you the final result.
Be careful with this syntax, you can only have at most two criteria within the formula with "OR" conditions...and if there are two then in one you must separate the criteria with commas, in the other with semi-colons.
If you need more you might use SUMPRODUCT with MATCH, e.g. in your case
=SUMPRODUCT(Quote_Value,(Salesman="JBloggs")*(Days_To_Close<=90)*ISNUMBER(MATCH(Quote_Month,{"Oct-13","Nov-13","Dec-13"},0)))
In that version you can add any number of "OR" criteria using ISNUMBER/MATCH
You can use DSUM, which will be more flexible. Like if you want to change the name of Salesman or the Quote Month, you need not change the formula, but only some criteria cells. Please see the link below for details...Even the criteria can be formula to copied from other sheets
http://office.microsoft.com/en-us/excel-help/dsum-function-HP010342460.aspx?CTT=1
You might consider referencing the actual date/time in the source column for Quote_Month, then you could transform your OR into a couple of ANDs, something like (assuing the date's in something I've chosen to call Quote_Date)
=SUMIFS(Quote_Value,"<=90",Quote_Date,">="&DATE(2013,11,1),Quote_Date,"<="&DATE(2013,12,31),Salesman,"=JBloggs",Days_To_Close)
(I moved the interesting conditions to the front).
This approach works here because that "OR" condition is actually specifying a date range - it might not work in other cases.
Quote_Month (Worksheet!$D:$D) contains a formula (=TEXT(Worksheet!$E:$E,"mmm-yy"))to convert a date/time number from another column into a text based month reference.
You can use OR by adding + in Sumproduct. See this
=SUMPRODUCT((Quote_Value)*(Salesman="JBloggs")*(Days_To_Close<=90)*((Quote_Month="Cond1")+(Quote_Month="Cond2")+(Quote_Month="Cond3")))
ScreenShot
Speed
SUMPRODUCT is faster than SUM arrays, i.e. having {} arrays in the SUM function. SUMIFS is 30% faster than SUMPRODUCT.
{SUM(SUMIFS({}))} vs SUMPRODUCT(SUMIFS({})) both works fine, but SUMPRODUCT feels a bit easier to write without the CTRL-SHIFT-ENTER to create the {}.
Preference
I personally prefer writing SUMPRODUCT(--(ISNUMBER(MATCH(...)))) over SUMPRODUCT(SUMIFS({})) for multiple criteria.
However, if you have a drop-down menu where you want to select specific characteristics or all, SUMPRODUCT(SUMIFS()), is the only way to go. (as for selecting "all", the value should enter in "<>" + "Whatever word you want as long as it's not part of the specific characteristics".
In order to get the formula to work place the cursor inside the formula and press ctr+shift+enter and then it will work!
With the following, it is easy to link the Cell address...
=SUM(SUMIFS(FAGLL03!$I$4:$I$1048576,FAGLL03!$A$4:$A$1048576,">="&INDIRECT("A"&ROW()),FAGLL03!$A$4:$A$1048576,"<="&INDIRECT("B"&ROW()),FAGLL03!$Q$4:$Q$1048576,E$2))
Can use address / substitute / Column functions as required to use Cell addresses in full DYNAMIC.
I would like to have part of an excel formula be dynamic, other than a cell reference.
For instance, suppose that in column A (cells A1:A99) I have a bunch of numbers, and I want to know how many of those numbers are greater than 50.
If I wanted this calculation to be static, I could simply use one of the following:
=COUNTIF($A$1:$A$99,">50")
=SUM(IF($A$1:$A$99>50,1,0))
=SUM(($A$1:$A$99>50)*1)
I mention all three because my actual formula is hairy and a bit of a mix of the second and the third. (After all, perhaps something will work with COUNTIF but not with the others.)
Now, I want to be able to type my condition in another cell (say C1). So if I type ">50" in C1, my calculation will be as above, but if I type "<100" I will count how many entries of column A are less than 100.
Is this possible? (I am using Excel 2003 on Windows XP.)
There may be something that I'm missing.
If you give
=COUNTIF($A$1:$A$99,C1)
in any cell, and then in cell C1 you type >50 or <100
don't you get what you want?
Use INDIRECT
=INDIRECT(COUNTIF($A$1:$A$99,">50"))
is same as
=COUNTIF($A$1:$A$99,">50")
But, as you identified, the former, you can generate within the excel cells! I do it all the time, for such things.
I usually solve this by adding another column carrying the result of a complex logical expression, like
=AND(OR(C3<D3;E3>=100);A3=VLOOKUP(B3;Sheet2!$A$2:$B$212;2;FALSE))
this formula is in all rows of -say- column F - note: no IF needed here!
then I calculate a complex conditional sum across column E using =SUMIF() like
=SUMIF(F2:F57;TRUE;E2:E57)
I know that some users say "I do not want to change my design. That's ok; my argument is that I have better control over the condition, I can work on the condition seperately from summing up or other functions that rely on that condition, and I can filter records for TRUE or FALSE to look at the subsets and have a rapid overview if the formula makes sense
hope that helps Good luck MikeD