Given a table with two columns, A and B:
For each row, multiply A and B, then sum all the results.
I can just do =(A1*B1)+(A2*B2)+... but I need it to work for a table of any size.
that is exactly what SUMPRODUCT is for:
=SUMPRODUCT(A1:A5,B1:B5)
You can also use the array version of sum. This can give some added flexability in certain situations.
{=SUM(A1:A5*B1:B5)}
Related
I have the following input data:
I want to get a formula that can sort out descending order values for the factors across the three treatments.
For a particular factor, the formula should return A for six (6) consecutive descending ordered values within the treatment, B for four (4) consecutive descended order values, C for three (3) consecutive descended ordered values, and blank otherwise.
Here is the expected output from the input data sample:
Notes:
I'm using office 365, please consider that in your answer
I need a formula with drag and drop than doing it manually because in some cases, the factors are up to 100 and more than 70 treatments...
The following formula will return the number of values that appear in consecutively descending order:
=LET(
Order,MMULT(IFERROR(N(C3:H3>D3:H3),0),N(COLUMN(C3:H3)>=TRANSPOSE(COLUMN(C3:H3)))),
Score,UNIQUE(FILTER(Order,Order>0),1,1),
IF(SUM(ISERROR(Score))=0,COUNT(Score)+2,0)
)
So that the resulting table will look like this:
You can then use an IF() or SWITCH() or INDEX() function solution to categorize the numerical scores into the classes 'A', 'B', and 'C'.
This would be a partial answer because it cannot be dragged to right.
I've used old functions from Excel 2007 so this should work for you, but I'm pretty sure that with advanced functions this solution can be improved and be dragged to right.
The formula I've used for Treatment 1 is:
=IF(--(CONCATENATE(B2;C2;D2;E2;F2;G2)="654321")>0;"A";IF(O(ISNUMBER(FIND("6543";CONCATENATE(B2;C2;D2;E2;F2;G2)));ISNUMBER(FIND("5432";CONCATENATE(B2;C2;D2;E2;F2;G2)));ISNUMBER(FIND("4321";CONCATENATE(B2;C2;D2;E2;F2;G2))));"B";IF(O(ISNUMBER(FIND("654";CONCATENATE(B3;C3;D3;E3;F3;G3)));ISNUMBER(FIND("543";CONCATENATE(B3;C3;D3;E3;F3;G3)));ISNUMBER(FIND("432";CONCATENATE(B3;C3;D3;E3;F3;G3)));ISNUMBER(FIND("321";CONCATENATE(B3;C3;D3;E3;F3;G3))));"C";"")))
My argument separator is the ; so you may need to replace those with commas
Here is my problem:
I need to search using or logic in a 2d array for any row that contains any given substring(s), and sum that row's sum column as a result.
I have a column, Hours, that I would like to sum if the column Name OR the column Description contain any number of criteria. So far my (ugly) solution is (pardon the formatting):
SUM(SUMIFS(B16:B100,C16:C100,{"(asterisk)Crit1(asterisk)","(asterisk)Crit2(asterisk)"}),SUMIFS(B16:B100,D16:D100,{"(asterisk)Crit1(asterisk)","(asterisk)Crit2(asterisk)"}))
This by itself is not bad, and with only 2 columns isn't horrible. But, some of you may have seen that this can cause double-counts if the criteria is in both columns, which I do not want.
So my question: Can I do this in such a way where I can search for criteria in multiple columns, and if they exist in any column, then sum the sum range, only once?
Try (untested since you show no data):
=SUM(B16:B100*((ISNUMBER(SEARCH({"Crit1","Crit2"},C16:C100))+ISNUMBER(SEARCH({"crit3","Crit4"},D16:D100)))>0))
Adding comparisons is like doing an OR; by comparing the sum of the comparisons to zero, we determine if any single one is present.
The formula may need modification if you have criteria which can be miscounted.
For example:
Note that Crit1 will return a match for Crit1, Crit101, etc. Depending on your actual data, a formula modification might be possible; or a UDF might be more practical.
Let's say 3 columns (A, B, C) are dynamic arrays and I want to create a fourth/final dynamic array formula that is the sum of these 3 columns for each row in column D. For clarity, I am looking for the row-by-row sum of each row in this final column.
This will work:
=A2#+B2#+C2#
How can the same be accomplished by using the SUM function? The reason I ask is that this is easier to use on larger ranges of data.
The following gives a #REF! error:
=SUM(A2:C2#)
New Edit:
With the addition of BYROW and LAMBDA we can do this a little easier than my original answer below:
=BYROW(A1#:C1#,LAMBDA(x,SUM(x)))
The BYROW passes each row into the LAMBDA which does the SUM iteratively and returns an array:
Original Answer
The problem is that SUM,MAX,MIN all allow arrays and do the whole on the full array. So we need to use something that uses arrays and spills individual results. That is what MMULT was built for.:
=MMULT(A2#:C2#,TRANSPOSE(COLUMN(A2:C2)^0))
Just realized with the dynamic arrays we have SEQUENCE:
=MMULT(A2#:C2#,SEQUENCE(COLUMNS(A2:C2),,1,0))
Try this for sums per column (assuming A1# is the dynamic range with the source data):
=SUBTOTAL(9,OFFSET(A1#,0,SEQUENCE(1,COLUMNS(A1#))-1,ROWS(A1#),1))
Just change the first argument of the SUBTOTAL function to use any of the aggregation functions available (min, max, average, etc.). With some tweaks, this can be made to work for row totals.
When I tried Scott Craner's formula above I received a VALUE# error, possibly related to the fact that I was testing it on data columns of different dynamic lengths.
Even though the expression A2#:C2# returns a matrix of width 3 columns, and height of whichever of the three columns has the most rows (filling in zeros for any blank cells), MMULT didn't seem to like that expression and resulting matrix as the first argument. However I found that I was able to modify it as follows to make it work:
=MMULT((A2#:C2#*1),SEQUENCE(COLUMNS(A2:C2),,,0))
Absolute legend. I've been trying to work this out. Thank you so much. I have never used MMULT before, only SUMPRODUCT for similar problems. My problem was to dynamically sum up the last few columns in a spill table and I was able to adapt your solution.
In terms of the question above, if the three spill columns were one spill table with rows and columns in the one spill range it would be:
=MMULT(A2#,SEQUENCE(ROWS(A2#)),SEQUENCE(COLUMNS(A2#)),,1,0))
I have date column H, and values in K, and I want to find the sum of the VALUES in K --if H is today.
I tried =COUNTIFS(K:K,"<>",H:H,">="&TODAY())
which gives me the number of entries today, but NOT the sum of their values!
Also, when searching I found some suggestions talking about greater/lesser than today, but I'm looking to compute Today only!
Here is some reading material about SumIfs ...
=SUMIFS(K:K,H:H,TODAY())
I prefer SUMPRODUCT for this.
= SUMPRODUCT(K:K,(H:H=TODAY())+0)
I recommend narrowing down the full column ranges to where ever your data actually ends (e.g. if you have 100 rows of data, change K:K to K1:K100).
=SUMIFS(K2:K500,H2:H500,TODAY())
First column is text labels, therefore not included.
Looking to find the max value in a column based on two sets of criteria
So the logic would be: Find the minimum value in column M, where the value in column A matches column N, and the value in Column Y is less than 318.
I've tried using an array formula like this but it doesn't seem to be working/is to memory heavy to run:
=MIN(IF(AND(N:N=A2,Y:Y<=318),M:M))
is there a simpler way? or perhaps a UDF that could work?
Thank you for your help!
You can't use AND in these type of formulas because it only returns a single value rather than the required array.
Here are three possible working versions:
1.) Use * to simulate AND
=MIN(IF((N:N=A2)*(Y:Y<=318),M:M))
confirmed with CTRL+SHIFT+ENTER
2.) Use multiple nested IFs
=MIN(IF(N:N=A2,IF(Y:Y<=318,M:M)))
confirmed with CTRL+SHIFT+ENTER
3.) Use AGGREGATE function
=AGGREGATE(15,6,M:M/(N:N=A2)/(Y:Y<=318),1)
The advantages of this approach are that you don't need "array entry", and it can ignore any errors in the data
Either way it's best to reduce the ranges sizes if you can because it might be slow with whole columns
Give this a try and adjust ranges to suit. Try not to use whole column references:
=SMALL(INDEX(($N$2:$N$101=A2)*($Y$2:$Y$101<=318)*$M$2:$M$101,),1+ROWS($M$2:$M$101)-COUNTIFS($N$2:$N$101,A2,$Y$2:$Y$101,"<=318"))
If you are using the whole column to pick up new data as it is added, consider using Dynamic Named Ranges instead
When things get this complex, I'll usually break it down and setup smaller/simpler formulas in seperate columns.
In other words, you have data in columns A through Y ?
So let's create a formula in column AA:
1) identify when value in Col A matches col N, and value in col Y < 318
=and(A1=N1,Y1<318)
2) copy AA1 to all the rows of your data.
3) now we have a condition to work off .. since there is a SUMIF and COUNTIF, but no MINIF .. we'll have to build that ourselves. first the IF:
in column AB1:
=if(AA1,M1,"")
copy that down to all your data.
finally, do your min:
=MIN(AB:AB)
Should give you your answer.
You could probably splice the first two together, but again, building a complex formula like this, build it simply, first, ;)