Using INDIRECT with an Array Input - excel

I am attempting to help a student with a really simple formula and am having trouble understanding the context of the solution.
We start with a small list of values in columns A & B and another list of addresses in column C that point to the values in column A or B:
The goal is to retrieve the items in column A or B in the order specified in column C.
Her first attempt was to use:
=INDIRECT(C1:C5)
Since we are using Excel 365, this produced a dynamic spill-down of #VALUE! errors. I explained that this is because the INDIRECT() worksheet function cannot accept an array input and if we use a string input like =INDIRECT("C1:C5") all we get is the address pointers rather than the values themselves.
I suggested =IF(ROWS($1:1)<=COUNTA(C:C),INDIRECT(C1),"") and copying downward manually. She left and returned later to tell me that they found a way to make INDIRECT() work with an array input:
=SUMIF(INDIRECT(C1:C5),"<>")
which DOES work! What we don't understand is:
Why does enclosing a non-working formula in SUMIF() make it work
Why SUMIF() is returning an array rather than a single value
Any explanations or references will be appreciated.

Related

ADDRESS TO RANGE

I have this formula:
=MATCH(""&"W"&C2&"",'Raw Data'!$5:$5,0) --> Which extract the column number, then
=SUBSTITUTE(ADDRESS(1,E3,4),"1","") --> I convert to letter
It returns: DH
Finally, I want to use that value of "DH" into the following formula
=INDEX('Raw Data'!A:A,MATCH(E26,'Raw Data'!DH:DH,0))
I tried many times and ways without success.
Data is dynamic, so the first value I'm looking for W2 (for example) will not always be in the same column.
Depending on the variable which you get on the column number, I want the spreadsheet to select that column.
Here is a simplified demonstration of what I think you are trying to do here:
Formula in A3:
=INDEX(A11:A20,MATCH(A2,INDEX(A11:E20,,MATCH("W"&A1,5:5,0)),0))
As you see, this can be done without transformation of a column number into a letter reference. It's simply a matter of nested INDEX/MATCH functions as per #BigBen in the comments.
Please adapt the above to suit your ranges.
Few more remarks just for future reference:
ADDRESS - This is a so-called volatile function. Though maybe not obvious these type of functions recalculate on any save, open, edit on your worksheet. The more of these, the slower your workbook gets.
""&"W"&C2&"" - There is no need to concatenate empty strings in front of other string values leaving you with the exact same results but formulas that are simply harder to read.

Is there any other functions for excel Vlookup with different column index depend on referenced cell value?

I want to use Vlookup function to depend on a referenced cell value. Please look at my equation.
=IF(G2=1,VLOOKUP(A9,Pipe_Size_Chart,2,FALSE),IF(G2=2,VLOOKUP(A9,Pipe_Size_Chart,3,FALSE),IF(G2=3,VLOOKUP(A9,Pipe_Size_Chart,4,FALSE),IF(G2=4,VLOOKUP(A9,Pipe_Size_Chart,5,FALSE),IF(G2=5,VLOOKUP(A9,Pipe_Size_Chart,6,FALSE),IF(G2=6,VLOOKUP(A9,Pipe_Size_Chart,7,FALSE),IF(G2=7,VLOOKUP(A9,Pipe_Size_Chart,8,FALSE))))))))
Here, all vlookup function calls depend on cell G2 value. Depend on its value, Column index for each function will be varied.But I want to use more advance or more compact function for that. I don't wan't to use macro. Can anyone please give me a piece of advice?
If your ifs are only 7, you can create a helping array that will match the values you need with your ifs. What I mean is that if you need for g2=1 to get 2, g2=2 to get 3 and so on, you can create as a first step an array with the numbers 0,1,2,3,4,5,6,7 (we will cal this array "A1:A8").
Then in your VLOOKUP you can use the MATCH function:
=VLOOKUP(A9,Pipe_Size_Chart,MATCH(G2,A1:A8,0),FALSE)
The MATCH function will return the relative position of your lookup value, that I guess is in cell G2, inside this array we created and this will be your index column number. For this example if you have G2=6 then the MATCH function will return the number 7 because 6 is the seventh number in our array.
I hope this will help. If it doesn't solve your problem please provide a visual example from your table so we can give more accurate answers.

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

Excel 2003/2007 named formula appears to store only single value not range/array

Similar to a question by Stephen Roy April 26, 2013, answered by Barry Houdini. I have a named range per this generic formula
{=IFERROR(INDEX(Range,SMALL(IF(
MATCH(Range,Range,0)=ROW(INDIRECT("1:"&ROWS(Range))),
MATCH(Range,Range,0)),ROW(INDIRECT("1:"&ROWS(Range))))),"")}
[obviously in 2003 I don't use IFERROR()]
"Range" itself is a named array formula.
The formula is used to pull unique entries from a range and arrange them at the 'top' of another 'range'. However, INDEX() appears to 'store' only a single value, not the array expected. Barry talked about wrapping the ROW() in another function to lose the {array}. It looks as though the first ROW() returns multiple values and works fine, it's the last ROW() which seems to be reduced to the first array entry only, thereby causing INDEX() to return only a single value. However, instead of trying to store this in memory, I select a multi-cell range for output, and use CSE, it works perfectly well. But I don't want to have to do that.
I've tried messing around with INDIRECT(), but can't get that to work at all.
Grateful for your thoughts folks, ian taylor
This might work for you. To return a list of unique values given your range x for example:
=LOOKUP(SMALL(IF(MATCH(x,x,0)=ROW(INDIRECT("1:"&ROWS(x))),MATCH(x,x,0)),
ROW(INDIRECT("1:"&SUM(IF(FREQUENCY(MATCH(x,x,0),MATCH(x,x,0)),1))))),
ROW(INDIRECT("1:"&ROWS(x))),x)
You could define this as a name called Unique and use it in other formulas eg =COUNTIF(x,Unique) returns an array of frequencies.
Addendum
Regarding INDIRECT/INDEX/ROW etc. here's my 2c (see also here). Function inputs and outputs can essentially be divided into three cases: single values, arrays or references. If a function input argument takes single values by default and an array is specified, then the result depends on the type of output of the function. If the output type of the function is:
A) a single value - an array of values is returned, one for each input value. This is the case for most functions eg =LOOKUP({1;2},{1;2;3},{"a";"b";"c"}) returns {"a";"b"}.
B) a reference - an array of references is returned. This is the case for INDIRECT/OFFSET. eg =INDIRECT("A1:A"&ROW()) returns a single element array containing a reference but this can raise errors in many functions as the references are not converted to values by default.
C) an array - a value or array is returned based on the first input of the function if evaluated normally and entered into a single cell. Or else an array is returned based on the first result for each input if entered into multiple cells. This is the case for INDEX which may return an array if one of the arguments is zero. For example =INDEX({1,2;3,4},0,{1;2}) returns {1;3} when evaluated in the formula bar, but {1;2} when array-entered into cells.
In fact Excel uses a variant data type that can take on any of these types so the details are a little more complex than this. Also there is the ability to modify arguments in place which may be why for example VLOOKUP behave like case C with arrays in the first argument but case A with the third argument.
i tried this as a defined name say, "Unique_List" so that i can use it as a Data validation list, but when i add this defined name to the data validation list, it gives an error.
=LOOKUP(SMALL(IF(MATCH(x,x,0)=ROW(INDIRECT("1:"&ROWS(x))),MATCH(x,x,0)), ROW(INDIRECT("1:"&SUM(IF(FREQUENCY(MATCH(x,x,0),MATCH(x,x,0)),1))))), ROW(INDIRECT("1:"&ROWS(x))),x)
where x is my range.
i tried transposing this formula to get the values comma-separated rather than semicolon-separated, but data validation list doesnt seem to work.
=TRANSPOSE(LOOKUP(SMALL(IF(MATCH(x,x,0)=ROW(INDIRECT("1:"&ROWS(x))),MATCH(x,x,0)), ROW(INDIRECT("1:"&SUM(IF(FREQUENCY(MATCH(x,x,0),MATCH(x,x,0)),1))))), ROW(INDIRECT("1:"&ROWS(x))),x))
Kindly advice.

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