Excel, Array Formulas, N/A outside of range, and ROW() - excel

I have a problem with ROW() in an array formula in Excel 2013.
Example:
I make a named range, called 'input', say 4 cells wide and 10 high. Then I make an array formula =ROW(input) one cell wide, 15 cells high.
I get 10 numbers - the first is the first row of input, and the rest count up from that, and then 5 #N/A follow. This is as it should be.
If instead of =ROW(input) I try one of the following:
=IFERROR(ROW(input),"x")
or
=IF(ISNA(ROW(input)),"x",ROW(input))
to catch the #N/As then what I expect to see is ten numbers, and then five x's. Instead I still see ten numbers and then five #N/As.
Can anyone tell me how to solve this problem? I want to get ten numbers, and then five x's.
And of lesser importance but just for curiosity (or in case it comes up in another case), why does this happen?
Why do I want to do this? It's part of a larger formula that I have simplified for this question.

I believe that, in such clauses, Excel gives precedence to the artificial expansion of the reference to match that of the worksheet range selected (which it will always do by filling with #N/As) over first resolving the IF clause over the array.
So, whereas "normally" (e.g in a single-cell array formula), e.g.:
=SUM(IF(ISNA(ROW(input)),"YES","NO"))
would, effectively, coerce Excel into expanding the single value_if_true and value_if_false parameters of the IF function into syntactically-appropriate arrays of those values, viz:
=SUM(IF({FALSE;FALSE;FALSE;FALSE;FALSE},{"YES","YES","YES","YES","YES"},{"NO","NO","NO","NO","NO"}))
i.e.:
=SUM({"NO";"NO";"NO";"NO";"NO"})
with multi-cell array formulas, e.g. your:
=IF(ISNA(ROW(input)),"YES","NO")
entered over a 10-cell range, is NOT first resolved thus:
=IF(ISNA({1;2;3;4;5;#N/A;#N/A;#N/A;#N/A;#N/A}),{"YES";"YES";"YES";"YES";"YES";"YES";"YES";"YES";"YES";"YES"},{"NO";"NO";"NO";"NO";"NO";"NO";"NO";"NO";"NO";"NO"})
(In which the the value_if_true and value_if_false parameters are first re-dimensioned in accordance with the dimension of the worksheet range in which the array is being entered.)
i.e.:
=IF({FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;TRUE;TRUE;TRUE},{"YES";"YES";"YES";"YES";"YES";"YES";"YES";"YES";"YES";"YES"},{"NO";"NO";"NO";"NO";"NO";"NO";"NO";"NO";"NO";"NO"})
i.e.:
={"NO";"NO";"NO";"NO";"NO";"YES";"YES";"YES";"YES";"YES"}
but rather as:
=IF(ISNA({1;2;3;4;5;#N/A;#N/A;#N/A;#N/A;#N/A}),{"YES";"YES";"YES";"YES";"YES";#N/A;#N/A;#N/A;#N/A;#N/A},{"NO";"NO";"NO";"NO";"NO";#N/A;#N/A;#N/A;#N/A;#N/A})
(The value_if_true and value_if_false parameters first being re-dimensioned in accordance rather with the dimensions of the Named Range input.)
i.e.:
=IF({FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;TRUE;TRUE;TRUE},{"YES";"YES";"YES";"YES";"YES";#N/A;#N/A;#N/A;#N/A;#N/A},{"NO";"NO";"NO";"NO";"NO";#N/A;#N/A;#N/A;#N/A;#N/A})
i.e.:
{"NO";"NO";"NO";"NO";"NO";#N/A;#N/A;#N/A;#N/A;#N/A}
Hope that helps a bit.
Regards

Related

How to highlight a missing value in a specified range with Conditional Formatting from the last used column

We use this format in our casino to know where we have to send our employees to certain tables or games. We recently changed the way we do this and we now need to have some checks to make sure we didn't forget certain tables.
Every hour/half hour/20mins we assign a table to a person, everyone else moves one up. We know exactly which tables are open at which times. We fill this in at the top. When we fill in the upcoming timeslot we would like to have some check so we don't forget a table and maybe miss out a employee.
Example:
In the example supplied you can see that we accidentally have two number 6's but no 7 I highlighted the number 7 in the top row but it would be nice if this is doable automatically
I used VLOOKUP and INDEX/MATCH in the formula for Conditional formatting but that does not seem to create the correct outcome.
Here is an example of how it can be done:
The formula used has the array {1;2;3;4;5;6;7} hard written into it, assuming that the number of tables does not vary. The output is 0 when no table is missing, otherwise it returns a list of missing tables separated by commas.
Note: That of course means, the comma separated list is not a numeric value but a string value and cannot be used for further calculations. If further calculations on this output are required, the 'solution' has to be changed accordingly.
Formula
=IFERROR(CONCAT(FILTER({1;2;3;4;5;6;7},ISERROR(MATCH({1;2;3;4;5;6;7},H5:H24,0)))&", "),0)
Explanation
The MATCH() function checks which of the numbers 1 to 7 are present in the given range (here H5:H24) and returns the cell index of where it is found. When a number does not appear in the range, the MATCH() function will generate an #N/A error for that number.
Then, the ISERROR() function will output a FALSE value for all numbers found by MATCH() and a TRUE value for those numbers where the MATCH() function lead to an error.
The FILTER() function filters and thereby reduces the number array {1;2;3;4;5;6;7} to only those numbers where the ISERROR() function is TRUE.
The CONCAT() function concatenates the resulting array from the FILTER() function (in case more than 1 number is missing) to a single string of numbers separated by commas.
However, when there are no open tables, i.e. the MATCH() function finds all numbers 1 to 7 in the given range, then the ISERROR() function will only return FALSE values and the thus the FILTER() function returns an 'empty' array, which is not allowed in excel and leads to an #CALC error in excel. This case is captured by the IFERROR() function encapsulating the whole calculation, and instead of showing the error, returning 0.
What about this formula:
=AND(COUNTIF(A$2:A$10,1)=1,COUNTIF(A$2:A$10,2)=1,COUNTIF(A$2:A$10,3)=1,COUNTIF(A$2:A$10,4)=1,COUNTIF(A$2:A$10,5)=1,COUNTIF(A$2:A$10,6)=1,COUNTIF(A$2:A$10,7)=1)
A bit clearer:
=AND(COUNTIF(A$2:A$10,1)=1,
COUNTIF(A$2:A$10,2)=1,
COUNTIF(A$2:A$10,3)=1,
COUNTIF(A$2:A$10,4)=1,
COUNTIF(A$2:A$10,5)=1,
COUNTIF(A$2:A$10,6)=1,
COUNTIF(A$2:A$10,7)=1)
... which means that the number of ones need to be 1, the number of twos need to be 1, ..., up to the number of sevens.
Hereby a screenshot of an Excel sheet, which contains that formula:
In order to understand how this works, you might work with formula auditing, more especially formula evaluating, hereby an extra screenshot, showing formula evaluating after some steps:
Have fun :-)

Multiply based on condition then sum results ( multiply if empty <> ) in google sheets

I need help in writing a formula in cell b7. The formula must look to the right and multiply the nonempty cells by the corresponding value in row 3, and I would like to sum up the results.
File link provided.
FILE LINK
ScreenShot
Please see my comment to your original post.
That said, I will try to explain how to approach this as I think you intend. (This solution will be a Google Sheets solution which will not work in Excel.)
The first thing you will need to do is to delete everything from Row 11 down: all of your examples and notes must be deleted for the following proposed formula to work correctly.
Once you have no superfluous data below your main chart, delete everything from B6:B (including the header "Total").
Then, place the following formula in cell B6:
={"TOTAL"; FILTER(MMULT(C7:G*1, TRANSPOSE(C$3:G$3*1)), A7:A<>"")}
This formula will return the header text "TOTAL" (which you can change within the formula itself if you like) followed by the calculation you want for each row where a name is listed in A7:A.
MMULT is a difficult function to explain, but it multiplies one matrix ("grid") or numbers by another matrix ("grid") and returns the sum of all products per row (or per column, depending on how you set it up) —— which is what you are trying to do.
MMULT must have every element of both matrices be a real number. To convert potential nulls to zeroes, you'll see *1 appended to each range (since null times 1 is zero).
This assumes that all data entered into C7:G and C3:G3 will always be either a number or null. If you enter text, you'll throw the formula into an error. If you think accidental text entries in those ranges are possible, use this version instead:
={"TOTAL"; FILTER(MMULT(IFERROR(C7:G*1, ROW(C7:G)*0), TRANSPOSE(IFERROR(C$3:G$3*1, COLUMN(C$3:G$3)*0))), A7:A<>"")}
The extra bits use IFERROR to exchange error-producing entries with zeroes, since MMULT must have every space in both matrices filled with a real number.

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.

Why this array formula doesn't work?

On the illustration all formulas are array. The range that each formula spans is bordered, and the first formula on each block is written on the top of that block.
Range A4:A103 is an input vector (which is numeric), range C4:G23 is a given (input) permutation of the rows of A4:A103 (necessarily positive non-zero integer numbers not greater then the length of the input vector).
Let us I interpret the permutation matrix as set of rows.
How to compute for each row in a constant number of cells the minimal number in the input vector? By the constant number of cells, I mean solution, that would require fixed number of cells for each row, regardless of the number of columns in permutation. (In the production case each dimension is much, much bigger; there is about 100 columns in the permutation matrix.)
I don't ask for VBA solutions. If it is necessary the solution can use a free and publicly available Excel add-on, like MoreFunc, but I'd prefer to keep it vanilla Excel 2007 or later.
I thought that the formula {=MIN(INDEX(INDIRECT($A$2);$C4:$G4))} would solve my problem. Surprisingly, Excel seems to not take into account the array nature of the formula, and evaluates it as if it was written as =MIN(INDEX(INDIRECT($A$2);$C4) which is equivalent to dysfunctional =INDEX(INDIRECT($A$2);$C4).
On the other hand, we can see the argument to the MIN is understood as array in the range I4:M4.
INDEX works in some strange ways!
Normally INDEX can't return an array - although you seem to have found the one exception to that - when it's an array formula entered in a range.
You should be able to use OFFSET to return the required array that will work within MIN, i.e. with this formula
=MIN(N(OFFSET(INDIRECT($A$2);$C4:$G4-1;0)))
confirmed with CTRL+SHIFT+ENTER

Sumproducts #value! error

I am trying to use the Sumproducts function, but get the #VALUE error
The code looks like this:
=SUMPRODUCT('Combined Output Table'!AO4:BH4,'ECAP CONSTANTS'!B2:I2)
Both arrays are made up percentage values.
I use the second array in a Sumproducts function elsewhere where it works perfectly, and i have checked that the first array is only made up of number values (in percentage format). Neither array has any characters or non-number values.
The two ranges need to be the same size, in your formula the first range is 20 cells, the second is only 8, so I don't know which cells should be multiplied but this should make it work
=SUMPRODUCT('Combined Output Table'!AO4:BH4,'ECAP CONSTANTS'!B2:U2)
Second range to finish at U2, making it the same size as the first range
Your ranges aren't the same size. It makes no sense for the algorithm to try to multiply some value by some value that is not present, thus all the ranges in a SUMPRODUCT() must always match in size.

Resources