Nested array formulas - excel

I want a summation of rates. Let me explain it: I would like to sum the numbers in column D that matches 2 conditions (green rows in excel). First one: column F equal to "closed". Second one: column C equal to those numbers which in turn matches the following condition: column F equal to "Partial Sold". At the same time, EACH number in the previous summation might be divided by the number of column D which matches "Partial Sold" in column F.
There is the example with the table/figure I attached: (4510 / 9820) + (6500 / 9820) + (9100 / 15400) + (2388 / 2995) + (12400 / 9820) + (2904 / 5855).
My cells would be: (D69 / D66) + (D70 / D66) + (D76 / D74) + (D82 / D78) + (D83 / D66) + (D84 / D72).
#Jeeped with your cells would be: (D6 / D3) + (D7 / D3) + (D13 / D11) + (D19 / D15) + (D20 / D3) + (D21 / D9)
.. C D E F
65 # Total Side Condition
66 1 9820 Buy Partial Sold
67 2 3850 Buy Closed
68 3 7151 Buy Partial Sold
69 1 4510 Sell Closed
70 1 6500 Sell Closed
71 4 8180 Buy Open
72 5 5855 Buy Partial Sold
73 6 2553 Buy Open
74 7 15400 Buy Partial Sold
75 2 4600 Sell Closed
76 7 9100 Sell Closed
77 8 7531 Buy Open
78 9 2995 Buy Partial Sold
79 3 3000 Sell Closed
80 10 8691 Buy Open
81 3 2500 Sell Closed
82 9 2388 Sell Closed
83 1 12400 Sell Closed
84 5 2904 Sell Closed
85 11 3848 Buy Open
86 12 7745 Buy Open

To do it in one step with an array formula you could use:
=SUM(IFERROR((D66:D86*(F66:F86="Closed"))/((C66:C86=TRANSPOSE(C66:C86))*TRANSPOSE(D66:D86*(F66:F86="Partial Sold"))),0))
This is an array formula and must be confirmed with Ctrl+Shift+Enter↵.
it will generate a 2D-array holding the original values for closed as rows and divides this 1D array by this:
buils up 2D-array by col C = transposed col C
multiply each row by col D
set all items in each row to 0 if not "Partial Sold"
for each div by 0 the IFERROR will set it to 0
and this all in the SUM will give you your output

I too would recommend using a helper column. You don't need to use array formulas to get to the answer though. You can use the following in the next available column:
=IF(F66="Closed",IFERROR(D66/SUMIFS($D$66:$D$86,$F$66:$F$86,"Partial Sold",$C$66:$C$86,C66),0),0)
This will return values for everything that matches your criteria, and zeroes for everything else. Then you can just take the sum of this helper column as your final summation of rates.
If you really don't want to use a helper column, you can wrap the helper column formula in a SUM and swap out the individual cell references for arrays (i.e. swap F66 for $F$66:$F$86, and so on), then enter it as an array formula with Ctrl+Shift+Enter↵. The whole thing would look like this:
=SUM(IF($F$66:$F$86="Closed",IFERROR($D$66:$D$86/SUMIFS($D$66:$D$86,$F$66:$F$86,"Partial Sold",$C$66:$C$86,$C$66:$C$86),0),0))

I do not see this being done without a helper column. In an unused column to the right of F66, put this array¹ formula.
=IF(AND(OR(C66=INDEX(C$66:C$86*(F$66:F$86="Partial Sold"), , )), F66="Closed"), D66/INDEX(D$66:D$86, AGGREGATE(15, 6, ROW($1:$21)/((C$66:C$86=C66)*(F$66:F$86="Partial Sold")), 1)), "")
Fill down as necessary. The result will be the sum of those 'helper' numbers.
        
Even if this could be done in a single formula, the calculation overhead would likely be prohibitive. Splitting a portion of the array calculations off to a helper column that can directly reference the value in column C for another lookup reduces this significantly.
¹ Array formulas need to be finalized with Ctrl+Shift+Enter↵. Once entered into the first cell correctly, they can be filled or copied down or right just like any other formula. Try and reduce your full-column references to ranges more closely representing the extents of your actual data. Array formulas chew up calculation cycles logarithmically so it is good practise to narrow the referenced ranges to a minimum. See Guidelines and examples of array formulas for more information.

Related

Sum of the greatest value in one column, plus the sum of the other values in another column

Consider the following sheet/table:
A B
1 90 71
2 40 25
3 60 16
4 110 13
5 87 82
I want to have a general formula in cell C1 that sums the greatest value in column A (which is 110), plus the sum of the other values in column B (which are 71, 25, 16 and 82). I would appreciate if the formula wasn't an array formula (as in requiring Ctrl + Shift + Enter). I don’t have Office 365, I have Excel 2019.
My attempt
Getting the greatest value in column A is easy, we use MAX(A1:A5).
So the formula I want in cell C1 should be something like:
=MAX(A1:A5) + SUM(array_of_values_to_be_summed)
Obtaining the values of the other rows in column B (what I called array_of_values_to_be_summed in the previous formula) is the hard part. I've read about using INDEX, MATCH, their combination, and obtaining arrays by using parenthesis and equal signs, and I've tried that, without success so far.
For example, I noticed that NOT((A1:A5 = MAX(A1:A5))) yields an array/list containing ones (or TRUEs) for the relative position of the rows to be summed, and containing a zero (or FALSE) for the relative position of the row to be omitted. Maybe this is useful, I couldn't find how.
Any ideas? Thanks.
Edit 1 (solution)
I managed to obtain what I wanted. I simply multiplied the array obtained with the NOT formula, by the range B1:B5. The final formula is:
=MAX(A1:A5) + SUM(NOT((A1:A5 = MAX(A1:A5))) * B1:B5)
Edit 2 (duplicate values)
I forgot to explain what the formula should do if there are duplicates in column A. In that case, the first term of my final formula (the term that has the MAX function) would be the one whose corresponding value in column B is smallest, and the value in column B of the other duplicates would be used in the second term (the one containing the SUM function).
For example, consider the following sheet/table:
A B
1 90 71
2 110 25
3 60 16
4 110 13
5 110 82
Based on the above table, the formula should yield 110 + (71 + 25 + 16 + 82) = 304.
Just to give context, the reason I want such a formula is because I’m writing a spreadsheet that automatically calculates the electric current rating of the short-circuit protective device of the feeder of a group of electric motors in a house or building or mall, as required by the article 430.62(A) of the US National Electrical Code. Column A is the current rating of the short-circuit protective device of the branch-circuit of each motors, and column B is the full-load current of each motor.
You can use this formula
=MAX(A1:A5)
+SUM(B1:B5)
-AGGREGATE(15,6,(B1:B5)/(A1:A5=MAX(A1:A5)),1)
Based on #Anupam Chand's hint for max-value-duplicates there could also be min-value-duplicates in column B for corresponding max-value-duplicates in column A. :) This formula would account for that
=SUM(B1:B5)
+(MAX(A1:A5)-AGGREGATE(15,6,(B1:B5)/(A1:A5=MAX(A1:A5)),1))
*SUMPRODUCT((A1:A5=MAX(A1:A5))*(B1:B5=AGGREGATE(15,6,(B1:B5)/(A1:A5=MAX(A1:A5)),1)))
Or with #Anupam Chand's shorter and better readable and overall better style :)
=SUM(B1:B5)
+(MAX(A1:A5)-MINIFS(B1:B5,A1:A5,MAX(A1:A5)))
*COUNTIFS(A1:A5,MAX(A1:A5),B1:B5,MINIFS(B1:B5,A1:A5,MAX(A1:A5)))
The explanation works for bot solutions:
The SUM-part just sums the whole list.
The second line gets the max-value for column A and the corresponding min-value of column B for the max-values in column A and adds or subtracts it respectively.
The third line counts, how many times the corresponding min-value for the max-value occurs and multiplies it with the second line.
Can you try this ?
=MAX(A1:A5)+SUM(B1:B5)-MINIFS(B1:B5,A1:A5,MAX(A1:A5))
What we're doing is adding the max of A to all rows of B and then subtracting the min value of B where A is the max.
If you have Excel 365 you can use the following LET-Formula
=LET(A,A1:A5,
B,B1:B5,
MaxA,MAX(A),
MinBExclude, MINIFS(B,A,MaxA),
sumB1,SUMPRODUCT(B*(A=MaxA)*(B<>MinBExclude)),
sumB2,SUMPRODUCT(B*(A<>MaxA)),
MaxA +sumB1+sumB2
A and B are shortcuts for the two ranges
MaxA returns the max value for A (110)
MinBExclude filters the values of column B by the MaxA-value (25, 13, 82) and returns the min-value of the filtered result (13)
sumB1 returns the sum of the other MaxA values from column B (26 + 82)
sumB2 returns the sum of the values from B where value in A <> MaxA (71 + 60)
and finally the result is returned
If you don't have Excel 365 you can add helper columns for MaxA, MinBExclude, sumB1 and sumB2 and the final result

Sumif of multiple Index matches against one value

Need help regarding Excel dynamically search based sum of two columns matching from two different tables.
I have got this Table of Data Entered One Time
A B C
1 Qlty Warp Weft
2 Stpl.1 150 20
3 Cotn.1 80 60
4 Stpl.2 20 20
5 Cotn.2 20 20
6 Stpl.3 20 40
in Column A2:A6, Quality can not be duplicated, its a unique Name
The Data entry and report Table is here
A B C D E F
8 Yarn Name Sent Bags Remaining Qualty Used Warp Used Weft
9 20 800 600 Stpl.1 71 200
10 150 101 30 Stpl.2 70 30
11 40 300 290 Stpl.3 100 10
12 20 400
C9:C5000 is Returning Column, Values are calculated on the base of Column A9:A5000 (Yarn Name)
Need to Find Yarn Name (eg:) "20" in B2:B6 AND/OR C2:C6, wherever it matches, index that Quality from A2:A6
Then match the returned qualities(could be more than one) to D9:D5000 and sum the mathced results from E9:F5000
I have tried so far in C12
=SUMIF($A$9:$A12,A12,$B$9:$B12)-(SUMIF($D$9:$D12,INDEX($A$2:$A$6,MATCH(A12,$B$2:$B$6,0)),$D$9:$D12)+SUMIF($D$9:$D12,INDEX($A$2:$A$6,MATCH(A12,$C$2:$C$6,0)),$D$9:$D12))
PS:- I am using Excel 2007
If I understand correctly, then following array formula can help you:
=SUM(IFERROR(INDEX($A$2:$A$6,N(IF(1,(MMULT(--($B$2:$C$6=A9),TRANSPOSE(COLUMN($B$2:$C$6)^0))>0)*(ROW($B$2:$C$6))-1)))=TRANSPOSE($D$9:$D$12),0)*TRANSPOSE($E$9:$E$12+$F$9:$F$12))
Array formula after editing is confirmed by pressing ctrl + shift + enter
Edit:
To calculate Warp and Weft columns separately use following array formula:
=SUM(IFERROR(INDEX($A$2:$A$6,N(IF(1,((A9=$B$2:$B$6)*ROW($B$2:$B$6))-1)))=TRANSPOSE($D$9:$D$12),0)*TRANSPOSE($E$9:$E$12))+SUM(IFERROR(INDEX($A$2:$A$6,N(IF(1,((A9=$C$2:$C$6)*ROW($C$2:$C$6))-1)))=TRANSPOSE($D$9:$D$12),0)*TRANSPOSE($F$9:$F$12))

Create a list of values from a table of values and exclude certain values

I have the following Excel spreadsheet:
A B C D E F G
1 Q1 Q2 Q3 Q4 Positive values
2 Asset 1 -50 85 -90 70 85
3 Asset 2 -28 -80 -45 60 70
4 Asset 3 -30 50 55 -10 60
5 Asset 4 -20 5 -80 -15 :
6 Asset 5 35 -30 27 -98 :
7
In Cells A1:E6 I have different assets with their performance from quarter Q1-Q4.
In Column F I create a list of all postive performances of the assets using the formula from here:
Column F = {LARGE(IF($B$2:$E$6>0,B$2:$E$6),ROW(B1:E1))}
All this works fine so far.
However, now I want to exclude certain values from the list in Column F. For example I do not want that number 85 or number 70 appear in the list. Therefore, I tried to modify the formula to:
Column F = {LARGE(IF(AND($B$2:$E$6>0,$B$2:$E$6<>85,$B$2:$E$6<>70),B$2:$E$6),ROW(B1:E1))}
However, now I get 0 as result.
Do you have any idea of a formula that could solve this issue?
Create an array of 0's where 0 is equivalent to a negative number or the excluded values
($B$2:$E$6>0)*($B$2:$E$6<>85)*($B$2:$E$6<>70)
1/(… will convert that to 1's and errors
Multiply by the original to create an array of original values and errors
=1/(($B$2:$E$6>0)*($B$2:$E$6<>85)*($B$2:$E$6<>70)) * B2:E6
Use the aggregate function to get the results you want
=AGGREGATE(14,6,1/(($B$2:$E$6>0)*($B$2:$E$6<>85)*($B$2:$E$6<>70))*$B$2:$E$6,ROWS($1:1))
Fill down to get the 2nd, 3rd, etc largest
You are on the right path. Instead of using AND, a nested IF would work.
You need to create a new IF criteria for every new condition you want to test.
So if you want to exclude 85 and 70 you need to add two additional IF statements.
Formula for Column F would be:
={LARGE(IF($B$2:$E$6>0,IF($B$2:$E$6<>85,IF($B$2:$E$6<>70,B$2:$E$6))),ROW(B1:E1))}
You can read here how the formula process is: Minimum if multiple criteria
If you have data in column F and you want to extract all values that are not 70 or 85 into column G, then in G2 enter:
=IFERROR(INDEX(F$2:F$9999, AGGREGATE(15, 6, ROW($1:$999)/((F$2:F$9999<>85)*(F$2:F$9999<>70)), ROW(1:1))),"")
and copy downwards:
Note that this approach does not require the use of an array formula.

Need excel formula to prescribe which 6 of 8 cells to use for average

How can I prescribe which 6 of 8 cells excel uses to make an average?
e.g.:
A1 Art 86
A2 English 88
A3 Law 89
A4 Chemistry 83
A5 Biology 81
A6 Math 1 87
A7 Math 2 67
A8 PhysEd 72
e.g. Average 1 is A1:A6 / 6
e.g. Average 2 is [top 6 highest] / 6
e.g. Average 3 is Chemistry, English and the next top 4 highest / 6
I want to define the list where Average 1 = A1:A6/6, Average 2 = ?, Average 3 = ?
I assume the course descriptions are in column A and the scores are in column B and not Column A
B1:B6 =AVERAGE(B1:B6)
Top 6 =AVERAGE(LARGE(B1:B8,{1,2,3,4,5,6}))
Chemistry + English + top 4
=(SUM(SUMIF(A1:A8,{"Chemistry","English"},B1:B8))+SUM(LARGE((A1:A8<>"Chemistry")*(A1:A8<>"English")*B1:B8,{1,2,3,4})))/6
This last is an array formula and must be entered by holding down Ctrl + Shift while holding down Enter
A longer formula with the same result, but which can be normally entered:
=(SUM(AGGREGATE(14,4,((A1:A8="Chemistry")+(A1:A8="English"))*B1:B8,{1,2}))+SUM(AGGREGATE(14,4,(A1:A8<>"Chemistry")*(A1:A8<>"English")*B1:B8,{1,2,3,4})))/6
For #2, You can use Rank() to identify the top 6, then AverageIf() to average those <=6.
For #3, give Chem & English a value of 1, then use Rank() on the remaining 6 items. Then AverageIf() <=4. This is where it helps to put Chem & English at the top of the list.
Here's an example file showing this:
Click here for the file
Anyway, that's ONE way to solve it... hope it helps!

Find what range a number belongs to

Ive written a function to calculate what MARK a student gets, based on a scoring table.
Why does my function work only for A mark?
This what the excel sheet looks like
COLUMN: A B C
Student SCORE MARK
1 adsf 90 A
2 asgfd 89 FALSE
3 A 90 100
4 B 81 89
5 C 71 80
6 D 61 70
7 E 56 60
8 Fx 0 55
This is the function:
{=IF(B1>=$B$3:$B$8,IF(B1<=$C$3:$C$8,$A$3:$A$8))}
I'm using {} brackets for array functions. (CTRL SHIFT ENTER)
Thank you
You're on the right track but your formula is returning an array not a single value. Wrapping the result in LOOKUP should give the desired result:
=LOOKUP("Z",IF(B1>=$B$3:$B$8,IF(B1<=$C$3:$C$8,$A$3:$A$8))
This returns the last matching grade since "Z" is larger than any other text value in the range.
A simpler method is:
=LOOKUP(-B1,-C$3:C$8,A$3:A$8)
The negative signs are needed so that the lookup values are in ascending order.

Resources