Using a formula with a range having a variable - excel

I have columns with a number of rows. I also have a module that counts certain cells when conditional formatting evaluates to true within the columns.
I can use a formula such as
=CountCFCells(A2:A201,README!$A$2)
and I get the correct result. However, I only want to examine the first X amount of rows (not all 201) I need to have a variable for the end row. I've defined NoR = 30 using the name manager and changed my formula to
=CountCFCells("A2:A" & NoR,README!$A$2)
however, this returns an error. It appears that the variable is substituted into the formula, but the range is in double quotes like
=CountCFCells("A2:A30",README!$A$2)
I believe the double quotes around my range is causing the error. Does any one know a solution to this problem? Thank you

Personally I avoid INDIRECT whenever possible as it's volatile - and I suspect your function takes a bit of calculating. I'd suggest INDEX instead:
=CountCFCells(A2:INDEX(A:A,NoR),README!$A$2)
This construction is still semi-volatile (it will recalculate when you first open the workbook) but better than fully volatile.

Is the function CountCFCells is expecting a range as an input, rather than a string? If so, try INDIRECT, like so:
=CountCFCells(INDIRECT("A2:A" & NoR),README!$A$2)

Related

Excel reference a range based on a string

I would like to input a number in a range from another sheet and I don't know how to do it.
The function:
=PERCENTRANK.INC(sheet1!$C$6:$C$**96**;sheet1!$C$6))
For example: The result of this function should be in a range of 10 days. So the range would be sheet1!M6:M16 (not sheet1!M6:M96)
I want input different numbers on the "96" space.
And I have a large matrix so it's impossible to do it manually.
Thank you so much!!
Avoid the use of volatile INDIRECT and OFFSET set-ups when a perfectly good non-volatile INDEX set-up is available.
=PERCENTRANK.INC(Sheet1!C6:INDEX(Sheet1!C:C,G3),Sheet1!C6)
=Average(indirect("sheet1!M6:M"&A1)) in A1 put 96
You may want to replace the range inside the average: =AVERAGE(FILTER(…)) where you can define a range by certain criteria.
edit:
If you want to use the absolute cell reference, see the answer from Zorigt.
Alternatively, you could also use the OFFSET function to define your range starting from a reference cell (e.g. 10 rows for 10 days)
With the filter you could define e.g. from which day to which day and/or any other criteria
If you want dynamic range as per the input you will give better make use of the address function with indirect. indirect takes static cell reference.
=ADDRESS($C$3+6,3)
Result: $C$16
=PERCENTRANK.INC($C$6:INDIRECT(ADDRESS($C$3+6,3)),C6)
however this function doesn't ignore the values outside the range that you gave.
so to overcome this problem you can check if the range you gave and the current row/cell in the formula is greated then or equal.
=IF(ROW(INDIRECT($D$3))>=ROW(),PERCENTRANK.INC($C$6:INDIRECT($D$3),C6))

Index Match Works on some cells, not others

I was using this Index Match formula with no issues:
=INDEX('Rain Data For 9 Stations'!A:S,MATCH(RainWICSProximity!J100,'Rain Data For 9 Stations'!A:A,0),INDEX($N$4:$N$12,MATCH(H100,$M$4:$M$12,0)))
I added more data, and it now only returns some values, while returning #N/A for others, even though there is a value to return.
Index returns the value in a range.
What you are doing is =INDEX(MATCH(),INDEX(MATCH())). It works due to some luck, because sometimes the second Index() returns cell with value as well. However, if the second index returns cell with an empty value, then the first index has to return something like =Index(4,0), which is #N/A.
In general, try =Index(Match(),Match()).
To see where exactly the error is, select the cell with the formula, go to the Excel ribbon >Formulas>Evaluate Formula.
Then press a few times Evaluate Formula and see what happens:
See this answer for step-by-step formula evaluation.
#Vityata was correct, Index, Match, Match works wonderfully, also, my original formula does work.
The issue was, I had calculate set to Manual, not auto, in excel settings.
I believe you need to expand your range. I am not real familiar with Index Match but trying to learn to use it more, but I believe it is kind of like VLOOKUP. Your ranges $N$4:$N$12 and $M$4:$M$12 is where it is looking right? If so, those ranges are not expanding even though you added more data. So you need to expand it to like $M$4:$M$100 or whatever. Or expand it to find the last row which is what I usually do. like mine would be "$M$4:$M" & LastRow & "" or something like that.

Using COUNTIF, OFFSET, MATCH in Excel

I keep getting an error around this certain part of my COUNTIF function and cannot find out why. I believe it's cause the Offset function won't output a range. It seems to work fine if I manually put a range, but that isn't an option.
How do I get a range as an output using Match?
=COUNTIFS(OFFSET(Sheet2!$A$1,0,MATCH(I$1,Sheet2!1:1,0)),"*Accountable*")
I think you want to count "Accountable" from $A$1 until the found match, so you are trying to "expand" the cell A1 by as many cells. The parameter to enlarge the number of columns in the OFFSET function is parameter 5. Try this:
=COUNTIFS(OFFSET(Sheet2!$A$1,0,0,1,MATCH(I$1,Sheet2!1:1,0)),"Accountable")
' ^^^
You could use INDEX to achieve the same. (sometimes preferred for its non-volatility):
=COUNTIFS(Sheet2!$A$1:INDEX(Sheet2!1:1,MATCH(I$1,Sheet2!1:1,0)),"Accountable")
Solved:
A.S.H's tip on keeping the ranges the same solved most of it.
The second bit I was running into was just a miscalculation of columns.
It needed to be the match function and then minus 1 column.

Use of ROW() or COLUMN() in OFFSET(...) generating #N/A! error

I want to have a cell at the top of a column of data which uses a worksheet function to record the total number of cells below it which contain data. There are no gaps in the column, so I figure I don’t need to use COUNTA, it would be more efficient to find the first blank cell. To this end I have the following function in cell R12:
=MATCH(TRUE,INDEX(ISBLANK(OFFSET($R$12,1,0,1000,1)),0),0)-1
This worked fine until I tried to use a named reference cell to define the resized range a bit more flexibly… replacing the above with
=MATCH(TRUE,INDEX(ISBLANK(OFFSET($R$12,1,0,ROW(last_cell)-ROW(),1)),0),0)-1
gives #N/A! in the cell. As a formula =ROW(last_cell)-ROW() works fine on its own so it’s a puzzle to me why it doesn’t work in the compound formula… even replacing a 1 in the OFFSET parameters with ROW(A1) throws an error.
I can work round it, but this behaviour is really annoying! Can anyone shed any light on this?
The problem you are having is that the OFFSET function is expecting a long integer as its [height] parameter and you are shoving an array of integers at it. Yes, there is only one integer in the array but it is still an array and OFFSET is jumping ship at the first sign of potential trouble. If you evaluate the formula as suggested by Grade 'Eh' Bacon above, you will see that the result of that simple math subtraction is wrapped in braces (e.g. { and } ). You need to remove any indication that the [height] parameter is being fed an array or OFFSET will keep choking.
=MATCH(TRUE,INDEX(ISBLANK(OFFSET($R$12, 1, 0, MIN(ROW(last_cell)-ROW()), 1)),0),0)-1
There are any number of basic Excel worksheet functions that can take an array of 1 and turn it into an integer. I've used the MIN function. MAX, SUM, AVERAGE, etc. would all work. They take an array of numbers and return a single integer, even if that array of numbers has only one number.
On a related topic, I find it admirable that you are trying to reduce the calculation cycles in your workbook but you are missing one important consideration. The first thing you should do is throw out the OFFSET function altogether.
=MATCH(TRUE,INDEX(ISBLANK($R$12:INDEX($R:$R, ROW(last_cell)+1)), , ), 0)-1
OFFSET is a volatile formula that recalculates whenever anything in the workbook changes. Opting for the INDEX function equivalent takes the formula out of volatile mode and it will only recalculate when something that affects its outcome changes.
You may be interested in the way OFFSET erroneously treats floating point errors. See OFFSET_Floating_Point_Error for more on that.
Having had a chance to play around a bit, I'm still confused!
OFFSET itself doesn't seem to have a problem accepting the return values of ROW and COLUMN as parameters. To use a trivial example, this formula works:
=COUNTBLANK(OFFSET($R$12,ROW(1)+1,0,ROW(R20)-COLUMN(),1))
Trying different ways of eliminating OFFSET from the expression, I came up with:
=MATCH(TRUE,INDEX(ISBLANK(INDIRECT(ADDRESS(13,18)&":"&ADDRESS(1012,18))),0),0)-1
Which works, at the cost of swapping OFFSET for INDIRECT (which I'm hoping is the lesser of 2 evils!) However I would prefer to use:
=MATCH(TRUE,INDEX(ISBLANK(INDIRECT(ADDRESS(ROW()+1,COLUMN())&":"&ADDRESS(ROW(last_cell),COLUMN()))),0),0)-1
Which doesn't work, giving #N/A! again, as does changing any of the explicit integers to ROW or COLUMN expressions.
Individually, I've tried OFFSET, INDEX, ISBLANK and MATCH with ROW and COLUMN expressions and they all seem to work, so it seems to be something about using them in compound formulae which is throwing the error.

Using Named Range as single cell references in formulas that accept arrays

So background first, question second.
I recently discovered an interesting property of named ranges that I'm experimenting with and not finding much help. The property is this: If I name a range (a column in this example), I can use the named range as a reference in formulas and it will usually resolve as though it were a reference to the same relative position as the current cell within the named range. So if I call A:A "Alphabet" and it contains letters a through z, each in their own row, I can simply type =Alphabet in cell b26 and it will evaluate to "z" (i.e. A26 instead of a:A). Seems simple, but it is shaping up to be quite powerful, because there is essentially an index function built-in. Very useful for making tidy formulas.
Onto the issue: when I use this same technique with a range that accepts an array argument (i.e. MAX, EOMONTH, etc.), the reference is resolving in the standard way (Max(A:A)). If I wrap the reference in VALUE(), then it resolves to just the single reference within the larger range (a26). The question is simply can anyone think of any way to avoid needing to do this, or at least to make the wrapper as unobstrusive as possible?
Real world example: I have a list of employees and I want to determine which date from three named ranges is larger. So I have something like
='DateSameRow1' > Max('DateSameRow2','DateSameRow3','DateSameColumn', and it is resolving as =a10 > Max(b:b,c:c,2:2). Note the issue: The named range outside of MAX resolved one way, and inside MAX resolved another. Sure, I could just write = a10 > Max(b10,c10,d2) or whatever, but this is so much more readable in what will end up being a huge formula. Right now I'm having to write MAX(VALUE('DateSameRow2')) or whatever to get the result I want and it is defeating the purpose.
Thanks
You can use --NAMED_RANGE in front of the "offending" named range and it will force a negative VALUE and then undo the negative.
Per my comment, I would recommend you not build a spreadsheet on this functionality. The -- is even further removed from VALUE in indicating that a named range is being used in this way.

Resources