Return array from INDEX function in Excel? - excel

I'm trying to use INDEX in array format in Excel but I'm running into problems.
From this question: Return array from INDEX function?, it seems that "INDEX (like VLOOKUP) doesn't return an array of values (except in some convoluted circumstances)"
So I'm wondering what alternatives there are.
I'm trying to do this:
=qlTimeSeries( ,
INDEX({39618,39619,39638,39639},{2,3,4}),
INDEX({18,19,38,39},{2,3,4})
)
and Index is not returning an array.
Any alternative idea how to get the result I am trying to get with INDEX({39618,39619,39638,39639},{2,3,4})?
i.e. from {39618,39619,39638,39639} get {39619,39638,39639} back?
NOTE: Instead of INDEX({39618,39619,39638,39639},{2,3,4}) my spreadsheet in fact uses a dynamic array of dates and the objective is to drop the first element of the array {39618,39619,39638,39639} which is why I am using INDEX.
EDIT: Looking for a solution that avoids using VBA

Try this array formula:
= INDEX({39618,39619,39638,39639},N(IF({1},{2,3,4})))
This will return what you desire: {39619,39638,39639}.
Note this is an array formula, so you must press Ctrl+Shift+Enter on the keyboard after typing this formula instead of just pressing Enter.
(Also note this works with dynamic ranges, not just hard-coded arrays.)

Related

How can I remove 0s from an array within an INDEX formula?

I'm writing a bit of a complicated INDEX formula here and I'm really close to the solution.
The INDEX below matches the row of the array based on two criteria
and the column based on a string elsewhere.
I'm using the ROW function to simulate a MATCH function to pass to the INDEX,
and N(IF()) to de-reference the INDEX function and pass an array of values to
the MIN function.
I'm using ROW instead of MATCH because MATCH(1,,) would only return the
first value of 6 TRUE that result from the two criteria.
It all works except for one issue: the array I pass to INDEX after N(IF(1,ROW())) still has a bunch of 0s. For example, it gets "{0,0,0,0,22,23,24,0,0)" so INDEX passes "{54,54,54,54,87,91,78,54,54}" to the MIN function.
Hence my issue. I feel like I'm really close to the answer but I've gotten stuck. If I could somehow remove the 0s from the array so that only "{22,23,24}" gets passed to INDEX, then everything would work in my sheet.
=IF($H$9="","",
MIN(INDEX($A$9:$Z$5000,
N(IF(1,ROW($A$1:$A$4991)*(M$3=$H$9:$H$5000)*($X$6=$A$9:$A$5000))),
MATCH($H4&CHAR(10)&CHAR(10)&CHAR(10)&$V$3&CHAR(10)&"(lbs)",$A$8:$Z$8,0))))
Instead of building an array just use MIN(IF())
=IF($H$9="","",MIN(IF((M$3=$H$9:$H$5000)*($X$6=$A$9:$A$5000)*(INDEX($A$9:$Z$5000,0,MATCH($H4&CHAR(10)&CHAR(10)&CHAR(10)&$V$3&CHAR(10)&"(lbs)",$A$8:$Z$8,0))<>0),INDEX($A$9:$Z$5000,0,MATCH($H4&CHAR(10)&CHAR(10)&CHAR(10)&$V$3&CHAR(10)&"(lbs)",$A$8:$Z$8,0)))))
This is an array formula and must be confirmed with Ctrl-Shift-Enter instead of Enter when Exiting Edit Mode.
It is even simpler with Office 365:
=IF($H$9="","",MINIFS(INDEX(A:Z,0,MATCH($H4&CHAR(10)&CHAR(10)&CHAR(10)&$V$3&CHAR(10)&"(lbs)",$8:$8,0)),INDEX(A:Z,0,MATCH($H4&CHAR(10)&CHAR(10)&CHAR(10)&$V$3&CHAR(10)&"(lbs)",$8:$8,0)),"<>0",$H:$H,$M$3,$A:$A,$X$6))

Finding a value from array in File Path [Excel]

I have a little problem with Excel.
I'm trying to compare if one of several specific words occur in a path.
This is what I do with the following function:
=IF(ISERROR(SEARCH($C$2:$C$4,A2)),"NO","YES")
However, the result is always "No".
Example data:
Does anyone have an idea?
SEARCH($C$2:$C$4,A2)
will return an array of a number or a #VALUE! errors.
If you wrap that in ISNUMBER it will return an array of TRUE;FALSE...
To see if ANY of the values are TRUE, wrap that in an OR and use that in your IF statement.
Of course, since this is an array formula, you have to enter it by holding down ctrl + shift while hitting Enter
=IF(OR(ISNUMBER(SEARCH($C$2:$C$4,A2))),"Yes","No")
You can see what is happening by using the Formula Evaluation tool
You can use SUMPRODUCT with ISNUMBER and SEARCH
=IF(SUMPRODUCT(--ISNUMBER(SEARCH(C2:C4,A2)))>0,"YES","NO")

Which built-in excel functions treat ranges as arrays?

For example =SUMPRODUCT(A2:A10-10) does, but =SUM(A2:A10-10) does not. Specifically in my situation I wish =MEDIAN(ABS(A2:A10-MEDIAN(A2:A10))) did; however sadly it does not, and if I knew which built in functions convert the ranges into arrays before they evaluate then I might be able to reformulate something that gives me what I'm looking for...
there are some natural array type formulas like SUMPRODUCT and some of the options in AGGREGATE, as well as some financial functions.
Many can be "forced" into array mode by simply using Ctrl-Shift-Enter instead of Enter when exiting edit mode.
For example your formula:
=MEDIAN(ABS(A2:A10-MEDIAN(A2:A10)))
If it is confirmed with Ctrl-Shift-Enter instead of Enter when exiting edit mode will "Force" the Array. If done correctly the Excel will put {} around the formula.
The INDEX function has an Array Form.
=SUM(INDEX((A2:A10)-10, , ))
In the above, INDEX is returning an array of values but a wrapping SUM is required to collect a total. The blank parameters represent all rows and all columns in the range (e.g. A2:A10) specified. All rows and all columns in the range can also be represented with zeroes in place of the blank parameters.
With 2 to 10 in A2:A10, your MEDIAN example would return 14 from,
=MEDIAN(INDEX(ABS((A2:A10)-MEDIAN(A2-A10)), , ))
(without CSE)
Use the Evaluate Formula command to see more of the inner workings of this style of INDEX use.

Using SUMPRODUCT and OFFSET on multiple rows in Excel

I have a question on using OFFSET in Excel.
For instance, I have a table with values varying by years.
Then, I have a table with some values varying by year/months.
!!Click here for the tables!!
I would like to write a formula e.g.
=SUMPRODUCT((E2:E37)*OFFSET(A1,C2:C37,1),E2:E37)
but it returns #VALUE!
In short, I would like to use an array of values in C2:C37 i.e. {1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3} to obtain the array {0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.04,0.04,0.04,0.04,0.04,0.04,0.04,0.04,0.04,0.04,0.04,0.04,0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05,}, and this array is then used in the SUMPRODUCT function.
Can someone help me solve the #VALUE! issue?
Thanks in advance!
Apparently (I didn't know this) Offset is unusual because it can return a set of range objects when used with an array as the second argument. Most functions can't handle this if you pass it to them. But if you put it through the N function, you get the right answer.
=SUMPRODUCT((E2:E37)*N(OFFSET(A1,C2:C37,1)))
or
=SUMPRODUCT((E2:E37),N(OFFSET(A1,C2:C37,1)))
Note that these appear to give an array of #Value! errors when you run them through Evaluate Formula but these resolve after passing through the N function.
Of course it would be more common to do this the easy way and use Index or Vlookup with a helper column. My first thought when trying to do it in a single Array formula without using Offset was this:-
=SUM(E2:E37*MMULT(N(C2:C37=TRANSPOSE((ROW(A2:A4)-1))),B2:B4))
I would think that the Offset way is easier and more efficient.
But in this particular case where there are only a small number of categories you could use this array formula which is perhaps the simplest approach:-
=SUM(CHOOSE(C2:C37+1,0,B2,B3,B4)*E2:E37)
The above formulae only work for the special case where the 'key' is the same as the row number in the lookup column. The offset method can easily be adapted to incorporate a lookup:-
=SUM((E2:E37)*N(OFFSET(A1,IFERROR(MATCH(C2:C37,A2:A4,0),0),1)))
See this reference

Does Excel have any map or select functions?

I have a row of string values, which I'd like to do a vlookup on each and then compute the average of the results. If this were C#, I'd do a Select( str => VLookup(str,dict)).Average(), is there a way to do this in a single excel function?
I'm using version 2010
In general, no. For your specific case, kind of.
Say you have a table like this
a 42
b 2
c 3
in E8:F10. If you call VLOOKUP with an array like this:
=VLOOKUP({"a","c"},E8:F10,2,FALSE)
you'll get back an array of values: {42,3}. (Enter the formula as an array function...Ctrl+Shift+Enter.) So the map part you can do in this case.
Unfortunately, AVERAGE doesn't seem to work with the array that VLOOKUP returns if you put it all in one formula and put the result in one cell. Worse, it appears to work, but just uses the first element, even if you enter the whole thing as an array formula. That is, if you put:
=AVERAGE(VLOOKUP({"a","c"},E8:F10,2,FALSE))
in cell H12, even if you enter it as an array formula, you'll get back 42 and not 22.5.
Oddly, putting the same formula in two cells, say H16:I16, and entering it as an array formula gives you back an array with two elements: {22.5, 22.5}. (It's probbaly just a one-element array getting expanded into two cells.) So you can get what you need without having to have a whole large intermediate array of results. (Using arrays in place of non-array arguments to worksheet functions can be wierd. See: Is there any documentation of the behavior of built-in Excel functions called with array arguments? )
Of course, the more Excel-like way to do this is to use an intermediate array and not try to compress it into a fancy array-formula. You'd have a list of the strings you want to look up, then drag a plain VLOOKUP (with an absolute reference to your lookup table) down/across a parallel row/column, and then average the results.

Resources