Excel's Find function; Exceptions over values - excel

I recently learned that Excel's Find function returns a #VALUE error when it doesn't find the needle in the haystack (i.e. no match is found). I have several questions about this behavior:
Is there another Excel function that works as Find but returns an actual value (e.g. -1) when no match is found?
Is there any well-known reason for the function having that behavior? I mean, talking about general programming and software design, Is there a known pattern (or methodology, or design philosophy) that prefers throwing exceptions over returning values (like -1, 0, "" or similar) when a function doesn't return a "valid" value?

The Find function looks for a case-sensitive match, and can be tested with IsNumber, like:
=IF(ISNUMBER(FIND("abc",A1)),FIND("abc",A1),"No exact match")
There is a very similar function called Search which does the same thing, but is not case sensitive. It also returns an error if no match is found.
So if you are looking for something and want to return -1 if there is no match and you are not worried about being case sensitive, then something like this should work for you:
=IF(COUNTIF(A1,"*abc*")=0,-1,SEARCH("abc",A1))
For case sensitive searches, it would be:
=IF(ISNUMBER(FIND("abc",A1)),FIND("abc",A1),-1)
If you are on Excel 2007 or later, you can skip the error checking by using IFERROR:
=IFERROR(SEARCH("abc",A1),-1)
=IFERROR(FIND("abc",A1),-1)

Related

IfError with else, does this function exist in Excel?

While trying to help the author of this other question, I bumped (again) into the situation that I would like the following Excel function:
=IFERROR(value, value_if_error, value_if_no_error)
In other words, I'm looking for an IFERROR() function with an else-clause.
The issue is: it can in theory be done as follows:
=IF(IFERROR(function(),error_value),value_if_error,value_if_no_error)
But what if error_value is a possible outcome of function()? That would make it impossible to use IFERROR(): e.g. function() returns a string, which can be anything, also an empty string, but it might also generate an error.
Edit: some clarification
Let me give an example:
=IFERROR(B3, "weird")
In "B3", there is a function, which returns a string, but even in case the value of this string is "weird", this is ok. How can I distinguish the erroneous case and the case where "weird" is a normal correct result?
As an image says more than a thousand words:
Next to IFERROR(), there also is the ISERROR() function, which can be used as an input for an IF()-clause:
=IF(ISERROR(value),value_if_error,value_if_no_error)

Excel: Multiple If with Countif Statements

In Excel, I have three formulas/statements I'd like to merge into one. I've listed the statements below. Is there a way to merge all three formulas into one? I'd like to learn how to write the logic to do this. Thanks.
=IF(COUNTIF($B:$B,$A2)=1, "MATCH")
=IF(COUNTIF($B:$B,$A2)>1, "DUPLICATE")
=IF(COUNTIF($B:$B,$A2)<1, "NO MATCH")
The syntax of the IF function is IF(true-false-condition, value-if-condition-true, value-if-condition-false) (where either missing value-if defaults to 0).
3-way (or more) IF conditionals can be written by nesting multiple boolean IF's, for example:
=IF(COUNTIF($B:$B,$A2)>1, "DUPLICATE", IF(COUNTIF($B:$B,$A2)=1, "MATCH", "NO MATCH"))
Also consider good practice of trapping the default 'else' case. The above answer does not do this, and it assumes your input will always be one of your stated cases (=1, <1 or >1) so omits the final IF condition. In that example this will not error because the evaluations will always return true or false, but this may not behave as expected if an input is a different data type, null set, etc. In the stated answer, this unexpected behaviour will "fail silently" which is a potential issue.
Instead, try:
=IF(COUNTIF($B:$B,$A2)>1, "DUPLICATE", IF(COUNTIF($B:$B,$A2)=1, "MATCH", IF(COUNTIF($B:$B,$A2)<1, "NO MATCH", "ERROR")))
In implementation you would replace "ERROR" with your chosen error handling method.
You could also look at the following Excel functions, as an alternative to nesting multiple IF functions:
SWITCH:
=SWITCH(expression, value1, result1, [default or value2, result2],…[default or value3, result3])
IFS:
=IFS (test1, value1, [test2, value2], ...)
Some of these are newer than others so be sure to test to your version of Excel (and consider compatibility with any other possible users of your file).

How to correct an Excel formula error

=O27&" "&IF(D27<>"",VLOOKUP(D27,성취기준1반!$B$4:$C$19,2)&" ","")&IF(E27<>"",VLOOKUP(E27,성취기준1반!$E$4:$F$19,2)&" ","")&IF(F27<>"",VLOOKUP(F27,성취기준1반!$H$4:$I$19,2)&" ","")&IF(G27<>"",VLOOKUP(G27,성취기준1반!$K$4:$L$19,2)&" ","")&IF(H27<>"",VLOOKUP(H27,성취기준1반!$N$4:$O$33,2)&" ","")&IF(I27<>"",VLOOKUP(I27,성취기준1반!$Q$4:$R$33,2)&" ","")&IF(J27<>"",VLOOKUP(J27,성취기준1반!$T$4:$U$33,2)&" ","")&IF(K27<>"",VLOOKUP(K27,성취기준1반!$W$4:$X$33,2)&" ","")&IF(L27<>"",VLOOKUP(L27,성취기준1반!$Z$4:$AA$33,2)&" ","")&IF(M27<>"",VLOOKUP(M27,성취기준1반!$AC$4:$AD$19,2)&" ","")&P27
this is working code
=O28&" "&IF(D28<>"",VLOOKUP(D28,성취기준1반!$B$4:$C$19,2)&" ","")&IF(E28<>"",VLOOKUP(E28,성취기준1반!$E$4:$F$19,2)&" ","")&IF(F28<>"",VLOOKUP(F28,성취기준1반!$H$4:$I$19,2)&" ","")&IF(G28<>"",VLOOKUP(G28,성취기준1반!$K$4:$L$19,2)&" ","")&IF(H28<>"",VLOOKUP(H28,성취기준1반!$N$4:$O$33,2)&" ","")&IF(I28<>"",VLOOKUP(I28,성취기준1반!$Q$4:$R$33,2)&" ","")&IF(J28<>"",VLOOKUP(J28,성취기준1반!$T$4:$U$33,2)&" ","")&IF(K28<>"",VLOOKUP(K28,성취기준1반!$W$4:$X$33,2)&" ","")&IF(L28<>"",VLOOKUP(L28,성취기준1반!$Z$4:$AA$33,2)&" ","")&IF(M28<>"",VLOOKUP(M28,성취기준1반!$AC$4:$AD$19,2)&" ","")&P28
this is doesn't workin code.
Why doesn't it work?
This is not an answer in terms of a solution, but an answer in terms of the method you could employ to find and solve the issue. Mainly because you have not provided a working verifiable example, data or detail of the actual error.
First I would remove the vlookups and replace them with the expected results - if that then functions as it should then each of the vlookups needs to be tested, if not then check the detail of the function.
Appreciate if you can assist by explaining.. "why this doesn't work?" part. It is an error message or the the expected value is _ but I got _ instead.. (:
One thing I noticed is that you don't define what will be the outcome if D28 is "". If you don't define it, it'll return 'FALSE' value instead of a String/text.
In your IF() function, you only say IF(d28<>"",<DisplayValueFrom성취기준1반>) it should be IF(d28<>"",<DisplayValueFrom성취기준1반>,<DisplaySomeThingElse>)

Using IF with OR, AND and Wildcard in same statement

I'm trying to create an IF statement that will basically look at one cell which currently has a macros enabling multi-select drop down from a lookup list.
The field the IF statement is based on is a drop down containing the following information:
Android
iOS
PC/Mac
All Devices
Mobile Devices
The user can select one value or multiple values.
The IF statement will be true IF, the field contains All Devices OR Mobile Devices OR Android AND iOS together. It must also be able to check wildcard as you can select multiple items therefore could be Android, PC/Mac, iOS in which case it should be true because both Android and iOS has been selected.
What should be the actual statement as this is the current one I'm using but I know you can't have wildcard string within this statement:
=IF(OR(C7="*-iOS*",C7="*-Android*",C7="Mobile Device",C7="All Delivery Methods",AND(C7="*-iOS*",C7="*-Android*")),"Mobile DTC/ALL","STB (VRP) HD, DEVICE (UVP) HD")
Thanks
Edit: If any of the following Scenarios is met and exist in Cell C7, then return the True statement.
Scenario 1: All Delivery Methods
Scenario 2: Mobile Devices
Scenario 3: Android AND iOS
Otherwise return the False statement.
Excel does not support wildcard statements on all formulas (see supported formulas), but you can achieve similar result, if you build a bit your formula.
Solution 1
E.g., try using FIND() with IFERROR(). FIND() will give you a number, telling you where the searched string is located.
Thus, =FIND("-Android","tell me more about -Android"), will give you a number.
If it does not find anything, it will give you a value error, which you may catch with IFERROR and return a specific value e.g. -1.
Then build the OR checking for values bigger than -1 and you will have what you need.
Solution 2
Another option is to use SEARCH(), which supoports wildcards the way you expect it:
=SEARCH("test*1";"aaaaaaaatestaaaa1")
will return 9. SEARCH in MSDN
Solution 3
In general, there are many ways to build this. As suggested in the comments by # ImaginaryHuman072889, you may use ISNUMBER(). It has the advantage, that it works quite ok with errors, thus you do not need an error catcher for it. Something like this will work ok:
=OR(ISNUMBER(SEARCH("a","b")),ISNUMBER(SEARCH("b","b")))
However, if you change the method from the first solution with an option returning 0 in case of error you would have something like this working as well:
=OR(IFERROR(SEARCH("a","b"),0),IFERROR(SEARCH("b","c"),0))
which is quite the same amount of formulas.
Solution 4
A really interesting solution, avoiding both OR() and IFERROR(), proposed by #barry houdini. It simply returns 0, if nothing from the results is found:
=COUNT(SEARCH({"a*a";"b*b";"c*c"},"I used to be abba fan."))
will return 2, because of a*a and b*b being found in abba. This is how to include the AND() of the original question of the OP:
=AND(
COUNT(SEARCH({"a*a";"b*b";"c*c"},"I used to be abba fan.")),
COUNT(SEARCH({"party*so";"am not"},"but now I am not."))
)

PEG.js and empty sequences

I'm trying to implement the TPTP grammar in PEG. It contains a rule for an empty sequence, which is used in many other rules, and PEG is rejecting this. A Google search finds https://github.com/pegjs/pegjs/commit/df154daafb9c6c952351493af02d3a55e0b05c59#commitcomment-10667420 which seems to be saying PEG by design does not allow empty sequence rules, which would make it unsuitable for implementing grammars such as TPTP which contain such. Do I understand this correctly, or am I missing something?
I believe it is still possible to do so, as explained in the posted link; instead of matching with nothing, you can match with "", and then return whatever you want to return :
Empty
= "" {return null;}

Resources