15

If the data in the range A1:A4 is as follows:

Apple
Banana
Orange
Strawberry

Then INDEX can be used to individually return any value from that list, e.g.

= INDEX(A1:A4,3)

Would return Orange.

Is there a similar Excel functions or combination of functions that would effectively allow you to do something like this:

= INDEX(A1:A4,{2;3})

Which would return an array {Banana;Orange}?

Is this possible (preferably without VBA), and if so, how? I'm having a tough time figuring out how to accomplish this, even with the use of helper cells.

I can figure out a somewhat complicated solution if the data is numbers (using MMULT), but the fact that the data is text is tripping me up because MMULT does not work with text.

mgae2m
  • 1,134
  • 1
  • 14
  • 41
ImaginaryHuman072889
  • 4,953
  • 7
  • 19
  • 51
  • 2
    Short answer, No. – Scott Craner Nov 08 '17 at 19:16
  • @ScottCraner Is the long answer, "yes, with VBA"? – ImaginaryHuman072889 Nov 08 '17 at 19:22
  • 1
    That most likely correct but if you explain more what you are starting with and where you want to end we may be able to find an alternative. – Scott Craner Nov 08 '17 at 19:23
  • Actually, the short answer is Yes. See my answer below. – jeffreyweir Nov 08 '17 at 21:30
  • @ScottCraner Just FYI, one of the answers showed that this is possible with the formula `=INDEX(A1:A4,2):INDEX(A1:A4,3)` which provided the exact desired result. Not telling this to prove you wrong, just thought you would want to know for future reference. – ImaginaryHuman072889 Nov 09 '17 at 11:43
  • 1
    That is because I misunderstood what you wanted. I figured you wanted to be able to choose the index of a list and return those to an array that could be used in a formula. If I had known you wanted contigous cells then I would have given that formula. But as I understood it you wanted the ability to pick and choose, ie" `=INDEX(A:A,{1,3}) and return {"Apple","Orange"})` which is not possible. Yes you can use INDEX to set the beginning and ending of a range, and I use it often in answering questions. But again that is not what you asked. And why I tried to get more info from you. – Scott Craner Nov 09 '17 at 13:41
  • @ScottCraner Good point. – ImaginaryHuman072889 Nov 09 '17 at 13:43
  • 2
    @ScottCraner: It *is* possible to use INDEX to return non contiguous cells, if you dereference it like I have done in the second part of my answer. Not that I'd probably use this over OFFSET.... – jeffreyweir Nov 09 '17 at 17:50
  • I stand corrected. I would use INDEX as OFFSET is volatile. Not sure if using N() makes this volatile or not. @jeffreyweir – Scott Craner Nov 09 '17 at 17:54
  • Yup, on the upside INDEX is only semi-volatile. On the downside, this is probably the least known trick in the book, meaning anyone who doesn't know the secret handshake will scratch their head if trying to unpick formulas using it. – jeffreyweir Nov 09 '17 at 18:05

4 Answers4

34

OFFSET is probably the function you want.

=OFFSET(A1:A4,1,,2)

But to answer your question, INDEX can indeed be used to return an array. Or rather, two INDEX functions with a colon between them:

=INDEX(A1:A4,2):INDEX(A1:A4,3)

This is because INDEX actually returns a cell reference OR a number, and Excel determines which of these you want depending on the context in which you are asking. If you put a colon in the middle of two INDEX functions, Excel says "Hey a colon...normally there is a cell reference on each side of one of these" and so interprets the INDEX as just that. You can read more on this at http://www.excelhero.com/blog/2011/03/the-imposing-index.html

I actually prefer INDEX to OFFSET because OFFSET is volatile, meaning it constantly recalculates at the drop of a hat, and then forces any formulas downstream of it to do the same. For more on this, read my post https://chandoo.org/wp/2014/03/03/handle-volatile-functions-like-they-are-dynamite/

You can actually use just one INDEX and return an array, but it's complicated, and requires something called dereferencing. Here's some content from a book I'm writing on this:

The worksheet in this screenshot has a named range called Data assigned to the range A2:E2 across the top. That range contains the numbers 10, 20, 30, 40, and 50. And it also has a named range called Elements assigned to the range A5:B5. That Elements range tells the formula in A8:B8 which of those five numbers from the Data range to display.

enter image description here

If you look at the formula in A8:B8, you’ll see that it’s an array-entered INDEX function: {=INDEX(Data,Elements)}. This formula says, “Go to the data range and fetch elements from it based on whatever elements the user has chosen in the Elements range.” In this particular case, the user has requested the fifth and second items from it. And sure enough, that’s just what INDEX fetches into cells A8:B8: the corresponding values of 50 and 20.

But look at what happens if you take that perfectly good INDEX function and try to put a SUM around it, as shown in A11. You get an incorrect result: 50+20 does not equal 50. What happened to 20, Excel?

For some reason, while =INDEX(Data,Elements) will quite happily fetch disparate elements from somewhere and then return those numbers separately to a range, it is rather reluctant to comply if you ask it to instead give those numbers to another function. It’s so reluctant, in fact, that it passes only the first element to the function.

Consequently, you’re seemingly forced to return the results of the =INDEX(Data,Elements) function to the grid first if you want to do something else with it. Tedious. But pretty much every Excel pro would simply tell you that there’s no workaround...that’s just the way it is, and you have no other choice.

Buuuuuuuut, they’re wrong. At the post http://excelxor.com/2014/09/05/index-returning-an-array-of-values/, mysterious formula superhero XOR outlines two fairly simple ways to “de-reference” INDEX so that you can then use its results directly in other formulas; one of those methods is shown in A18 above. It turns out that if you amend the INDEX function slightly by adding an extra bit to encase that Elements argument, INDEX plays ball. And all you need to do is encase that Elements argument as I've done below:

N(IF({1},Elements))

With this in mind, your original misbehaving formula:

=SUM(INDEX(Data,Elements))

...becomes this complex but well-mannered darling:

=SUM(INDEX(Data, N(IF({1},Elements))))
Avraham
  • 1,655
  • 19
  • 32
jeffreyweir
  • 4,668
  • 1
  • 16
  • 27
3

You can get this type of behavior without an array formula. In say D1

=IFERROR(INDEX($A$1:$A$4,CHOOSE(ROWS($1:1),2,3)),"")

and copy down. Note the 2,3 is buried inside the CHOOSE() function.

enter image description here

You can replace the 2,3 with any set of indices.

Gary's Student
  • 95,722
  • 10
  • 59
  • 99
0

Correct

Update 3

You should using array formula:

For = INDEX(A1:A4,{2;3}) write = INDEX(A1:A4,ROW($A$2:$A$3))

For using array formula, (1) select the range of cells you want return results, vertically (for example B1:B2) and then press (2) F2 and enter above formula, then (3) press Ctrl + Shift + Enter.

Update

Explain:

You can controlling row_num and column_num parts of INDEX with array formulas for returning more specially wanted results.

There is two approach to returning array formula results:

  • (I)

    1. Select the range that you want show returned results.
    2. Press F2
    3. Type your array form formula.
    4. Then Press Ctrl + Shift + Enter.

Example:

=INDEX($A$1:$A$4,SMALL(IF($B$2=$A$1:$A$4,ROW($A$1:$A$4)-ROW($A$1)+1),ROW($A:$A)))
  • (II)

    1. Enter the array form formula in first cell you want showing returned results (Then press Ctrl + Shift + Enter), then extend the formula.

Example:

=INDEX($A$1:$A$4,SMALL(IF($B$2=$A$1:$A$4,ROW($A$1:$A$4)-ROW($A$1)+1),ROW(A1)))

Conclusion

INDEX formula works in array form.

You need enter row_num or column_num in an array. for this use suitable array formulas as: IF, SMALL, CHOOSE. Note that MATCH is not array form formula.

Temporary sample file (for 30 days): book.xlsx

Sheet

mgae2m
  • 1,134
  • 1
  • 14
  • 41
  • This doesn't work... the second argument of `INDEX` must be a number. Since `$A$2:$A$3` evaluates to `{Banana;Orange}`, your formula here returns an error, specifically `#VALUE!`. Whether or not you enter it as an array formula makes no difference. – ImaginaryHuman072889 Nov 08 '17 at 20:29
  • I had update the the answer and correct with better details. Please review my answer and judge about it's value and acceptance. – mgae2m Nov 09 '17 at 08:19
  • I suggest array formula, that has more power in several cases. – mgae2m Nov 09 '17 at 08:42
  • The downvote will remain. The first part of your answer completely misses the point of my question. On top of that, the formula doesn't even work. Your formula `= INDEX(A1:A4,ROW($A$2:$A$3))` returns only the value in `A2` if it is entered as an array formula, and the whole point of the question was to use an independent index rather than simply taking the `ROW` of a cell range. Your formula is superfluous because `= INDEX(A1:A4,ROW($A$2:$A$3))` is basically a complicated way to write the formula `= $A$2:$A$3`. Additionally, your `SMALL` function is missing arguments. – ImaginaryHuman072889 Nov 09 '17 at 12:09
  • As your familiarity about array formula, I explained more about how to use array formula with update the top of my answer. The `SMALL` function is great and work. Whats your problem? – mgae2m Nov 09 '17 at 12:28
  • Again, your formula `= INDEX(A1:A4,ROW($A$2:$A$3))` returns only `Banana` and not `{Banana;Orange}`, even if entered as an array formula. The `SMALL` function requires two arguments and your formula only contains one argument. – ImaginaryHuman072889 Nov 09 '17 at 12:32
  • The `=INDEX($A$1:$A$4,SMALL(IF($B$2=$A$1:$A$4,ROW($A$1:$A$4)-ROW($A$1)+1,ROW($A:$A)))` formula is dependent and I upload picture hope can help in transfer my mean. – mgae2m Nov 09 '17 at 12:48
  • 1
    @ImaginaryHuman072889, I insert you a sample file. and picture. You was right man. I apologize you with shame. My formula (contains `SMALL` function) involved an error. I correct and test it before send to you with a sample file and picture. Hope my answer reach your satisfy and accept. and vote. And solve your issue. Please ask any remains questions. Please excuse me my initial answer mistakes. – mgae2m Nov 09 '17 at 13:31
  • I'll remove downvote because I admire your perseverance and willingness to help. – ImaginaryHuman072889 Nov 09 '17 at 13:32
  • @imaginaryHuman072889, If my answer is right and solve problem, please Upvote or accept. thanks. – mgae2m Nov 09 '17 at 14:13
0

Thanks to the obscure technique based on "de-referencing" found by superhero XOR and mentioned above by @jeffreyweir, I have managed to make VLOOKUP() also work in a CSE array formula (one could say INDEX(MATCH()) or LOOKUP() should do the trick, yes...).

In the 3 examples below, the goal is always to sum values in column $B:$B (2) retrieved and returned by the VLOOKUP() function.

Example 1:

Looking for text values only in column $A:$A

enter image description here

=SOMME(RECHERCHEV(T(SI({1};$A$1:$A$3));$A$1:$B$3;2;0))
=SUM(VLOOKUP(T(IF({1},$A$1:$A$3)),$A$1:$B$3;2;0))

Example 2:

Looking for numeric values only in column $A:$A

enter image description here

=SOMME(RECHERCHEV(N(SI({1};$A$1:$A$3));$A$1:$B$3;2;0))
=SUM(VLOOKUP(N(IF({1},$A$1:$A$3)),$A$1:$B$3,2;0))

Example 3:

Looking for any type of values (numeric/text) in column $A:$A

enter image description here

=SOMME(CNUM(RECHERCHEV(T(SI({1};TEXTE($A$1:$A$3;"@")));TEXTE($A$1:$B$3;"@");2;0)))
=SUM(VALUE(VLOOKUP(T(IF({1},TEXT($A$1:$A$3,"@"))),TEXT($A$1:$B$3,"@"),2,0)))

Note 1: while the array constant {1} is not required with the INDEX(MATCH()) solution (a scalar 1 does the trick (or True, etc.)), the vector form seems to be necessary for this VLOOKUP() solution.

Note 2: N() and T() are to my knowledge the only 2 functions that seems to allow to "de-reference" ranges and convert them to VBA-like arrays of strings/numerical values. This might be related to this strange behavior:

enter image description here enter image description here

Indeed, like any CSE array formula, the expected results should be {A,B,C} and {1,2,3} respectively...

hymced
  • 570
  • 5
  • 19
  • 1
    FYI if you have a version of Office that supports the new feature called "Dynamic Array Formulas", there is no more need to make a CSE formula, Excel now automatically detects an array input. So, the formula `=SUM(VLOOKUP($A$1:$A$3,$A$1:$B$3;2;0))` entered normally returns 6, while `{=SUM(VLOOKUP($A$1:$A$3,$A$1:$B$3;2;0))}` wrongly returns 1. – hymced Feb 04 '20 at 16:13
  • Hi, you mention an `INDEX(MATCH())` solution but only show `VLOOKUP` - I cannot get this to work with `INDEX(MATCH())`. Do you have a working example? – Alex M Mar 02 '20 at 23:17
  • Yes sure, here is one : `{=SUM((INDEX($D$1:$D$2;N(IF({1};MATCH($A$1:$A$5;$C$1:$C$2;0))))*($A$1:$A$5=F1)))}`. And as I said in my previous comment, now you don't even need to validate the formula as array formula, it also works as a normal formula https://i.stack.imgur.com/B02WC.png – hymced Mar 04 '20 at 17:10
  • Let's say you have certain data in column A, each element of the data has a corresponding value, given in the blue table. You can immediately sum the corresponding values of all the elements matching a certain criteria, here being the "A" elements in row 1, then the "B" elements in row 2: – hymced Mar 04 '20 at 17:16