This function can also calculate something like the result of sumifs if I put an array into the criteria argument: =sumproduct(sumifs(sumrange, criteria range, criteria)). It gives me the sum of the sum of all the criterion in the array. If I just do =sumifs(sumrange,criteria range, criteria) and the criterion is an array, then the result would be zero. I could only check the result by pressing F9 and it gives me the sum of each criteria separately. Why can sumproduct function add up all the separate values here?
When you use this formula
=SUMIFS(sumrange,criteria range, criteria)
with a range in place of the criteria then the result is an array of values
To get the result you want you can enclose that in SUM function......but then the formula needs to be "array entered" with CTRL+SHIFT+ENTER.....so using SUMPRODUCT is a way to avoid array entry. Because the result of SUMIFS is a single array SUMPRODUCT has nothing to multiply so it just sums the array
In short, when fed a single array SUMPRODUCT just sums the contents, e.g.
=SUMPRODUCT({1,2,3}) = 6
SumProduct is a very particular formula and you'll see it used in many occasions as a workaround to using array formulas, but only when it's used as a substitute of a point-array formulas (array formulas entered into a single cell), because it works with arrays by default.
In your particular case, you seem to get 0 with SUM(SUMIFS) as pure coincidence, because the sum of elements that are true for the first element of your array criterion is 0.
If you have, for example, a table as such:
A B C
1 t t
2 f f
3 t
4 x
5 x
and use the formula:
=SUM(SUMIFS($A$1:$A$5,$B$1:$B$5,$C$1:$C$2))
You will get 4 as a result, because it will only evaluate the first element of your condition array. If you instead enter it as an array formula with Ctrl + Shift + Enter, it will evaluate the condition with all the elements of your conditional array, working as such:
Evaluate =SUMIFS({1,2,3,4,5},{t,f,t,x,x},{t})
Return =SUM({1,2,3,4,5}*{1,0,1,0,0}) => SUM({1,0,3,0,0}) => 4
Store 4 in the first position of the temporary array {4,NULL}
Evaluate =SUMIFS({1,2,3,4,5},{t,f,t,x,x},{f})
Return =SUM({1,2,3,4,5}*{0,1,0,0,0}) => SUM({0,2,0,0,0}) => 2
Store 2 in the second position of the temporary array {4,2}
Evaluate =SUM({4,2})
Return 6
Which is pretty much the exact same thing the SUMPRODUCT formula would do.
Let me know if there's any further clarification needed.
Related
I need to count how many different values are in a range. I got the answer by using SUMPRODUCT(1/COUNTIF(A2:A37,A2:37)), however, I don't understand the formula, can someone please help me explain?
If I do the COUNTIF separately, the result is 0? How does SUMPRODUCT(1/COUNTIF) help? Also, inside the COUNTIF, the range and criteria are the same, what does this mean? I understand that the range is where we look for, and the criteria is for what criteria, but if the criteria is the entire range, how are we specifying what we're looking for here? How does this translate/work?
Here my sample input:
enter image description here
Just extend some of the comments provided in your question for a better understanding. Here: Excel dynamic arrays, functions and formulas you can find a detail explanation about dynamic arrays and implicit interception and how it has changed through Excel evolution.
SUMPRODUCT (array1, [array2], ...) can be used with a single argument, in such case it sums all elements in array1, i.e. similar to SUM function (Excel SUMPRODUCT Function). For example: SUMPRODUCT({1;2;3}) = 6.
Note: Multiplication is the default operation of SUMPRODUCT, but you can use others (check this link) replacing the , with the corresponding operation. For example: SUMPRODUCT({1;2;3}/({1;2;3}))=3 (acts as COUNT), i.e. 1/1+2/2+3/3 but SUMPRODUCT({1;2;3},{1;2;3})=14, i.e. 1*1+2*2+3*3.
COUNTIF(range, criteria) the first argument has to be a range, but the second argument can be a number, expression, cell reference, or text string that determines which cells will be counted, but it also can be a range or an array (Excel COUNTIF function). If that is the case, COUNTIF is invoked for each element of criteria and returns an array of the same size and shape as criteria. For example if the following range A1:A4 has the following values:
|1|
|2|
|1|
|1|
the following expressions will return:
COUNTIF(A1:A4, 1) = 3
COUNTIF(A1:A4, A1:A2) = {3;1} i.e. 2x1 array
COUNTIF(A1:A4, {1;2}) = {3;1}
COUNTIF(A1:A4, {1,2}) = {3,1} i.e. 1x2 array
and for a two dimensional criteria {1,2;0,1} a 2x2 array:
=COUNTIF(A1:A4, {1,2;0,1}) = ={3,1;0,3} i.e. 2x2 array
Note: Remember you can not invoke the function with the first input argument as an array, for example: COUNTIF({1;2;1;1}, 1) returns an error. It has to be a range.
so we can count how many times each element of the first input argument is repeated like this:
COUNTIF(A1:A4,A1:A4) = {3;1;3;3} i.e. 4x1 array
Now back to SUMPRODUCT (remember with a single argument it is just the sum of the elements):
SUMPRODUCT(COUNTIF(A1:A4,A1:A4))
= SUMPRODUCT({3;1;3;3})
= 10
i.e. sum of occurrences of each element of A1:A4
and finally:
SUMPRODUCT(1/COUNTIF(A1:A4,A1:A4))
= SUMPRODUCT({1/3;1/1;1/3;1/3})
= 3*(1/3) + 1
= 2
which results in total total number of unique elements in A1:A4. As #Harun24hr pointed out, it can be achieved in Microsoft 365 with: COUNTA(UNIQUE(A1:A4) or also COUNT(UNIQUE(A1:A4) since in the example of this answer A1:A4 are numbers, but in the sample of your question (letters) you have to use: COUNTA.
Is there a formula that returns a value from the first line matching two or more criteria? For example, "return column C from the first line where column A = x AND column B = y". I'd like to do it without concatenating column A and column B.
Thanks.
True = 1, False = 0
D1 returns 0 because 0 * 1 * 8 = 0
D2 returns 9 because 1 * 1 * 9= 9
This should let you change the criteria:
I use INDEX/MATCH for this. Ex:
I have a table of data and want to return the value in column C where the value in column A is "c" and the value in column B is "h".
I would use the following array formula:
=INDEX($C$1:$C$5,MATCH(1,(($A$1:$A$5="c")*($B$1:$B$5="h")),0))
Commit the formula by pressing Ctrl+Shift+Enter
After entering the formula, you can use Excel's formula auditing tools to step through the evaluation to see how it calculates.
SUMPRODUCT definitely has value when the sum over multiple criteria matches is needed. But the way I read your question, you want something like VLOOKUP that returns the first match. Try this:
For your convenience the formula in G2 is as follows -- requires array entry (Ctrl+Shift+Enter)
[edit: I updated the formula here but not in the screen shot]
=INDEX($C$1:$C$6,MATCH(E2&"|"&F2,$A$1:$A$6&"|"&$B$1:$B$6,0))
Two things to note:
SUMPRODUCT won't work if the result type is not numeric
SUMPRODUCT will return the SUM of results matching the criteria, not the first match (as VLOOKUP does)
Apparently you can use the SUMPRODUCT function.
Actually, I think what he is asking is typical multiple results display option in excel. It can be done using Small, and row function in arrays.
This display all the results that matches the different criteria
Here is an answer that shows how to do this using SUMPRODUCT and table header lookups. The main advantage to this: it works with any value, numeric or otherwise.
So let's say we have headers H1, H2 and H3 on some table called MyTable. And let's say we are entering this into row 1, possibly on another sheet. And we want to match H1, H2 to x, y on that sheet, respectively, while returning the matching value in H3. Then the formula would be as follows:
=INDEX(MyTable[H3], ROUND(SUMPRODUCT(MATCH(TRUE, (MyTable[H1] & MyTable[H2]) = ($x1 & $y1),0)),0),1)
What does it do? The sum-product ensures everything is treated as arrays. So you can contatenate entire table columns together to make an array of concatenated valued, dynamically calculated. And then you can compare these to the existing values in x and y- somehow magically you can compare the concatenated array from the table to the individual concatenation of x & y. Which gives you an array of true false values. Matching that to true yields the first match of the lookup. And then all we need to do is go back and index that in the original table.
Notes
The rounding is just in there to make sure the Index function gets back an integer. I got #N/A values until I rounded.
It might be more instructive to run this through the evaluator to see what's going on...
This can easily be modified to work with a non table - just replace the table references with raw ranges. The tables are clearer though, so use them if possible. I found the original source for this here: http://dailydoseofexcel.com/archives/2009/04/21/vlookup-on-two-columns/. But there was a bug with rouding values to INTs so I fixed that.
Here is the screenshot of my excel workbook
I do not understand why the value in cell j7 is 44 ?
j7 formula is =LOOKUP(1,(TRIM($D$2:$D$9)=TRIM(H7))/(TRIM($E$2:$E$9)=TRIM(I7)),$F$2:$F$9)
The result of the two arrays division is the following
{TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE}/
{TRUE;FALSE;TRUE;FALSE;FALSE;TRUE;FALSE;FALSE} =
{1;#DIV/0!;0;#DIV/0!;#DIV/0!;0;#DIV/0!;#DIV/0!}
Right ?
So I am looking for 1, basically the formula becomes
LOOKUP(1,{1;#DIV/0!;0;#DIV/0!;#DIV/0!;0;#DIV/0!;#DIV/0!},$F$2:$F$9)
Hence the result should be 10 but not 44 . . . . . ?
EDIT
When i correct my formula to =LOOKUP(1,1/(TRIM($D$2:$D$9)=TRIM(H7))/(TRIM($E$2:$E$9)=TRIM(I7)),$F$2:$F$9)
it works fine . Why ? Thank you everybody for giving the alternative solutions with match and index. I just can't understand why my first formula did not work. Any why when i add 1/ it MAGICALLY works ? ? ?
If the values are not in ascending order, and you are looking for a value within the range of values (as opposed to a value larger than anything in the range), LOOKUP may give unexpected results.
A different way to return the desired result is with a combination of INDEX and MATCH:
=INDEX($F$2:$F$9,MATCH(1,(TRIM($D$2:$D$9)=TRIM(H7))/(TRIM($E$2:$E$9)=TRIM(I7)),0))
entered as an array formula with ctrl-shift-enter
Note that with MATCH, looking for an exact match, the range does not need to be sorted.
Another formula that will return the correct results, and can be normally entered (assuming no duplicate entries in the first table):
=SUMPRODUCT((TRIM(H7)=TRIM($D$2:$D$9))*(TRIM(I7)=TRIM($E$2:$E$9))*$F$2:$F$9)
The explanation is:
with the first formula, the first array in the Lookup function contains zeros after the 1 value, in the third and sixth value of the array:
Lookup expects data to be sorted ascending and will return the first item less than or equal to the search value, starting from the last value in the array. In this case that is the zero value in the sixth position of the array.
The edited formula results in an array that contains only one number "1". All other values are Div errors. So the position of that "1" value is what Lookup will use.
Further explanation:
In your first formula you divide two arrays that contain TRUE or FALSE and the result contains 1, 0 and Div error values.
{TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE}/
{TRUE;FALSE;TRUE;FALSE;FALSE;TRUE;FALSE;FALSE} =
{1;#DIV/0!;0;#DIV/0!;#DIV/0!;0;#DIV/0!;#DIV/0!}
Including the 1/ in the formula will divide the first array of TRUE and FALSE values by 1, which returns an array that consists of either 1 or Div errors. Further dividing that array by the second array will only return 1 or Div errors, no zeros. The steps are
1/{TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE}/{TRUE;FALSE;TRUE;FALSE;FALSE;TRUE;FALSE;FALSE} results in
{1;1;#DIV/0!;#DIV/0!;#DIV/0!;#DIV/0!;#DIV/0!;#DIV/0!}/{TRUE;FALSE;TRUE;FALSE;FALSE;TRUE;FALSE;FALSE} results in
{1;#DIV/0!;#DIV/0!;#DIV/0!;#DIV/0!;#DIV/0!;#DIV/0!;#DIV/0!}
No zeros!
As mentioned, LOOKUP expects the values in the lookup_vector to be in ascending order. To gain the first match of columns H & I to columns D & E, I would suggest mathematically excluding the non-matching rows. What is left would be the matching rows. The following example supplies the first double match.
For J2
=INDEX($F$2:$F$9,MIN(INDEX(ROW($1:$8)+(($D$2:$D$9<>H2)+($E$2:$E$9<>I2))*1E+99,,)))
Fill down as necessary. This is a standard formula and can be easily modified to supply the 2nd, 3rd, etc matching values by swapping SMALL() in place of MIN(). Your results should be close to the following.
Part 1:
I was able to construct a formula that does exactly what I want (from some examples), but yet, I'm unable to figure out how exactly it works. I have, starting with cell A1:
Price $
table 20
chair 10
Invoice Quantity
table 17
chair 1
chair 2
table 3
What I want is the final total (430) for the invoice which is computed as Quantity*Price for each item (17*20 + 1*10 + 2*10 + 3*20). the following formula correctly does this:
=SUMPRODUCT(B6:B9,SUMIF(A2:A3,A6:A9,B2:B3))
I understand the basics of SUMPRODUCT and SUMIF. But here, my argument for SUMIF's range is A2:A3, which makes me think the SUMIF would iterate through A2 and A3, and not through A8:A11 (which is the criteria). What gives?
Edit: the unclear part is, what exactly does SUMIF do (what is its iteration pattern) when the first two arguments are of different dimensions (here, the range is 2 cells while the criteria is 4 cells). Also, what is the "output" of SUMIF? An array? Of what dimensions?
Part 2:
In addition, if I ignored the quantity and simply wanted to add 20 whenever I saw a table and 10 whenever I saw a chair, I figured I would do:
=SUMIF(A2:A3,A6:A9,B2:B3)
But that doesn't work, and I have to enclose it with a SUMPRODUCT() for it to work and correctly evaluate to 60. Enclosing it within a SUM doesn't work either (probably because the SUMIF doesn't return an array?) Why?
I've read a bunch of tutorials and still can't understand this, and would be most grateful for a clear, intuitive explanation for both these cases. Thank you.
SUMIF can produce an array of results. If you take my formula
=SUMIF(A6:A9,A2:A3,B6:B9)
it says
For the criteria in A2 (ie table)
- look at A6:A9
- where table is matched, sum the corresponding value in B6:B9
- returns 20 (ie 17 +0 +0 +3)
- this is stored in the first position of the array
Then for the criteria in A3 (ie chair)
- look at A6:A9
- where table is matched, sum the corresponding value in B6:B9
- returns 3 (ie 0 +1 +2 +0)
- this is stored in the second position of the array
So the end array from the SUMIF is {20:3}
You can see the array result by highlighting the SUMIF formula in Excel's formula bar and then pressing F9
Then use SUMPRODUCT to multiple the count in the SUMIF by the $ values in B2:B3 to get total dollars
={20;3}*{20:10}
=20*20 + 3*10
= 430
Part 1
Rather than
SUMIF(A2:A3,A6:A9,B2:B3)
which produces a four element array of
={20;10;10;20}
(corresponding to table;chair;chair;table)
You should use
SUMIF(A6:A9,A2:A3,B6:B9)
which sums the values in B6:B9 against your two criteria in A2:A3 giving the desired result
={20;3}
(corresponding to table;chair)
and then use SUMPRODUCT to weight your array, ie
=SUMPRODUCT(SUMIF(A6:A9,A2:A3,B6:B9),B2:B3)
={20;3}*{20:10}
=430
Part 2
Use COUNTIF to return an array of the number of chairs and tables and then multiply by the vales using SUMPRODUCT
=SUMPRODUCT(B2:B3,COUNTIF(A6:A9,A2:A3))
={20;10} * {2;2}
=60
Well you only have one minor mistake:
probably because the SUMIF doesn't return an array?
SUMIF can work with arrays, thats why you formula SUMPRODUCT( SUMIF() ) works in first place, to SUMIF show an array you have to select a group of cells (like C6:C9) input the formula and use CTRL+SHIFT+ENTER instead of ENTER only. this generate an "array fomula", identified by curly brackets {} (those can only be entered with CTRL+SHIFT+ENTER, no manualy) and show the array formula and results
Is there a formula that returns a value from the first line matching two or more criteria? For example, "return column C from the first line where column A = x AND column B = y". I'd like to do it without concatenating column A and column B.
Thanks.
True = 1, False = 0
D1 returns 0 because 0 * 1 * 8 = 0
D2 returns 9 because 1 * 1 * 9= 9
This should let you change the criteria:
I use INDEX/MATCH for this. Ex:
I have a table of data and want to return the value in column C where the value in column A is "c" and the value in column B is "h".
I would use the following array formula:
=INDEX($C$1:$C$5,MATCH(1,(($A$1:$A$5="c")*($B$1:$B$5="h")),0))
Commit the formula by pressing Ctrl+Shift+Enter
After entering the formula, you can use Excel's formula auditing tools to step through the evaluation to see how it calculates.
SUMPRODUCT definitely has value when the sum over multiple criteria matches is needed. But the way I read your question, you want something like VLOOKUP that returns the first match. Try this:
For your convenience the formula in G2 is as follows -- requires array entry (Ctrl+Shift+Enter)
[edit: I updated the formula here but not in the screen shot]
=INDEX($C$1:$C$6,MATCH(E2&"|"&F2,$A$1:$A$6&"|"&$B$1:$B$6,0))
Two things to note:
SUMPRODUCT won't work if the result type is not numeric
SUMPRODUCT will return the SUM of results matching the criteria, not the first match (as VLOOKUP does)
Apparently you can use the SUMPRODUCT function.
Actually, I think what he is asking is typical multiple results display option in excel. It can be done using Small, and row function in arrays.
This display all the results that matches the different criteria
Here is an answer that shows how to do this using SUMPRODUCT and table header lookups. The main advantage to this: it works with any value, numeric or otherwise.
So let's say we have headers H1, H2 and H3 on some table called MyTable. And let's say we are entering this into row 1, possibly on another sheet. And we want to match H1, H2 to x, y on that sheet, respectively, while returning the matching value in H3. Then the formula would be as follows:
=INDEX(MyTable[H3], ROUND(SUMPRODUCT(MATCH(TRUE, (MyTable[H1] & MyTable[H2]) = ($x1 & $y1),0)),0),1)
What does it do? The sum-product ensures everything is treated as arrays. So you can contatenate entire table columns together to make an array of concatenated valued, dynamically calculated. And then you can compare these to the existing values in x and y- somehow magically you can compare the concatenated array from the table to the individual concatenation of x & y. Which gives you an array of true false values. Matching that to true yields the first match of the lookup. And then all we need to do is go back and index that in the original table.
Notes
The rounding is just in there to make sure the Index function gets back an integer. I got #N/A values until I rounded.
It might be more instructive to run this through the evaluator to see what's going on...
This can easily be modified to work with a non table - just replace the table references with raw ranges. The tables are clearer though, so use them if possible. I found the original source for this here: http://dailydoseofexcel.com/archives/2009/04/21/vlookup-on-two-columns/. But there was a bug with rouding values to INTs so I fixed that.