Excel Matching problem with logic expression - excel

(I understand Excel is only borderline programming)
I have a block of data that represents the steps in a process and the possible errors:
ProcessStep Status
FeesPaid OK
FormRecvd OK
RoleAssigned OK
CheckedIn Not Checked In.
ReadyToStart Not Ready for Start
I want to find the first Status that is not "OK".
I have attempted this:
=Match("<>""OK""", StatusRange, 0)
which is supposed to return the index of the first element in the range that is NOT-EQUAL (<>) to "OK"
But this doesn't work, instead returning #N/A.
I expect it to return 4 (index #4, in a 1-based index, representing that CheckedIn is the first non-OK element)
Any ideas how to do this?

I think this and other similar questions are completely legitimate programming questions (EDIT: see here: https://meta.stackexchange.com/questions/22922/which-site-do-excel-or-other-spreadsheet-formulas-belong-on/76767#76767). (It's probably a duplicate of some other StackOverflow question, though.)
You want to use an array formula:
=MATCH(TRUE,(StatusRange<>"OK"),0)
You need to enter this as an array formula, with Ctrl-Shift-Enter.
'MATCH' finds a value in a range or an array. Comparing a range to a scalar, as in '(StatusRange<>"OK")', returns an array of boolean values, so you're looking to match a value of 'TRUE'.
(The formula you posted was looking for a string literal with the value '<>"OK"'...)
If you ultimately want the value in the ProcessStep column, look at the help for the 'INDEX' or 'VLOOKUP' functions.

Related

TEXTSPLIT inside CHOOSECOLS inside another TEXTSPLT isn't working as expected

For an example, string A,B;C
I am doing this formula, =TEXTSPLIT(CHOOSECOLS(TEXTSPLIT("A,B;C",","),2),";")
TEXTSPLIT inside will give 2 element column array A and B;C
Then, CHOOSECOLS(*,2) over it will give B;C since it is the 2nd element in the array
It is ok till now. If I TEXTSPLIT over this with ; as a separator, then I expect again a 2-element column array B and C. Instead, I get only the first element as result, that is B. What is going wrong here? Is it a bug? I know if I do like TEXTSPLIT("A,B;C",{",",";"}), I will get my result, but I have a different sort of scenario. My actual text looks more like A,B,C;D,E,F, and I need D E F as array. If I do something like =TEXTSPLIT(CHOOSECOLS(TEXTSPLIT("A,B,C;D,E,F",";"),2),","), I get only D, instead of expected array
Another observation I had is that, if I spilt the operation into 2, say I put the result of CHOOSECOL in a cell, and do another TEXTSPLIT in another cell, I get the result. But I don't want to do it in another cell.
As I mentioned in my comment, simply replace CHOOSECOLS with INDEX:
=TEXTSPLIT(INDEX(TEXTSPLIT("A,B,C;D,E,F",";"),2),",")
For this case using the Implicit Intersection operator (#) solves your problem. Just add to your formula the #-operator before CHOOSECOLS:
=TEXTSPLIT(#CHOOSECOLS(TEXTSPLIT("A,B;C",","),2),";")
Output:
CHOOSECOLS returns 1x1 array and TEXTSPLIT as its name indicates, it operates at a text (string) level. The #-operator converts the array into a string. We would expect here that Excel would do the cast for us, but it doesn't happen.
You can check the above rationale by looking at the steps Excel carries out via Evaluate Formula functionality:
The intermediate result after CHOOSECOLS call`:
The intermediate result after #-Operator:
It is the same intermediate result as #JosWoolley's answer using INDEX.
Try-
=TEXTSPLIT(TEXTJOIN("",,CHOOSECOLS(TEXTSPLIT("A,B;C",","),2)),";")
CONCAT() may also work.
=TEXTSPLIT(CONCAT(CHOOSECOLS(TEXTSPLIT("A,B;C",","),2)),";")

Excel formula to sum an array of items from a lookup list

I'm trying to make my monthly transaction spreadsheet less work-intensive but I'm running up against problems outputting my category lookups as an array. Right now I have a table with all my monthly transactions and I want to create another table with monthly running totals. What I've been doing is manually summing each entry from each category, but I'd love to automate the process. Here's what I have:
=SUM(INDEX(Transactions[Out], N(IF(1,MATCH(I12,Transactions[Category],FALSE)))))
I've also tried using AGGREGATE in place of SUM but it still only returns the first value in the category. The N(IF()) was supposed to force INDEX to return all the matches as an array, but it's not working. I found that trick online, with no explanation of why it works, so I really don't know how to fix it. Any ideas?
Just in case anyone ever looks at this thread in the future, I was able to find a simpler solution to my problem once I implemented the Transactions[Category]=I12 method. SUM, itself will take an array as an argument, so all I had to do was form an array of the values I wanted to keep from Transactions[Out] range. I did this by adjusting the method Ron described above, but instead of using 1/(Transactions[Category]=I12 I used 1/IF(Transactions[Category]=I12, 1,1000) and surrounded that by a FLOOR(*resulting array*, .01) which rounded all the thousandth's down to zero and didn't yield any #DIV/0! errors.
Then! I realized that the simplest way to get the actual numbers I wanted, rather than messing with INDEX or AGGREGATE, was to multiply the range Transactions[Out] by the binary array from the IF test. Since the range is a table, I know they will always be the same size. And SUM automatically multiplies element by element and then adds for operations like this.
(The result is a "CSE" formula, which I guess isn't everyone's favorite. I'm still not 100% clear on what it means: just that it outputs data in a single cell, rather than over multiple cells. But in this context, SUM should only output a single number, so I'm not sure why I need CSE... A problem for another day!)
In your IF, the value_if_true clause needs to return an array of the desired row numbers from the array.
MATCH does not return an array of values; it only returns a single value which, with the FALSE parameter, will be the first value. That's why INDEX is only returning the first value.
One way to return an array of values:
Transactions[Category]=I12
will return an array of {TRUE,FALSE,FALSE,TRUE,...} depending on if it matches.
You can then multiply that by the Row number to get the relevant row on the worksheet.
Since you are using a table, to obtain the row number in the data body array, you have to subtract the row number of the Header row.
But now we are going to have an array which includes 0's for the non-matching entries, which is not good for us as a row number argument for the INDEX function.
So we get rid of that by using the AGGREGATE function with the ignore errors argument set after we do change the equality test to 1/(Transactions[Category]=I12) which will create DIV/0 errors for the non-matchers.
Putting it all together
=SUM(INDEX(Transactions[Out],AGGREGATE(15,6,1/(Transactions[Category]=I12)*ROW(Transactions)-ROW(Transactions[#Headers]),ROW(INDIRECT("1:"&COUNTIF(Transactions[Category],$I$12))))))
You may need to enter this with CSE depending on your version of Excel.
Also, if you have a lot of these formulas, you may want to change the k argument for AGGREGATE to use the INDEX function (non-volatile) instead of the volatile INDIRECT function.
=SUM(INDEX(Transactions[Out],AGGREGATE(15,6,1/(Transactions[Category]=I12)*ROW(Transactions)-ROW(Transactions[#Headers]),ROW(INDEX($A:$A,1,1):INDEX($A:$A,COUNTIF(Transactions[Category],$I$12),1)))))
Edit
If you have Excel/O365 with dynamic arrays and the FILTER function, you can greatly simplify the above to the normally entered:
=SUM(FILTER(Transactions[Out],Transactions[Category]=I12))

Excel - lookup multiple values in a string and return first one

I need a function to look up organizational abbreviations in a text and return the first one thas shows up. I tried to solve that with a nested if clause but it has a logical error.
=IF(ISNUMBER(SEARCH("BZC";I5)); "Finanz"; IF(ISNUMBER(SEARCH("AZC" /1";I5));"IT";""))
It looks up BZC and AZC as desired and return the organization name. However, it does no return the first match in a string. Since BZC is the first lookup it will always be returned if it is in the string, eventhoug it might not be the first org abbreviation.
What functionality of excel can be used to solve this issue? I basically need an array of variables that a function should do a look up and return the first one that is found.
Edit:
I tried to implement the formula form Justyna MK. Besides the fact, that I still need to figure out the meaning of the formula (iferror, mid, small) It returns #N/A in my example. Is there a certain reason for that?
I hope I understood your request correctly. Here's an Array formula for you to try (enter using Ctrl + Shift + Enter):
=CHOOSE(MATCH(MID(A1,SMALL(IFERROR(SEARCH({"BZC","AZD","xxx"},A1),""),1),3),{"BZC","AZD","xxx"},0),"Finanz","IT","Other")
You'd probably need to change , to ; in order to match your regional settings.
You can easily expand the list of search items by modifying the contents of curly brackets { } and also by expanding the MATCH results at the very end of the formula.
Here's some sample result:
Edit: here's an adjusted solution that ignores the length of your code (the previous solution was assuming that the code is always 3-characters long). This time it's not an array formula so you can enter it as it is.
Also, I suspect that you should not change , to ; inside the curly brackets (it would modify the formula from column to row delimiter and thus it will stop working). The remaining , can be transformed to ;, if that makes sense.
=CHOOSE(MATCH(TRIM(LEFT(SUBSTITUTE(RIGHT(A1,LEN(A1)-SUMPRODUCT(SMALL(IFERROR(SEARCH({"BZC","AZD","XYZX/1","NP-HSD"},A1),""),1))+1)," ",REPT(" ",255)),255)),{"BZC","AZD","XYZX/1","NP-HSD"},0),"Finanz","IT","Other1","Other2")
The result:

Multiple "IF" statements in Excel but using the same phrase look up

I can not figure out how to put 2 of the same IF statement but with a different result in case is not there then to do the second combination.
=IF(C2737="XXX_SF",INDEX(TMParking_8_24!A:A,MATCH(Tracker!J2737&"xxxshortform",TMParking_8_24!F:F,0)),
The above formula is what I'm looking for. Incase xxxshrotform is not there I would like it to search for a xx5shortform. So I added the below to the second part of the formula:
INDEX(TMParking_8_24!A:A,MATCH(Tracker!J2737&"xx5shortform",TMParking_8_24!F:F,0)))
Within the INDEX the xx5shortform exists but it is not finding it.
Use the IFERROR function to pass control over to a second MATCH function if the first is not found.
=IF(C2737="XXX_SF",
INDEX(TMParking_8_24!A:A,
IFERROR(MATCH(Tracker!J2737&"xxxshortform",TMParking_8_24!F:F,0),
MATCH(Tracker!J2737&"xxshortform",TMParking_8_24!F:F,0))), "")
There was no indication as to what to return if C2737 does not equal XXX_SF nor what to do if the second match does not work.

Array evaluation of find_text argument in SEARCH() function

Say I have the following:
Entering the following formulas in cell C1 and then clicking Evaluate Formula->Evaluate produces very different results:
Formula 1: B$1:B$5 evaluates as non-array
{=SEARCH(B$1:B$5,A1)}
Formula 2: B$1:B$5 evaluates as an array
{=IF(SEARCH(B$1:B$5,A1),"")}
Why, exactly, is this? What is the cause of this behavior? If possible, please provide other examples using other Excel functions to illustrate what is happening here.
Parenthetically:
My question came about while experimenting with the accepted answer to this question.
In general, an array of values will only be returned by a worksheet function given that the following two conditions are satisfied:
1) The formula in question is either in itself capable of returning an array of values, or else is contained within a larger set-up of several functions, one or more of those which precede the function in question (and therefore act upon it) having that property. Whether that capability is something which requires coercion (i.e. via array-entry (CSE)) or is an in-built feature of the function is not important in terms of the answer you are seeking.
2) The array generated must be passed to a further function for processing. Excel is more teleological than you think: it has no great belief in returning an array of values as an end in itself.
As for your example, it's not that SEARCH, when array-entered, isn't capable of processing arrays (it is). It's more that there is no further function incited which is to act upon that array. In the IF version, there is precisely that, though again, if you process that one more time you'll find that your current array is reduced to just the first element in that array. Wrap a further function around the IF, e.g. SUM, and you'll be able to go one step further, and so on and so on.
And here is a major difference between evaluating formulas via the Evaluate Formula tool, and repeated "evaluation" via selecting various parts of the function in the formula bar and pressing F9.
The latter will always return an array of values, whether the above two conditions are satisfied or not. However - and not many people realise this - the "evaluation" so obtained can, ultimately, lead to incorrect results, and so should only be used providing one is aware of its limitations.
Take the following example, for instance:
With A1:A10 empty, the formula:
=SUMPRODUCT(0+(A1:A10=""))
correctly returns 10.
Now select just the part A1:A10 in the formula bar and press F9. Excel, being forced to "evaluate" the range, returns:
=SUMPRODUCT(0+({0;0;0;0;0;0;0;0;0;0}=""))
which, on further processing, results (correctly, it would seem) in the quite different result of 0.
Regards

Resources