Sum the results of vlookups across multiple columns - arrays

I'm trying to avoid repetition. The following formula works:
=IFERROR(VLOOKUP($C3,'Business Goals'!$A$3:$C$8,3),0)+
IFERROR(VLOOKUP($D3,'Business Goals'!$A$3:$C$8,3),0)+
IFERROR(VLOOKUP($E3,'Business Goals'!$A$3:$C$8,3),0)+
IFERROR(VLOOKUP($F3,'Business Goals'!$A$3:$C$8,3),0)+
IFERROR(VLOOKUP($G3,'Business Goals'!$A$3:$C$8,3),0)+
IFERROR(VLOOKUP($H3,'Business Goals'!$A$3:$C$8,3),0)
Essentially I want to sum up columns C:H, and the values I want to sum are all stored within the same lookup table.
For my own sanity, if you're providing an answer and it doesn't REQUIRE INDEX/MATCH please express your answer using VLOOKUP.

You can use array formulas to achieve this (see caveat below):
=SUM(('Business Goals'!$A$3:$A$8=$C3:$H3)*'Business Goals'!$C$3:$C$8)
This uses the fact that in arithmetic operations, (x=y) evaluates to 1 if true or 0 otherwise. ('Business Goals'!$A$3:$A$8=$C3:$H3) creates a rectangular array which is like a lookup table with a 1 where the values in $C3:$H3 match those in 'Business Goals'!$A$3:$A$8. That is then multiplied by the corresponding values in 'Business Goals'!$C$3:$C$8 and finally the whole lot is summed over.
Remember to paste the formula into the formula bar and then press Ctrl+Shift+Enter otherwise it won't be recognised as an array formula.
This works provided you wanted the "exact match" form of VLOOKUP (e.g. VLOOKUP(A1,B2:G30,FALSE)) which returns an error if it can't find the data, rather than the default approximate match which you have. That assumes a sorted list and returns the next largest row if it can't find an exact match. I don't think there is a neat way of doing it if you need the approximate match.

Related

Dynamic Spill Formula For Reduce Function Mixed With Split

My sample sheet is probably easier to understand than my writing but here's the issue: I have a sheet that I'm trying to create a spill formula that sums an array of numbers up in each line.
Columns B:D is my existing data that's being evaluated
If values exist in Column D (which is not always the case), split values (defined by , ) and lookup each one's most recent entry (column B) and sum its value from column C with other members in same cell.
I can accomplish this using the Reduce formula shown in my sample data in blue column F, and dragging the formula to the latest entry, however it will not spill down dynamically.
=iferror(REDUCE(0,SPLIT(D2,",",false),lambda(total,value,xlookup(value,B:B,C:C,"",0,-1)+total)),0)
I can get the C values to spill down dynamically (as shown in green columns in sample) as numeric values, but I can't figure out how to sum them.
=Filter(iferror(XLOOKUP(SPLIT(D2:D,", ",false),B:B,C:C,"",0,-1),0),A2:A>0)
I would have expected something like either of these to work, but both generate a #N/A
=Filter(iferror(REDUCE(0,SPLIT(D2:D,", ",false),
lambda(total,value,xlookup(value,B:B,C:C,"",0,-1)+total)),0),A2:A>0)
=Filter(sum(iferror(XLOOKUP(SPLIT(D2:D,", ",false),B:B,C:C,"",0,-1),0)),A2:A>0)
I've also tried these as named functions with only the spilled variables as input, but same result.
I know the reduce function can perform a spilled range, as shown here on Ben Collins' site, however I can't figure out how to get it to do so with my dataset. It's occurred to me that because I'm generating a horizontal array, a verticle array may not be possible?
Any helpful answers will be upvoted if not accepted. Thanks.
Here's one approach:
=byrow(index(map(iferror(split(D2:index(D:D,match(2,1/(D:D<>""))),", ",0,1)),lambda(z,xlookup(z,B:B,C:C,)))),lambda(y,sum(y)))
To have your formula spill down you can use MAP or BYROW:
Your formula:
=iferror(REDUCE(0,SPLIT(D2,", ",false),lambda(total,value,xlookup(value,B:B,C:C,"",0,-1)+total)),0)
With MAP:
=MAP(D2:D7,LAMBDA(ζ,iferror(REDUCE(0,SPLIT(ζ,", ",false),lambda(total,value,xlookup(value,B:B,C:C,"",0,-1)+total)),0)))
Here's another solution using FILTER:
=MAP(D2:INDEX(D:D,MAX(ROW(D:D)*(D:D<>""))),LAMBDA(ζ,IFNA(SUM(FILTER(C:C,COUNTIF(SPLIT(ζ,", ",),B:B))),0)))

Using Index/Max/If to find multiple values in array and get for highest corresponding value result displayed

I am currently trying to use some excel formulas like "Index"/"Max"/"If" with multiple criteria. This means I want to lookup all values in A2:I2 and search them in my second table in A8:A20. At the same time I want to lookup the maximum in C8:C20 and for the entry that
1) matches A2:A20 and 2) has the highest value in C2:C20 I want to get the value of the "Result" column be displayed in I7, which is "D".
After trying multiple variations with Index/Vlookup/Max/If etc. I cannot find any formula for this problem to handle multiple matching criteria within arrays.
Perhaps is there any VBA solution to loop through both tables and get the result displayed below?
P.S. As this is only a small part of my worksheet it is not efficient to use one Index formula for each cell trying to match my second table. It would be great to work with two arrays matching each others values.
Using your provided sample, in result cell I7 use this formula: =MAX(INDEX((A8:A20=A2:I2)*C8:C20,))

Index/Match with three criteria

I have searched and searched and searched and searched, I can only find solutions for index/match with two criteria.
does anyone have a solution for index/match with three criteria?
as a sample of my actual data, i would like to index/match the year, type and name to find the data in the month column
You can match an unlimited number of criteria by using SUMPRODUCT() to find the proper row:
=INDEX(D2:D9,SUMPRODUCT((A2:A9=2015)*(B2:B9="Revenue")*(C2:C9="Name 1")*ROW(2:9))-1)
EDIT#1:
Scott's comment is correct! The advantagesof the SUMPRODUCT() approach is that it is not an array formula and can be expanded to handle many criteria. The disadvantage is that it will only work if there is 1 matching row. The use of SUMPRODUCT() is explained very well here:
xlDynamic Paper
Because your question has numerical data, you can simply use SUMIFS.
SUMIFS provides the sum from a particular range [column D in this case], where any number of other ranges of the same size [the other columns, in this case] each match a particular criteria. For text results, one of the other recommended solutions will be needed.
In addition to being a little cleaner, this has the attribute [could be good or bad depending on your needs] that it will pick up multiple rows of data if multiples exist, and sum them all. If you expect unique rows, that's bad, because it won't warn you there are multiples.
The formula in your case would be as follows [obviously, you should adjust the formulas to reference your ID cells, and pick up the appropriate columns]:
=SUMIFS(D:D,A:A,2015,B:B,"Revenue",C:C,"Name1"))
What this does is:
Sum column D, for each row where: (1) column A is the number 2015; (2) column B is the text "Revenue"; AND (3) column C is the word "Name1".
If assuming your data starts in A1 ("Year") and goes to D15 ("????"), you can use this. You bascically just add your criteria with &, then when doing the Match() regions, connect their respective ranges with & as well.
=Index(D2:D9,Match(A15&B15&C15,A2:A9&B2:B9&C2:C9,0))
and enter with CTRL+SHIFT+ENTER and make the references absolute (i.e. $D$2:$D$9), I just didn't to keep the formula a little easier to read.

Change array dimensions, using spreadsheet functions, when used inside SUMPRODUCT

I am interested in spreadsheet functions, not VBA solutions, to be included in a single cell formula.
[A1:A15 contain numeric values from 1 to 127, B1:B15 contain integers from 1 to 7 that set a divisor.]
Given the function:
=SUMPRODUCT(MOD(FREQUENCY(A1:A15;A1:A15);B1:B15))
FREQUENCY(A1:A15;A1:A15) gives a 1-column array of 15+1 rows, whereas the second part (B1:B15) is a 1-column array of 15 rows.
I would like to change the resulting array given by FREQUENCY (only in memory -not explicit in sheet-) from a 1-column 16 rows array to a 1-column 15 rows array with the first 15 cell values of that array.
[FREQUENCY documentation: https://support.office.com/en-us/article/FREQUENCY-function-44e3be2b-eca0-42cd-a3f7-fd9ea898fdb9 NB: for Excel, second remark states number of elements that depend on bins_array. ]
I would appreciate suggestions.
Thus, both arrays within MOD will have the same dimensions and SUMPRODUCT will not find cells with error values. I can disregard error values using IF and ISERROR within SUMPRODUCT, but I'd rather disregard the non-relevant part of the FREQUENCY resulting array if it is possible.
It has been thought that making it more specific might be more helpful, so it has been heavily reduced and simplified.
With external help, I have been able to fine-tune a way to solve my problem using INDEX in array formula mode. I am posting the answer in case it helps others.
One way: Put FREQUENCY(A1:A15;A1:A15), or any formula that produces an multi-cell array, within INDEX and have 2nd and/or 3rd arguments as array of consecutive values which will represent rows/columns.
INDEX(FREQUENCY(A1:A15;A1:A15);ROW(INDIRECT("1:" & ROWS(FREQUENCY(A1:A15;A1:A15)-1));1)
First argument within INDEX is the resulting array coming from a formula to shrink (from 16x1 to 15x1), which would be a multi-cell array formula if explicitly entered; second argument is the array 1..15 given by row numbers from 1 to the number of total rows of the "array from formula to shrink" MINUS 1: the first 15 (out of 16) values in the array from a formula; 3rd argument is the column of the shrank array (if need be, more than one could be selected using an analogue to the second argument).
In the particular case of FREQUENCY, because it is known that we are interested in the "bins" part of the function, the formula can be simplified by including the total rows of the "bins"/"intervals" array inside FREQUENCY (its second argument). We will have
INDEX(FREQUENCY(A1:A15;A1:A15);ROW(INDIRECT("1:" & ROWS(A1:A15)));1)
and the complete formula would become
SUMPRODUCT(MOD(INDEX(FREQUENCY(A1:A15;A1:A15);ROW(INDIRECT("1:" & ROWS(A1:A15)));1);B1:B15))
Now, both dividend and divisor of MOD have exactly the same dimensions (15x1) and because B1:B15 includes integers greater than 0 there are no errors.
Thanks all for helping me in making question more concise and better formatted.
ADDITIONAL INFORMATION: As pointed out correctly in comments by XOR LX, this does not seem to work in the widely popular spreadsheet software Excel. It has been developed for an INDEX function inside SUMPRODUCT as used in Open Office Calc which I had mistakenly thought 100% equivalent to Excel's version. A more complete answer perhaps using other functions would be appreciated.
In the previous answer, XOR LX points out very correctly that this formula cannot work in Excel, due to row_num/column_num argument behaviour. Very kindly XOR LX has shown me how that approach can work, and also thanks and credit for supplying a good answer: "INDEX can be used to redimension array (even dynamically created ones) if the row_num/column_num array is coerced to take an arbitrary array with the right dimensions, as shown on this blog entry " The following formula has been checked in Excel 2010 and has the expected results:
SUMPRODUCT(MOD(INDEX(FREQUENCY(A1:A15,A1:A15),N(INDEX(ROW(INDIRECT("1:" & ROWS(A1:A15))),,)),1),B1:B15))
NB: row_num argument of first INDEX, a ROW generated auxiliary array, has been nested inside N(INDEX([...],,)); at least one comma is necessary to account for the two arguments minimum of the nested INDEX. It is in itself interesting the discussion that applies generally to INDEX's arguments, and other functions', that need to be coerced to take arrays (see, here and here at XOR LX's blog). For Open Office users it might be worth stressing the point made at the blog
Unlike OFFSET, (...) for which the first parameter must be a
reference (...) in the worksheet, INDEX can also accept –
and manipulate – for its reference arrays which consist of values
generated e.g. via other subfunctions within the formula. XOR LX's blog
That would be indeed the case in changing the dimension in an array as in this question, but also useful in reversing or displacing the values in an array, for example. Open Office accepts arrays as row_num/column_num, so the coercion is not needed and some formulas rely on this, but without it, these formulas are unlikely to work when files are open in Excel.
Regrettably, this type of coercion is not passed correctly to Open Office, and formula need to be "decoerced" to work, at least in my casual tests.
In order to use a formula that would work in both spreadsheet programs regarding shortening arrays, the only thing I have managed is the following (required: arrays must be single-column)
SUMPRODUCT(
(COLUMN(INDIRECT("R1C1:R"& ROWS(vals_to_mod) &"C"& ROWS(FREQUENCY(vals_for_freq,vals_for_freq)),FALSE))
-ROW(COLUMN(INDIRECT("R1C1:R"& ROWS(vals_to_mod) &"C"& ROWS(FREQUENCY(vals_for_freq,vals_for_freq)),FALSE))
=0)
*MOD(TRANSPOSE(FREQUENCY(vals_for_freq,vals_for_freq)),vals_to_mod)
)
(it "shortens" one array to the shortest of the pair, by creating an auxiliary array with TRUE/1s on the diagonal starting top-left and FALSE/0s elsewhere, therefore disregarding all defined values outside the square section of the array. Thus, SUMPRODUCT adds values within the diagonal of the square section which are the product of the corresponding values up to the last value of the shorter array.)

Use set of keywords to extract values from second worksheet

I'll try to explain the problem I'm facing best as I can.
A have a set of data that contains multiple duplicates extracted as an excel file. Within this data are "keys" that I want to use to filter out relevant data from another workbook.
I start by removing duplicates from the list of keywords and I think I got this working kind of satisfactory. I then try to extract and calculate the minimum from the values using the following array formula:
=MIN(VLOOKUP(Blad1!D2:D8,Blad2!A3:D9,2))
However, this doesn't work as expected. The value returns the minimum value from the target range, but seems to ignore the provided keywords. Instead it simply finds the minimum value of the entire range.
I am far from a professional when it comes to excel so any suggestions on how this could be done in a more efficient way are welcome.
Here is a link to a sample document.
These array formulas should be what you need.
'MINIF in F2,
=MIN(IF(COUNTIF($D$2:$D$8, Blad2!$A$2:$A$9&""), Blad2!$B$2:$B$9))
'MAXIF in G2
=MAX(IF(COUNTIF($D$2:$D$8, Blad2!$A$2:$A$9&""), Blad2!$C$2:$C$9))
'AVERAGEIF¹ in H2
=AVERAGE(IF(COUNTIF($D$2:$D$8, Blad2!$A$2:$A$9&""), Blad2!$D$2:$D$9))
Array formulas need to be finalized with Ctrl+Shift+Enter↵.
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.
The results are 15, 35 and 23.6.
¹Note that this is NOT the native AVERAGEIF function or AVERAGEIFS function but an array formula. This approach was chosen due to the large number of criteria.

Resources