ISNUMBER statement only reading first condition - excel

Good day,
I am trying to insert this formula into excel to search for specific terms in a cell, and return a value "50" if the term is found.
I have been able to successfully implement this using the below primitive formula:
=IF(C1394<>70,C1394,IF(ISNUMBER(SEARCH("*PD*",B1394)),"50",IF(ISNUMBER(SEARCH("*OD*",B1394)),"50",IF(ISNUMBER(SEARCH("*OC*",B1394)),"50",IF(ISNUMBER(SEARCH("*OF*",B1394)),"50",IF(ISNUMBER(SEARCH("*PC*",B1394)),"50",IF(ISNUMBER(SEARCH("*MS*",B1394)),"50",C1394)))))))
I tried to make my formula more efficient and dynamic using the below approach, however excel only reads the first condition "PD" and ignores the rest
=IF(C8266 =70,IF(--ISNUMBER(SEARCH({"*PD*","*OD*","*OC*","*OF*","*PC*","*MS*"},B8266)),"50",C8266),C8266)
Can someone please advise what am I doing wrong?

You're just missing an OR clause, see this: http://www.mrexcel.com/forum/excel-questions/601195-check-multiple-text-strings-cell.html#post2977162
So you want:
=IF(C8266=70,IF(OR(ISNUMBER(SEARCH({"*PD*","*OD*","*OC*","*OF*","*PC*","*MS*"},B8266))),"50",C8266),C8266)

What you are doing wrong is you are trying to evaluate an array within a formula that doesn't usually evaluate arrays. You evaluate such formulae by pressing and holding Ctrl+Shift and then press Enter.
Otherwise, your formula can be shortened to the below:
=IF(OR(ISNUMBER((C8266=70)*SEARCH({"PD","OD","OC","OF","PC","MS"},B8266))),"50",C8266)
SEARCH does not require wildcards.
A boolean multiplied by a number gives a number. An error multiplied by a number gives an error. So you can safely combine the first and second checks together and drop the --.
OR is then used to check if there is at least 1 number within the array of numbers and/or errors.
Similarly array invoked (with Ctrl+Shift+Enter).

Related

Efficiently replace 0 with NA

I am trying to find a way to efficiently replace zero with NA() in an Excel formula. I know the following works:
=IF(FORMULA = 0, NA(), FORMULA)
But my problem is that this will cause FORMULA to execute twice. I have cases where this may be a longer =SUMIFS() in a giant table.
So I would like for:
No VBA
Only have the base FORMULA calculate once
I thought at first to try to use SUBSTITUTE() to replace "0" with something that would trigger a value error, and then just wrap all of that within IFERROR(). That obviously fails since SUBSTITUTE() cannot be forced (to my knowledge) to check for full word match (so 100 would trigger the error).
Is this possible? I have thought for years it was not, but decided to put some thought back into it.
The general answer is
=IFERROR(f'(f(FORMULA)), AlternateValue)
where f(FORMUALA) returns an error (any error will do) for values of FORMULA that you want an alternate value for.
And f'(...) is the inverse of f(...), so f'(f(FORMULA)) returns FORMULA for other values.
Ensure the first function is applied to the whole of FORMULA. Enclosing it in () guarantees that.
Secondly, ensure the two functions are applied in the correct order, also achieved using ().
In this case you want an alternate value for 0 so you can use
=IFERROR(1/(1/(FORMULA)), NA())
Calculation and display can occur in two different locations - why merge operations when you don't need to?
A1 - =Formula
B1 - =If(A1 = 0, NA(),A1)

Assign an Excel function result to a variable within a cell

I'm working on an Excel spreadsheet where I'm using VLOOKUP to get data from another sheet. I have it working, but it's giving me an annoying "0" for blank results. I'd like to incorporate ISBLANK to address it.
My problem is the syntax. I REALLY do NOT want to retype the entire VLOOKUP function for the results if it returns FALSE.
In other words, what I'm trying to avoid doing is this:
=IF(ISNULL(VLOOKUP($A2,Sheet!$B$1:Sheet!$C$200,2)),"",VLOOKUP($A2,Sheet!$B$1:Sheet!$C$200,2))
Ideally, what I want to do is something like this:
=IF(ISNULL(VLOOKUP($A2,Sheet!$B$1:Sheet!$C$200,2)),"",[some variable that stores the result of the VLOOKUP])
Ideas, anyone? Thanks...
Are you open to formatting? You can hide the zeros that way, and therefore keep the formula short.
Highlight the range of the VLOOKUP() results, and go to Formatting, then Custom. Use this format and any 0 will be effectively hidden:
0;-0;;#
It depends whether you're looking up text or numbers.
If you want the result of your expression to be text that you're looking up, it's as simple as wrapping your VLOOKUP with the function T().
So, for text, replace VLOOKUP($A2,Sheet!$B$1:Sheet!$C$200,2,FALSE) with T(VLOOKUP($A2,Sheet!$B$1:Sheet!$C$200,2,FALSE))
If the result of your expression is a number, and your VLOOKUP expression is too complicated to repeat, then you can avoid writing it twice by sneakily using IFERROR. The trick is to make it so that when VLOOKUP returns 0, it makes an error, but otherwise it returns what VLOOKUP returned. And you can do this by taking advantage of some maths: Where x<>0, then 1/(1/x) = x. When x=0, Excel returns #DIV/0!. If we use IFERROR, then we can replace that with an empty string ("")
So, for numbers, replace VLOOKUP($A2,Sheet!$B$1:Sheet!$C$200,2,FALSE) with IFERROR(1/(1/VLOOKUP($A2,Sheet!$B$1:Sheet!$C$200,2,FALSE)),"")
By the looks of it the formula you're asking for is:
=IF(VLOOKUP($A2,Sheet!$B$1:$C$200,2,FALSE)="","",VLOOKUP($A2,Sheet!$B$1:$C$200,2,FALSE))
Edit: The FALSE at the end of the function is so it only finds an exact match. Omitting it, or setting it as True, returns an exact or the next largest value that is less than the lookup value - your list must be sorted in ascending order for that to work.
Note the range reference to the sheet called Sheetis Sheet!$B$1:$C$200 and not Sheet!$B$1:Sheet!$C$200.
Having said that, an easier way is just to hide the 0 returns with number formatting.
Give the cell a custom number format of:
#,##0;-#,##0;;#
The first section #,##0 is the format for positive numbers, the second -#,##0 for negative numbers, the third ;;(no format set) for zeros and the last # for text.

Finding a value from array in File Path [Excel]

I have a little problem with Excel.
I'm trying to compare if one of several specific words occur in a path.
This is what I do with the following function:
=IF(ISERROR(SEARCH($C$2:$C$4,A2)),"NO","YES")
However, the result is always "No".
Example data:
Does anyone have an idea?
SEARCH($C$2:$C$4,A2)
will return an array of a number or a #VALUE! errors.
If you wrap that in ISNUMBER it will return an array of TRUE;FALSE...
To see if ANY of the values are TRUE, wrap that in an OR and use that in your IF statement.
Of course, since this is an array formula, you have to enter it by holding down ctrl + shift while hitting Enter
=IF(OR(ISNUMBER(SEARCH($C$2:$C$4,A2))),"Yes","No")
You can see what is happening by using the Formula Evaluation tool
You can use SUMPRODUCT with ISNUMBER and SEARCH
=IF(SUMPRODUCT(--ISNUMBER(SEARCH(C2:C4,A2)))>0,"YES","NO")

Which built-in excel functions treat ranges as arrays?

For example =SUMPRODUCT(A2:A10-10) does, but =SUM(A2:A10-10) does not. Specifically in my situation I wish =MEDIAN(ABS(A2:A10-MEDIAN(A2:A10))) did; however sadly it does not, and if I knew which built in functions convert the ranges into arrays before they evaluate then I might be able to reformulate something that gives me what I'm looking for...
there are some natural array type formulas like SUMPRODUCT and some of the options in AGGREGATE, as well as some financial functions.
Many can be "forced" into array mode by simply using Ctrl-Shift-Enter instead of Enter when exiting edit mode.
For example your formula:
=MEDIAN(ABS(A2:A10-MEDIAN(A2:A10)))
If it is confirmed with Ctrl-Shift-Enter instead of Enter when exiting edit mode will "Force" the Array. If done correctly the Excel will put {} around the formula.
The INDEX function has an Array Form.
=SUM(INDEX((A2:A10)-10, , ))
In the above, INDEX is returning an array of values but a wrapping SUM is required to collect a total. The blank parameters represent all rows and all columns in the range (e.g. A2:A10) specified. All rows and all columns in the range can also be represented with zeroes in place of the blank parameters.
With 2 to 10 in A2:A10, your MEDIAN example would return 14 from,
=MEDIAN(INDEX(ABS((A2:A10)-MEDIAN(A2-A10)), , ))
(without CSE)
Use the Evaluate Formula command to see more of the inner workings of this style of INDEX use.

simplifying Excel formula currently using INDEX, ROW, SUMPRODUCT and IFERROR

Does anyone have any brilliant ideas to simplify this difficult formula? Don't panic when you see it, I will try to explain.
=IFERROR(INDEX(rangeOfDesiredValues,(1/SUMPRODUCT((rangeOfSerials=$D20)(rangeOfApps=cfgAppID)(rangeOfAccessIDs=cfgAccessID)*ROW(rangeOfDesiredValues))^-1)),"")
Currently I am using SUMPRODUCT to do the equivalent of a VLOOKUP with multiple columns as criteria. Usually that only works with number results, but since I need to find text, I'm using SUMPRODUCT in combination with ROW and INDEX.
Unfortunately when no cell is found, my SUMPRODUCT returns 0. This causes the formula to return the incorrect cell rather than blank. For this reason I am running the result through this calculation:
(1 / result)^-1
This way results of 0 become an error, and other results remain unchanged. I feed this into IFERROR, so that errors become blanks.
Does anyone know how to make this neater? I am not able to create new columns in any of my spreadsheets.
It's always best to avoid using multi-condition summing functions like SUMPRODUCT when you want to find a single value (it would obviously give you an incorrect result or error if there's more than one row which matches all three conditions, I assume you expect one match at most here?). ROW function can also be problematic if you insert any rows in the worksheet.....
There are several approaches that can work. For a single formula, using MATCH is the most common - MATCH will only give the correct position or an error so no problems with zero values. That would look like this:
=IFERROR(INDEX(rangeOfDesiredValues,MATCH(1,(rangeOfSerials=$D20)*(rangeOfApps=cfgAppID)*(rangeOfAccessIDs=cfgAccessID),0)),"")
That's an "array formula" that needs to be entered with CTRL+SHIFT+ENTER......or you can make it into a regular formula with an extra INDEX function like this
=IFERROR(INDEX(rangeOfDesiredValues,MATCH(1,INDEX((rangeOfSerials=$D20)*(rangeOfApps=cfgAppID)*(rangeOfAccessIDs=cfgAccessID),0),0)),"")
A third alternative is to use LOOKUP which doesn't need "array entry"
=IFERROR(LOOKUP(2,1/(rangeOfSerials=$D20)/(rangeOfApps=cfgAppID)/(rangeOfAccessIDs=cfgAccessID),rangeOfDesiredValues),"")
That differs slightly from the previous versions in the case of multiple matches - it will give you the last match rather than the first in that scenario (but I assume you have only one match at most, as stated above).
Finally, if you don't mind using helper columns you could simplify the formulas considerably. Just use a "helper" column to concatenate the three criteria columns separated by dashes and then you can use a simple VLOOKUP or INDEX/MATCH, e.g.
=IFERROR(INDEX(rangeOfDesiredValues,MATCH($D20&"-"&cfgAppID&"-"&cfgAccessID,Helper_Column,0)),"")

Resources