My worksheet contains orders from clients. The orders are all wooden panels.
Every order is assigned a number which is led by the letter Q.
Column B contains the number of parts in the order.
Column C contains the total m² in the order.
Orders that contain one or more parts that are 2.8 x 0.0735 m will get a row of their own.
I'm trying to count the number of times that this part occurs in a list of more than a thousand rows.
So if I divide the total m² by the m² of the part I'm looking for and divide this by the amount of parts in the order, I should get exactly 1 as a result.
If I take the sum of all the number of parts that result in a 1, I get my total.
Now I'd like to put this in one formula for the entire worksheet, but SUMIF doesn't work the way I'm trying. (It's in Dutch)
=SOM.ALS(B:B;(C:C/(2,8*0,0735)/B:B)=1)
I can't seem to use this formula as a criterium in the SUMIF.
For now I use a helping column that gives the right amount per row. Then take the total SUM of these.
Is it possible to put this in a single formula?
Yes, it is possible. Try this one:
{=SUM(--(B:B=C:C/(2.8*0.0735))*IF(ISERROR(1/B:B),0,1))}
Remember to enter it as an array function with CNTRL + SHIFT + ENTER.
The first half of the formula is just a logical test, after the asterisk it tests if 1/B results in an error (thereby omitting text, zeroes, and blanks) and returns a zero if there is an error.
These are then summed and the result displayed.
In Dutch and English:
{=SOMPRODUCT(--(B:B=(ALS(ISTEKST(C:C);1;C:C))/(2,8*0,0735));B:B)}
{=SUMPRODUCT(--(B:B=(IF(ISTEXT(C:C),1,C:C))/(2.8*0.0735)),B:B)}
is working perfectly. (Enter with Ctrl-Shift-Enter)
The first bit is the logical test, which will check if B:B = C:C / (2.8*0.0735)
It got stuck on #VALUE! because there is text in C:C.
The IF(ISTEXT)) eliminates text by converting them to numeric values, in this case 1, but it can be any numeric value.
The logical test will return TRUE(1) or FALSE(0) because of the double dash or unary operator and this will be multiplied by their respective B:B value.
Because the row with text has no value in B:B, it will result as zero.
Related
I've got a massive parts spreadsheet that I'm trying to simplify. Various parts could be included in number of locations, which I would like to add up to a single list. The attached file is just an example using reindeer.
This is doable with using a bunch of SUMIF statements added together, but not practical due to the range of columns I need to include. There's gotta be a better way!?
=SUMPRODUCT(--($D$4:$J$11=$A4),$E$4:$K$11))
SUMPRODUCT can do that. Make sure the second range shifts one column, but has equal count of columns (and rows).
($D$4:$J$11=$A4) results in an array of TRUE's or FALSE's for the value in range $D$4:$J$11 being equal to the value in $A4 (no $ prior to it's row number will increase the row # referenced when dragged down).
Adding -- in front of the array converts the TRUE's and FALSE's to 1's and 0's respectively.
Multiplying that with the range to the right of it will result in 1* the value in $E$4:$K$11 for all TRUE's, which results in it's value, or 0* the value in $E$4:$K$11 for all FALSE's, which results in 0.
Summing the array of values results in the sum of all values where the condition is met in the column left from it.
SUMPRODUCT combines the multiplication of the array and summing the array results to 1 total sum.
You can use simply the SUM:
=SUM((D$4:$D$11=A4)*$E$4:$E$11,($F$4:$F$11=A4)*$G$4:$G$11, etc.)
where in etc you can put any range you want. If you don't use 2021/365 version, you must confirm the formula with CTRL+SHIFT+ENTER.
I got a problem with my Excel, where it shows a same name twice, if the 'racers' have the excact same time. For example in the picture the racers 7 & 9 and racers 5 & 10 have the same time, but in the Start grid it shows the same name twice. It should be 4. Racer7 5. Racer9 & 9. Racer5 10. Racer10
The Function of Cell I3 =IF(OR(ISBLANK(B3);ISBLANK(C3));"";INDEX($B$3:$B$32;MATCH(J3;$D$3:$D$32;0))) (I have to use format ';' instead of ',') Function of cell J3 =IFERROR(SMALL($D$3:$D$32;H3);"")
Link to the file (does not work in Google Sheets & the functions have to use local formatting)
xlsx file
MATCH and RANK Getting Sick When Handling Time
Formulas
COMMA
[D3] =IF(NOT(ISNUMBER(C3)),"",ROUND($D$1-A3*"00:10,0"-C3,8))
[H3] =IF(ISNUMBER(K3),RANK(J3,D$3:D$32,2),"")
[I3] =IF(IFERROR(INDEX($B$3:$B$32,SMALL(IF($D$3:$D$32=J3,ROW($J$3:$J$32)-ROW(J$3)+1),COUNTIF($J$3:$J3,J3))),"")=0,"",IFERROR(INDEX($B$3:$B$32,SMALL(IF($D$3:$D$32=J3,ROW($J$3:$J$32)-ROW(J$3)+1),COUNTIF($J$3:$J3,J3))),""))
[J3] =IFERROR(SMALL($D$3:$D$32,A3),"")
[K3] =IFERROR(J3-J$3,IF(I3="","","disqualified"))
COLON
[D3] =IF(NOT(ISNUMBER(C3));"";ROUND($D$1-A3*"00:10;0"-C3;8))
[H3] =IF(ISNUMBER(K3);RANK(J3;D$3:D$32;2);"")
[I3] =IF(IFERROR(INDEX($B$3:$B$32;SMALL(IF($D$3:$D$32=J3;ROW($J$3:$J$32)-ROW(J$3)+1);COUNTIF($J$3:$J3;J3)));"")=0;"";IFERROR(INDEX($B$3:$B$32;SMALL(IF($D$3:$D$32=J3;ROW($J$3:$J$32)-ROW(J$3)+1);COUNTIF($J$3:$J3;J3)));""))
[J3] =IFERROR(SMALL($D$3:$D$32;A3);"")
[K3] =IFERROR(J3-J$3;IF(I3="";"";"disqualified"))
Why is MATCH 'miscalculating' to '7' instead of '6' in cells 'I6' and 'I7' in OP's worksheet (formula in 'D3')?
Time has a ton of decimals so I guess it's 'seeing' the values in 'D8' and 'D9' as different values. To avoid this you can round the values. If you want to use only these values it is enough to round them to 8 decimals for the numbers to be recognized as different even by a millisecond. If you want to sum them there might be some inaccuracies. In OP's case 8 decimals is more than enough.
RANK (formula in 'H3') is also 'miscalculating' if no rounding.
Why the long formula?
Best try it with and without the IF statement and see for yourself.
Here's a Hint:
For this you need a tie breaker. The unfortunately best way of doing this is using a helper column. In my test sheet I used column E but the column could, of course, be anywhere. More importantly, it could be hidden. In this column you enter a formula like
=D3+ROW()/10^8
The point is that the addition must be so small that it makes no difference to the result on rounding. So, the number of results you treat in this may makes a difference. If you find that the addition changes the result in the last row, increase the exponent. The change I made add 0.0001 seconds to each result, multiplied by the row number: 0.0001 in the first row, 0.0002 in the second, 0.0003 in the third etc. Check the results in the 10th and 100th row.
Now the results in column E are all different and it's these results that are used in columns J and I.
[J3] =SMALL($E$3:$E$32,H3)
and
[I3] =INDEX($B$3:$B$32,MATCH(J3,$E$3:$E$32,0))
There will be no more duplicates but the "winner" of a draw is decided by his position in the list.
A solution in old school array-formula-style would be:
Note It's an array-formula which needs to be confirmed through CTRLSHIFTENTER
=IF(OR(ISBLANK(B3),ISBLANK(C3)),"",INDEX($B$1:$B$32,SMALL(IF($D$1:$D$12=J3,ROW($J$1:$J$12)),COUNTIF($J$1:$J3,J3))))
The IF checks the timelist for the current time value and gives all matching lines back which are getting ranked by small. COUNTIF counts the occurences of the current time up to the current line.
How to get this in excel
excel table
F column is the result column
For the following answer I am going to assume you only ever have two numbers in any row, but they can be in any cell along the row and they are always greater than 0.
If you just wish to find the difference between the two numbers without worrying about which number is bigger, a simple equation using maximum and minimum can be used, eg in Cell F1 you would have
=MAX(A1:E1)-MIN(A1:E1)
However, from your example, it seems more likely that you want to know the difference between the first number and the second number.
The difficulty here, is that the cells in columns B, C and D could contain either the first number, the second number, or no number! The solution is to use the following equation in Cell F1
=(MAX(A1:E1)-MIN(A1:E1))*IF(MAX(A1:E1)=INDEX(A1:E1,MATCH(0,A1:E1,-1)),-1,1)
This formula works as follows:
We still start off with the simple difference between the max and min, and then this is multiplied by 1 or -1 depending on which way around the numbers are.
MATCH(0,A1:E1,-1)
This part of the equation looks along the row for a 0, and assumes they are in descending order, so it will return the position of the second number.
This is then inserted into the INDEX function and checked to see if it is the same as the maximum number and the IF function returns either -1 or 1 as required.
Paste this formula on F1, then copy to F2 and F3
=INDEX(A1:E1,MATCH(TRUE,INDEX(A1:E1<>"",),0)) - LOOKUP(9.99E+307,A1:E1)
I am currently drawing up a spreadsheet that will automatically remove duplicates and alphabetize a list:
I am using the COUNTIF() function in column G to create a sort order and then VLOOKUP() to find the sort in column J.
The problem I am having is that I can't seem to get my SortOrder column to function properly. At the moment it creates an index for two number 1's meaning the cell highlighted in yellow is missed out and the last entry in the sorted list is null:
If anyone can find and rectify this mistake for me I'll be very grateful as it has been driving me insane all day! Many thanks.
I'll provide my usual method for doing an automatic pulling-in of raw data into a sorted, duplicate-removed list:
Assume raw data is in column A. In column B, use this formula to increase the counter each time the row shows a non-duplicate item in column A. Hardcord B2 to be "1", and use this formula in B3 and drag down.
=if(iserror(match(A3,$A$2:A2,0)),B2+1,B2)
This takes advantage of the fact that when we refer to this row counter in our revised list, we will use the match function, which only checks for the first matching number. Then say you want your new list of data on column D (usually I do this for display purposes, so either 'group-out' [hide] columns that form the formulas, or do this on another tab). You can avoid this step, but if you are already using helper columns I usually do each step in a different column - easier to document. In column C, starting in C3 [C2 hardcoded to 1] and drag down, just have a simple counter, which error-checks to the stop at the end of your list:
=if(C2<max(B:B),C2+1," ")
Then in column D, starting at D2 and dragged down:
=iferror(index(A:A,match(C2,B:B,0)),"")
The index function is like half of the vlookup function - it pulls the result out of a given array, when you provide it with a row number. The match function is like the other half of the vlookup function - it provides you with the row number where an item appears in a given array.
Hope this helps you in the future as well.
The actual reason that this is going wrong as implied by Jeeped's comment is that you can't meaningfully compare a string to a number unless you do a conversion because they are stored differently. So COUNTIF counts numbers and text separately.
20212 will give a count of 1 because it is the only (or lowest) number.
CS10Z002 will give a count of 1 because it is the first text string in alphabetical order.
Another approach is to add the count of numbers to the count if the current cell contains text:-
=COUNTIF(INDIRECT("$D$2:$D$"&$F$3),"<="&D2)+ISTEXT(D2)*COUNT(INDIRECT("$D$2:$D$"&$F$3))
It's easier to show the result of three different conversions with some test data:-
(0) No conversion - just use COUNTIF
=COUNTIF(D$2:D$7,"<="&D2)
"999"<"abc"<"def", 999<1000
(1) Count everything as text
=SUMPRODUCT(--(D$2:D$7&""<=D2&""))
"1000"<"999"
(2) Count numbers before text
=COUNTIF(D$2:D$7,"<="&D2)+ISTEXT(D2)*COUNT(D$2:D$7)
999<1000<"999"
(3) Count everything as text but convert numbers with leading zeroes
=SUMPRODUCT(--(TEXT(D$2:D$7,"000000")<=TEXT(D2,"000000")))
"000999" = "000999", "000999"<"001000"
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