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
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
Right now I need to sum up some values in certain cells in Excel that are unstructured with text like this:
Netherlands (325)
Belgium (214)
Australia (970)
etc.
So I am only interested in the total value. Of course I could clean the cells and separate the value from the text and sum it up. But I was wondering if there is a fast solution in excel to ignore the text and just take the value in the cell, since this kind of scenario happens often in daily business.
Best regards!
No, you will must have some a bit more complex formula to accomplish this, as far as I am informed, you cant just take in consideration numbers from text only.
In your case, if A1 is "Netherlands (325)", you would have to filter out number with something like =MID(A1, SEARCH("(", A1)+1, (SEARCH(")", A1)) - (SEARCH("(", A1)+1)), and then sum that column.
Eventually, if you dont want to take another column for numbers, you can do similar thing as upper one, with array formula.
Are your values always 3 numeric characters? Then yes here you go:
=SUMPRODCUT(0+RIGHT(SUBSTITUTE(A1:A3,")",""),3))
Thanks for the formulas so far. What I just experienced is, if you type
in the number of the first cell manually next to it, excel auto fills all cells beneath with the corresponding numbers of the other fields. That is super handy and fast I guess.
So, say I have at cell A1:
=IF(A2=1,A2,0)
That OK, that's a tiny formula easy to understand.
If the formula starts to grow, I would have something like:
IF(...big formula here...=1,...repeat the big formula here...,0)
It's a dummy example but the key point here is that when I repeat the big formula at the TRUE condition position the formula double its size, what can hinder the formula debugging, for example.
Is there a way to not repeat the whole formula writting at this situation?
I don't want to use any macro/VBA to do this or any other 'helper' cells.
Thanks
In this particular case you don't have to use an IF statement, can just use
=--(A2=1)
Or for some other value, say 2,
=(A2=2)*2
These work if one of the results you want is zero.
It is a little more difficult if you have an IF statement like
=IF(A2>2,A2,2)
but you can often use MAX or MIN to avoid the IF statement
=MAX(A2,2)
If you had a chain of IF statements to divide the number in A2 into ranges like
=IF(A2>=2,20,IF(A2>=1,10,0))
You could replace it with a lookup
=IFERROR(VLOOKUP(A2,{1,10;2,20},2),0)
Sometimes you can replace a series of IF statements with CHOOSE, e.g. to return "Negative", "Positive" or "Zero"
=CHOOSE(SIGN(A2)+2,"Negative","Zero","Positive")
One tricky way I have seen is to use inverse functions one of which gives an error under certain conditions, so you could try
=IFERROR((SQRT(A2-2)^2)+2,2)
but I'm not sure I could recommend it as these methods can be vulnerable to rounding errors.
See this previous question
Create a helper column -- say, col X -- that calculates your big formula. Hide the column if you don't want to confuse other spreadsheet viewers.
Then your long, difficult to debug formula becomes IF(X1=1,...X1...,0).
I'm working on data from a population of people with allergies. Each person has a unique ExceptionID, and each allergen has a unique AllergenID (451 in total).
I have a data table with 2 columns (ExceptionID and AllergenID), where each person's allergies are listed row by row. This means that the ExceptionID column has repeated values for people with multiple allergies, and the AllergenID column has repeated values for the different people who have that allergy.
I am trying to count how many times each pair of allergies is present in this population (e.g. Allergen#107 & Allergen#108, Allergen#107 & Allergen#109,etc). To keep it simple I've created a matrix of 451 rows X 451 columns, representing every pair (twice actually because A/B and B/A are equivalent).
I somehow need to use the row name (allergenID) to lookup the ExceptionID in my data table, and count the cases where that matches the ExceptionIDs from the column name (also AllergenID). I have no problem using Vlookup or Index/Match, but I'm struggling with the correct combination of a lookup and Sumproduct or Countif formula.
Any help is greatly appreciated!
Mike
PS I'm using Excel 2016 if that changes anything.
-=UPDATE=-
So the methods suggested by Dirk and MacroMarc both worked, though I couldn't apply the latter to my full data set (17,000+ rows) because it was taking a long time.
I've since decided to turn this into a VBA macro because we now want to see the counts of triplets instead of pairs.
With the 2 columns you start with, it is as good as impossible... You would need to check every ExceptionID to have 2 different specific AllergenID. Better use a helper-table with ExceptionID as rows and AllergenID as columns (or the opposite... whatever you like). The helper table needs a formula like:
=COUNTIFS($A:$A,$D2,$B:$B,E$1)
Which then can be auto-filled. (The ranges are from my example, you need to change them to your needs).
With this helper-matrix you can easily go for your bigger matrix like this:
=COUNTIFS(E:E,1,INDEX($E:$G,,MATCH($I2,$E$1:$G$1,0)),1)
Again, you can auto-fill with this formula, but you need to change it, so it fits your needs.
Because the columns have the same ID2 (would be your AllergenID), there is no need to lookup them because E:E changes automatically with the auto-fill.
Most important part of the formulas are the $ which should not be messed up, or you can not auto-fill it.
Picture of my self-made example (formulas are from the upper left cell in each table):
If you still have any questions, just ask :)
It can be done straight from your original set-up with array formulas:
Please note that array formulas MUST be entered with Ctrl-Shift-Enter, before copying across and down:
In the example pic, I have NAMED the data ranges $A$2:$A$21 as 'People' and $B$2:$B$21 as 'Allergens' to make it a nicer set-up. You can see in the formula bar how that looks as a formula. However you could use the standard references like this in your first matrix cell:
EDIT: silly me, N function is not needed to turn the booleans into 1's and 0's, since multiplying booleans will do the trick. Below formula works...
SUM(IF(MATCH($A$2:$A$21,$A$2:$A$21,0)=ROW($A$2:$A$21)-1, NOT(ISERROR(MATCH($A$2:$A$21&$E2,$A$2:$A$21&$B$2:$B$21,0)))*NOT(ISERROR(MATCH($A$2:$A$21&F$1, $A$2:$A$21&$B$2:$B$21,0))), 0))
Then copy from F2 across and down. It can be perhaps improved in technique with sumproduct or whatever, but it's just a rough example of the technique....
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.