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)))
The following works as expected and counts all the cells in the range A2:P2 that contains either PH, V or O.
=SUM(COUNTIFS(A2:P2;{"PH";"V";"O"}))
I have to reuse this several places and therefore want to place the criteria array in a cell and read it from there. Something like:
=SUM(COUNTIFS(A2:P2;"&A1&")) where cell A1 contains {"PH";"V";"O"}.
Is it possible to parse the text from A1 into the formula?
Assuming that you're using Excel 2013 or later, and that A1 contains the text PH;V;O the formula below should work
=SUM(COUNTIFS(A2:P2;FILTERXML("<c><e>"&SUBSTITUTE(A1;";";"</e><e>")&"</e></c>";"//e")))
(this will have to be entered as an array formula if you don't have dynamic arrays)
A certain cell is part of a range containing an array formula (created using CTRL-SHIFT-ENTER). Other than my brute force method of visually examining the formula in the certain cell, does Excel have a command that will highlight the range of cells which contain the array formula? For instance, assume C10 has the following array formula ={TRANSPOSE(myarray)}, how can I ask Excel to highlight the range of cells that will receive the contents of the transposed "myarray"?
This feels like a Excel 101 question but my search has been futile.
If there is no "junk" below the array formula, something like:
=COUNTA(C10:C9999)
Let's say I have in B2 the formula =ROW(A1:A3). This formula gives an array of {1;2;3}. Because a cell only holds one value, cell B2 displays a value of 1. Any place in the worksheet, the formula =B2 gives 1, not the array. Yet, Excel still remembers the array because the formula is still in B2.
Is there any way to get the array back so it, the whole array, not its individual elements, can be used for further manipulation? I'm looking for something like OPERATION(B2) = {1;2;3}. For example, SUMPRODUCT(OPERATION(B2)) = SUMPRODUCT(ROW(A1:A3)) = 6.
As a workaround, you can store your formula in Name Manager, e.g.:
Then you can use it as a reference in Excel formulas, like =INDEX(Rows,2,1):
I realize that this is not the answer to the OP's question as they do not have the latest Office 365. I put this here for those who come later and do have it.
With the latest Office 365 with Dynamic array formulas this problem is now gone.
Putting =ROW(1:3) or the equivalent dynamic array formula =SEQUENCE(3) Excel will spill the array down automatically without the need of Ctrl-Shift-Enter:
And now one can refer to the array by only refering to A1 by putting # after the reference:
=SUM(A1#)
Then no matter how the array in A1 changes the other formula does not need to be changed.
The caveat is that the formula in A1 needs the room to spill down. If there is a cell that has anything in it that resides in the spill down array it will return an error.
Just to try and clarify this, arrays in Excel before the September 2018 update for Office 365 don't self-expand like they do in Google sheets, so if you put an array into a single cell you just get the first element of the array (see column A for example).
If you want to enter the array directly into the sheet, you have to select the cells you want it to occupy (say B2:B4) and enter it as an array formula (see column B) using CtrlShiftEnter
You can still use the array in another formula as long as it's expecting an array - e.g. with sumproduct you get the correct total, 6 (see column C).
=SUMPRODUCT(ROW(A1:A3))
Unfortunately this doesn't always work without entering the whole formula as an array formula (see column D).
=SUM(ROW(A1:A3))
EDIT
#JvDV is correct, you don't always get the first element of an array expression entered into a single cell - see this reference for explanation of the implicit intersection mechanism.
I have two methods, which might qualify as solutions or workarounds, depending on what technology you're willing to accept.
Both rely on retrieving the formula that produces the array from B2 and then evaluating that formula each time you invoke your OPERATION(B2).
Method 1: VBA
Create a UDF:
Function Arr(R as Range)
Arr = Application.Evaluate(R.Formula)
End Function
which you then invoke in a cell, e.g. =SUM(Arr(B2)).
Method 2: Name Manager + EVALUATE()
Note that this is different from Justyna's answer. The idea is to allow you to specify the address of the cell holding the array-generating formula.
Create a name that holds =EVALUATE(FORMULATEXT(INDIRECT(INDEX($1:$1048576;ROW();COLUMN()+1)))). This way you can specify that you want the content of the cell B2 by writing the string B2 to the nearest cell to the right of the cell in which you're using your newly created name.
Unfortunately, EVALUATE() cannot be used within a cell.
I would prefer to use an excel array formula (but if it can only be done in VBA, so be it) that copies ALL cells from a column array that contains specific text. The picture below shows what I am after and what I have tried. I'm getting close (thanks to similar, but different questions) but can't quite get to where I want. At the moment, I am getting only the first cell instead of all the cells. In my actual application, I am searching through about 20,000 cells and will have a few hundred search terms. I expect most search terms to give me about 8 - 12 cells with that value.
formula I am using:
=INDEX($A$4:$A$10,MATCH(FALSE,ISERROR(SEARCH($C$1,$A$4:$A$10)),0))
Spredsheet Image
To make this work efficiently, I recommend having a separate cell holding the results count (I used cell C2) which has this formula:
=COUNTIF(A:A,"*"&C1&"*")
Then in cell C4 and copied down use this array formula (The -3 is just because the header row is row 3. If the header row was row 1, it would be -1):
=IF(ROW(A1)>$C$2,"",INDEX($A$4:$A$21000,SMALL(IF(ISNUMBER(SEARCH($C$1,$A$4:$A$21000)),ROW($A$4:$A$21000)-3),ROW(C1))))
I tested this with 21000 rows of data in column A with an average of 30 results per search string and the formula is copied down for 60 cells in column C. With that much data, this takes about 1-2 seconds to finish recalculating. Recalculation time can vary widely depending on other factors in your workbook (additional formulas, nested dependencies, use of volatile functions, etc) as well as your hardware.
Alternately, you could just use the built-in Filter functionality, but I hope this helps.
You need to get the ROWS. Put this in C4 and copy down.
=IFERROR(AGGREGATE(15,6, IF(SEARCH($C$1, $A$4:$A$10)>0, ROW($A$4:$A$10)), ROW($C4)-ROW($A$4)+1), "")
Array formula so use ctrl-shift-Enter