Whenever I use reference to dynamic array function in Excel in multiple condition (AND/OR) it is not working properly (usually it will not spill). I have SEQUENCE function in column "A" and I would like to mark any rows between 5 to 9. Formula looks like this: =IF(AND(A1#>5;A1#<9);"x";""). Any idea how to fix this? Or is it a bug in Excel (or some logic why this is not possible I do not see).
When using array formula, either Dynamic or forced one cannot use AND or OR. We need to either use * or + respectively.
In this case with OR:
=IF((A1#>5)+(A1#<9);"x";"")
For AND:
=IF((A1#>5)*(A1#<9);"x";"")
Related
Up front let me say I can do this in VBA but I am trying to do it without using VBA with the assistance of the new LAMBA function.
I have a list, let us say A,B,C,D,C,E,B,B
what I am trying to write is an enumeration function which gives me the individual positions of set of identical items. So in the above example it would return a list 1,1,1,1,2,1,2,3 (the last item is a three because it is the 3rd "b" element etc). It is easy enough to do in cells with the answer in the next row:
a1:a8 contain A,B,C,D,C,E,B,B
b1 contains =COUNTIF(A1:$A$1,A1) and that gets dragged across all the columns
But I need the output in a dynamic array and something like b1
=COUNTIF(A1:$A$1,A1:H1) obviously won't work.
I've also tried writing a recursive LAMBDA statement which runs through a diminishing range but that gives me VALUE errors and is pretty complex in any case.
Any suggestions?
Use Offset inside the COuNTIFS:
=COUNTIF(OFFSET(A1,0,0,1,SEQUENCE(,COUNTA(1:1))),INDEX(1:1,,SEQUENCE(,COUNTA(1:1))))
For a non Volatile version use:
=MMULT(SEQUENCE(,COLUMNS(A1:H1),1,0),(A1:H1=TRANSPOSE(A1:H1))*(SEQUENCE(,COLUMNS(A1:H1))>=SEQUENCE(COLUMNS(A1:H1))))
With LET:
=LET(x,A1:H1,y,COLUMNS(x),MMULT(SEQUENCE(,y,1,0),(x=TRANSPOSE(x))*(SEQUENCE(,y)>=SEQUENCE(y))))
I would like to be able to use Excel's filter formula and get only specific columns as a result.
For example, I tried the below formula and failed.
=FILTER((A:B,D:D),A:A=3475,"")
How can I get this working? I want to get the filtered result where any value in column A equals 3475, and only get columns A,B and D
You could use a single one formula like:
=TRANSPOSE(CHOOSE({1,2,3},FILTER(A:A,A:A=3475),TRANSPOSE(FILTER(B:B,A:A=3475)),TRANSPOSE(FILTER(D:D,A1:A4=3475))))
But considering performance, I'd go with two seperate formulas as proposed in the comments.
You need use the proper array for the array argument to the filter function.
I used a Table since using whole-column references is inefficient.
For example, if you want to return only columns 1,2 and 4 of a table, you can use:
=INDEX(Table1,SEQUENCE(ROWS(Table1)),{1,2,4})
So your filter function might be:
=FILTER(INDEX(Table1,SEQUENCE(ROWS(Table1)),{1,2,4}),Table1[colA] = myVar)
IF, for some reason you don't want to use Tables, the following formula should also work:
=FILTER(INDEX($A:$D,SEQUENCE(LOOKUP(2,1/(LEN($A:$A)>0),ROW($A:$A))),{1,2,4}),myVar=INDEX($A:$A,SEQUENCE(LOOKUP(2,1/(LEN($A:$A)>0),ROW($A:$A)))))
as would, the less efficient:
=FILTER(INDEX($A:$D,SEQUENCE(ROWS($A:$A)),{1,2,4}),myVar=$A:$A)
I've got a table with entries in the first column and several properties of those entries in other columns. The properties are all calculated via formula except for some that I have manually entered. I am trying to count the number of properties that I have manually entered.
Some Excel functions, such as the COUNTIF(range, criteria) function, accept a cell range as one argument and a logical operator query (=, <>, >, <, >=, <=) as the other. This works well for static conditions, like comparison against a known value (e.g. COUNTIF[Table[MyColumn]], <>0), but I'd like to use the boolean return value of a function in place of the logical operator so I can evaluate every entry on the [Table[MyColumn]] range, specifically the (negated) result of ISFORMULA().
Here's some psuedo-code of what I want to do: COUNTIF([Table[MyColumn]], // check if entry is a formula or manually entered with something like ISFORMULA()). This would then return a count of all of the manually entered cells in MyColumn. All of the cells in MyColumn contain numeric values, and I want to count only the ones that weren't generated via formula.
Is it possible to substitute a boolean return value for a query condition like this? If so, is it possible using structured references ([MyColumn]) instead of absolute references (C2:C87)? Does the operation I am trying to perform require the use of VBA scripts?
Two ways I can think of. I like the new FILTER() function but you'll need to be on newer version of Excel.
=SUM(--ISFORMULA(Table1[MyColumn]))
or
=COUNT(FILTER(Table1[MyColumn],ISFORMULA(Table1[MyColumn])))
edit: if you're not an Office 365 (not on latest version of Excel) you might need to use Ctrl+Shift+Enter for the first option.
I often find myself writing Excel formulas that have something like this in the formula:
= IF(<long expression>=<some condition>,<long expression>,0)
Is there any way to accomplish this without needing to type out <long expression> twice (and also without using helper cells)?
Ideally, something that works similar to IFERROR, i.e.
= IFERROR(<some expression>,0)
This checks if <some expression> would return any type of error, and if it doesn't, it automatically returns <some expression> (without needing to again explicitly type it out a second time).
Is there an Excel function (or combination of Excel functions) similar to IFERROR but instead of checking an error condition, it checks a general (user-defined) condition based on the formula?
When it comes to formula efficiency and calculation speed, using helper cells can be of great value, even if they may initially muck up the spreadsheet design.
Put calculations into a helper cell and refer to the helper cell in the IF statement. That way the calculation will only happen once.
This method is preferred by spreadsheet auditors over the alternative of packing everything into one formula, because it is also much easier to follow and pick apart.
With careful spreadsheet planning you can house helper cells in a different (hidden) sheet or in columns that you hide to tidy up the design.
This answer applies to Excel 365 as of March 2020. A new function is now available in Insider builds of Excel. It is called LET() and is used to define, and assign a value to, a variable that can then be used multiple times inside the braces of the LET() function.
Example:
=LET(MyResult,XLOOKUP(C1,A1:A3,B1:B3),IF(MyResult=0,"",MyResult))
The first parameter is the name of a new variable, MyResult. The variable is assigned a value with the second parameter. This can be a constant, like a number or a text, or like in this case, a formula.
The third parameter is a calculation that can use the variable value.
In the following screenshot, the Xlookup returns a 0 because the found cell is empty.
In the next formula down, the Xlookup is wrapped in an IF statement, evaluated, and then repeated. This is the approach where the calculation is duplicated, as described in the question.
The third formula shows the LET() function and its result.
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.