Excel, equation to output either 'Agent name', "COPY", or "Not Found" - excel-formula

I had an excel test that I didn't do particularly well on, but this one question had me stumped. I need an equation that takes the name in this list and outputs the agent name in 'first.initial' or "COPY" or "NOT FOUND"
Sheet 1:
Agent 
Adam.m
Agent 
David.e
Agent 
Joe.A 
Agent
Ben.B
Agent
Kat.C
Agent
Training.22
Agent
Admin
Convert these names: Correct output:
David Everit David.e
Joe a. Joe.A
Ben Ben.B
Sam p. NOT FOUND
Training 22 Training.22
David E. COPY
Kat Cathy Kat.C
David D. NOT FOUND
Adam.S NOT FOUND
The equation I submitted that my teacher said was wrong was:
=IFNA(IF(COUNTIF(Sheet1!A:A, A3)>1, "COPY", INDEX(Sheet1!A:A,MATCH(A3&"*",Sheet1!A:A,0))),"Not Found")

Well here's the thing.
You are checking the original data source for the name, pre-conversion. I must admit, the COPY was a bit misleading at first but I caught on later.
You are also wrapping the whole thing in a single logical... ISNA()... Your formula can only return TRUE, FALSE or an error from this.
Putting the wrapped ISNA() aside, this means that for your formula the majority of these entries are Not Found. True, if you instead had a list of data that had already been manipulated this would almost succeed. But you are checking for the "COPY" in the wrong data...
Your first task here would be to manipulate the data to the desired format of '[Firstname].[initial]' // So assuming that the first set of characters in the cell is always going to be the forename you can use a combination of something like:
=LEFT(A2,SEARCH(" ",A2)-1) - Gets the forname by returning the left-most characters to a length of the first space position minus 1.
=RIGHT(A2,LEN(A2)-SEARCH(" ",A2)) - Gets all characters to the right of space by determining the legth from the right as the total cell length minus the position of space.
You will need to perform a logical on the second scenario though as you want a single letter is it is a word or the entire thing if it is a number:
=IFERROR(RIGHT(A2,LEN(A2)-SEARCH(" ",A2))-0,MID(A2,SEARCH(" ",A2)+1,1))
So what i have done here is attempt to remove 0 from the string, if it is a number, this will succeed and return that number to us. If it fails it will produce an error and progress on to the second clause, giving us the single character.
You can combine these using simple string building or a concatenate clause:
=LEFT(A2,SEARCH(" ",A2)-1)&"."&IFERROR(RIGHT(A2,LEN(A2)-SEARCH(" ",A2))-0,MID(A2,SEARCH(" ",A2)+1,1))
or
=CONCATENATE(=LEFT(A2,SEARCH(" ",A2)-1),".",IFERROR(RIGHT(A2,LEN(A2)-SEARCH(" ",A2))-0,MID(A2,SEARCH(" ",A2)+1,1))
So now we are almost there, except that Ben and Adam are producing errors as there isn't a space character that can be found. We'll handle that error now so that we can move on to our search:
=IF(ISERROR(SEARCH(" ",A2)),A2,LEFT(A2,SEARCH(" ",A2)-1)&"."&IFERROR(RIGHT(A2,LEN(A2)-SEARCH(" ",A2))-0,MID(A2,SEARCH(" ",A2)+1,1))) - if you cannot find a space character then we will have the whole cell, otherwise, we will use the space to build the search term.
Now that we have the text formatted in the way that we want it, we can move forward to do the search, the order is important as we will need to first check our results from above for duplicates and print "COPY" where found, then look for the match and return it if it's there and lastly return "NOT FOUND" if we cannot find it.
We are going to need the use of the wildcard in order to satisfy the entry Ben. So let's show the logic first then throw the whole formula together:
=IF(COUNTIF($B$1:B1,[SearchTermFormula]),"COPY", - This part of the formula uses countif to check whether the search term already exists above it, returns "COPY" if so and will continue to the next part, the absolute referencing ($$) is important so that the range updates as you copy the formula down but keeps the first cell locked.
IF(ISNUMBER(MATCH([SearchTermFormula]&"*",Sheet1!$A$1:$A$14,0)),[SearchTermFormula],"NOT FOUND") - So this works to show the basic logical, again we use IF() to determine whether a match can be made as a number would be returned if so. We can then return the search term itself or "NOT FOUND".
A more elegent version of this part though would be:
IFERROR(INDEX(Sheet1!$A$1:$A$14,MATCH([SearchTermFormula]&"*",Sheet1!$A$1:$A$14,0)),"NOT FOUND"))
As it actually returns the result from sheet1 as well as making us use the [SearchTermFormula] 1 less time, using less resources.
INDEX() essentially maps the range as a 1 based array. What that means is the first cell in the range is considered an address of 1,1. You can think of it adding X and Y axis but 0,0 is outside the top left and the Y axis is inverted.
So we get it to index column A and MATCH returns the relative position, as the row's are equally sized, the relative position will be the row number we are after so we get the result returned or an error value, so IFERROR() leads us on to produce "NOT FOUND".
Putting all that together we have:
=IF(COUNTIF($B$1:B1,IF(ISERROR(SEARCH(" ",A2)),A2,LEFT(A2,SEARCH(" ",A2)-1)&"."&IFERROR(RIGHT(A2,LEN(A2)-SEARCH(" ",A2))-0,MID(A2,SEARCH(" ",A2)+1,1))))>0,"COPY",IFERROR(INDEX(Sheet1!$A$1:$A$14,MATCH(IF(ISERROR(SEARCH(" ",A2)),A2,LEFT(A2,SEARCH(" ",A2)-1)&"."&IFERROR(RIGHT(A2,LEN(A2)-SEARCH(" ",A2))-0,MID(A2,SEARCH(" ",A2)+1,1)))&"*",Sheet1!$A$1:$A$14,0)),"NOT FOUND"))
Sorry for the essay but I hope it helps you understand the scope

Related

How do I get first n non-zero values in a row?

I currently have this formula but it returns the non-zero values in the opposite order I want.
Here's the formula:
=INDEX($R275:$BE275,LARGE(IF($R275:$BE275<>0,COLUMN($R275:$BE275)- MIN(COLUMN($R275:$BE275))+1),COLUMNS($A:A)))
This returns the first non-zero value from column BE looking back towards R, when I want it to work the other way, the first instance from right to left. When I draft the formula to the right, I want it to pick up the next non-zero value, right to left.
If I could get this figured out, as well as how to return the column header as well, that would be great.
Screenshot/here refer.
The formula you provided returns the last non-zero value which is also what you state you're trying to find:
"I want...the first instance from right to left."
To avoid ambiguity, I provide solutions for the first such occurrence (and corresponding heading), and a revised method to determine the last occurrence (or first occurrence "from right to left").
First occurrence
(working from left to right)
Function can be simplified significantly to the following:
=INDEX(A2:H2,0,MATCH(1,--(A2:H2<>0),0))
Corresponding heading:
=INDEX($A$1:$H$1,0,MATCH(1,--(A2:H2<>0),0))
Per #ScottCraner, this also works (albeit uses the same unnecessarily long function):
=INDEX($R275:$BE275,SMALL(IF($R275:$BE275<>0,COLUMN($R275:$BE275)- MIN(COLUMN($R275:$BE275))+1),COLUMNS($A:A)))
Last occurrence
Revised function to consider (requires Office 365 compatible version of Excel, and customisation to return corresponding heading)..
=LET(reverse,INDEX(A2:H2,0,SEQUENCE(1,COUNTA(A2:H2),COUNTA(A2:H2),-1)),INDEX(reverse,MATCH(1,--(reverse<>0),0)))

Find function works weird

Well... It's really weird, but let me explain.
I am trying to get the country string from the A1. So i should get the position of second # and after that i can use MID and get the country. But, well.. Please check out.
Here is the situation:
A1: "Abergwili# Wales# United Kingdom"
B1: =FIND("#";A1;1) > Result: 10 >> Correct!
C1: =FIND("#";A1;B1) > Result: 10 >> What??? It should output 7! I really don't get it!
Any help?
The FIND function in Excel uses the last argument as the string index to start searching from. If that index matches the target string, it will return that index again. There are a few options:
You could restructure your current FIND function to start at the character after B1's result, which will produce the formula =FIND("#",A1,B1+1). To get the position relative to B1, you could subtract the value of B1, which creates =FIND("#",A1,B1+1)-B1. (This is similar to JvdV's answer)
You could explicitly search through the remaining substring after the first match using the RIGHT function, which transforms the original function to =FIND("#",RIGHT(A1, LEN(A1)-B1)), which automatically returns the result relative to the last match. To get the absolute result, you could add the value of B1 back in, creating =FIND("#",RIGHT(A1, LEN(A1)-B1))+B1.
Good luck!
(Side note - You probably want commas instead of semicolons, unless your Excel is set up to work with them. My Excel complained mightily when testing with ; characters)

Excel formula to search partial match and align row

I have 2 column data in Excel like this:
Can somebody help me write a formula in column C that will take the first name or the last name from column A and match it with column B and paste the values in column C. The following picture will give you the exact idea what I am trying to do. Thanks
Since your data is not "regular", you can try this formula which uses wild card to look for just the last name.
=INDEX($B$1:$B$4,MATCH("*" &MID(A1,FIND(" ",A1)+1,99)&"*",$B$1:$B$4,0))
It would be simpler if the first part followed some rule, but some have the first initial of the first name at the beginning; and others at the end.
Edit: (explanation added)
The FIND returns the character number of the first space
Add 1 to that to get the character number of the next word
Use MID to extract that word
Use that word in MATCH (with wild-cards before and after), to find it in the array of email addresses. This will return it's position in the array (row number)
Use that row number as an argument to the INDEX function to return the actual email address.
If you want to first examine the email address, you will need to determine which of the letters comprise the last name. Since this is not regular according to your example, you will need to check both options.
You will not be able to look for the first name from the email, as it is not present.
If you can guarantee that the first part will be follow the rule of one or the other, eg: either
FirstInitialLastName or
LastNameFirstInitial
Then you can try this:
=IFERROR(INDEX($B$1:$B$4,MATCH(MID(A1,FIND(" ",A1)+1,99)& LEFT(A1,1) &"*",$B$1:$B$4,0)),
INDEX($B$1:$B$4,MATCH( LEFT(A1,1)&MID(A1,FIND(" ",A1)+1,99) &"*",$B$1:$B$4,0)))
This seems to do what you want.
=IFERROR(VLOOKUP(LOWER(MID(A1,(SEARCH(" ",A1)+1),LEN(A1)))&LOWER(MID(A1,1,1))&"*",$B$1:$B$4,1,FALSE),VLOOKUP(LOWER(MID(A1,1,1))&LOWER(MID(A1,(SEARCH(" ",A1)+1),LEN(A1)))&"*",$B$1:$B$4,1,FALSE))
Its pretty crazy long and would likely be easier to digest and debug broken up into columns instead of one huge formula.
It basically makes FLast and FirstL out of the name field by splitting on the space.
LastF:
=LOWER(MID(A1,(SEARCH(" ",A1)+1),LEN(A1)))&LOWER(MID(A1,1,1))
And FirstL:
=LOWER(MID(A1,1,1))&LOWER(MID(A1,(SEARCH(" ",A1)+1),LEN(A1)))
We then make 2 vlookups for these by using wildcards:
LastF:
=VLOOKUP([lastfirst equation from above]&"*",$B$1:$B$4,1,FALSE)
And FirstL:
=VLOOKUP([firstlast equation from above]&"*",$B$1:$B$4,1,FALSE)
And then wrap those in IfError so they both get tried:
=IfError([firstLast vlookup],[lastfirst vlookup])
The rub is that's going to be hell to edit if you ever need to, which is why I suggest doing each piece in another column then referencing the previous one.
You also need to be aware that this answer will get tripped up by essentially the same name - e.g. Sam Smith and Sasha Smith would both match whatever the first entry for ssmith was. Any solution here will likely have the same pitfall.

finding dynamically a match between two tables; one has text and the other the search pattern

EXCEL - finding a match between two tables
https://drive.google.com/folderview?id=0B2WLaA0HlUBVWnlwaFRGMmdwaVU&usp=sharing - excel file
FILE : vraag.xlsm
I would like to make a dynamically solution, for searching a text pattern from one table if it is also in the text of an other table (in different columns).
(Dynamically, I mean if the are elements are added, deleted, changed)
So searching if one the elements from column 'ID_type' can be found in the text of column 'element'
!
table A [T_example] : in a column contains tekst (within maybe one
of the elements of the other table)
table B [T_rec_by_type] : contains several possible strings
edited : next seems to be a wrong approach : MATCH()
=IF(ISNA(VLOOKUP(A23;T_rec_by_type[ID_type];1;FALSE));FALSE; "File found in row " & MATCH(A23;T_rec_by_type[ID_type];0))
In the first example (exactly match, so not as search pattern), it works.
But the idea is to search in the text to find the searchpattern ... and return via VLOOKUP a value from an other column (in this stadium just ID_type).
A possible solution found in an answer online
EXCEL - Find category by searching keyword from other worksheet
https://drive.google.com/folderview?id=0B2WLaA0HlUBVWnlwaFRGMmdwaVU&usp=sharing - excel file
FILE : SearchAMatchtingStad.xlsm
In the hope to find a solution ... for my case via this answer, I tried it out but unfortunately without succes.
So what am I doing wrong?
(I tried it first with tables, columns and ...
=IFERROR(IF(INDIRECT("Sheet1!A"&MAX(IF(ISERROR(SEARCH(CONCATENATE("*";Table1[[stad 1]:[stad 3]];"*");[#shop]))+(Table1[[stad 1]:[stad 3]]="");0;ROW(Table1[[stad 1]:[stad 3]]))))=Table2[[#Headers];[antwerpen]];[#sales];"");"Not found")
to figure out my fault/problem, why it doesn't work ...
I did it just by one cell, but without luck)
= IFERROR( IF( INDIRECT("Sheet1!A" & MAX( IF( ISERROR( SEARCH("*"&Sheet1!$B$2:$D$4&"*";$B8)) + (Sheet1!$B$2:$D$4="") ; 0 ; ROW(Sheet1!$B$2:$D$4)))) = D$7;$C8; "") ; "Not found")
A small remark ENTERING AN ARRAY FORMULA: press the CTRL SHIFT and ENTER
In a way it seems that there is an issue with array formulas
So when I do a one to one 'search' it seems to work =SEARCH("*"&B2&"*";$B8)
But when I do it with an array (despite it is still an array but with "\" instead of { "genk" ; "mol" ; "leuven" ; ... }), it seems to be a problem, or not working the way I wished. =SEARCH(CONCATENATE("*";OR(Table1[[stad 1]:[stad 3]]);"*");B8)
So I give it a last try.
But with OR or without gives the same result.
And to check if it maybe a problem is with CONCATENATE, I created a simular table with the wildcard already implemented.
Maybe ONE important thing, I forget to say there is always a space in front of the ID_TYPE.
And the ID_TYPE itself followed by a number (of maximum 3 characters) and a space.
You may have to change ; to , and , to . according to your local.
#Tom Sharpe
Thanks for your answer, but when I tried it out, it doesn't work.
Maybe ONE important thing, I forget to say there is always a space in front of the ID_TYPE.
And the ID_TYPE itself followed by a number (of maximum 3 characters) and a space.
I used 0 - in case default, not found.
Correct Tom, if I use '=FORMULATEXT(B35)', I see the formula is surrouded by { and }.
So I don't understand what I'm doing wrong.
And it worked fine at your place, you did it with my spreadsheet? Strange.
I uploaded the file changed as "vraag2.xlsm"
#user3616725
Maybe ONE important thing, I forget to say there is always a space in front of the ID_TYPE.
And the ID_TYPE itself followed by a number (of maximum 3 characters) and a space.
put new file in the shared folder : vraag2.xlsm
Here's another solution without using Regex. It tests each element in the first column of the table in A1:A7 (ID_type) using FIND to see if it is a substring of the element in A25 and below. The row numbers of any matching cells in a1:a7 are stored in an array. Because you want the first match, it uses MIN to find the lowest row number. If there is no match, it stores a reference to a cell which is outside the table, i.e. A8. I'm using FIND because I don't want to match lowercase, otherwise ... "3 spots plafond" would match with A because it has an 'a' in it.
If you enter the array formula in (say) d25 and pull it down, it will give the row number of the first matching cell in the table. If you enter the second formula in (say) e25 and pull it down, it will give the corresponding cell in another column of the table, in this case column B (type).
The first formula in structured form is:-
=MIN(IF(ISERROR(FIND(T_rec_by_type[[#Data],[ID_type]],A25)),ROW(A$8),ROW(T_rec_by_type[[#Data],[ID_type]])))
and the second one in structured form is
=IFERROR(INDEX(T_rec_by_type[[#All],[type]],D25),"Not found")
The formulae in ordinary notation (which I find a bit easier) are
=MIN(IF(ISERROR(FIND(A$2:A$7,A25)),ROW(A$8),ROW(A$2:A$7)))
and
=IFERROR(INDEX(B$1:B$7,D25),"Not found")
ROW(A$8) above is just a not very subtle way of getting a row number which is greater than that of any rows in the table. You could just use an arbitrary large number, or perhaps add a Totals row to the first table and use that to get the reference.
I haven't been able to work out why your vlookup didn't work with the table (it's OK if I copy the cells somewhere else), perhaps other people can comment.
using REGEX functions from MORFUNC ADDON*
I used your vraag.xlsm shhet that you linked to.
In cell C25 put: =REGEX.MID(TABLE12[[#ThisRow],[element]],MCONCAT(T_rec_by_type[ID_type],"|"),,TRUE)
this will give you the first (left-most) of the "keywords" that appears in the corresponding "element" cell.
This is almost there. but you say that the "SSR" sensor is more important than V, so that's the one that should be displayed if they both appear.
this is not pretty, but will work (if u provide more details on possible "ID_type"s and the order of things in "element" field i might be able to come up with something more elegant...) :
paste in cell D25:
=IF(REGEX.COMP(Table12[[#This Row],[element]],A$2,TRUE),A$2,IF(REGEX.COMP(Table12[[#This Row],[element]],A$3,TRUE),A$3,IF(REGEX.COMP(Table12[[#This Row],[element]],A$4,TRUE),A$4,IF(REGEX.COMP(Table12[[#This Row],[element]],A$5,TRUE),A$5,IF(REGEX.COMP(Table12[[#This Row],[element]],A$6,TRUE),A$6,IF(REGEX.COMP(Table12[[#This Row],[element]],A$7,TRUE),A$7,""))))))
copy C25 and D25 down, for the other elements
MOREFUNC ADDON
Morefunc Addon is a free library of 66 new worksheet functions.
HERE is some information (by original author)
here is the last working download link I found
here is a good installation walk-through video

Excel can't find a value even though it exists within the worksheet

this is my first post so i am sorry if this is confusing at all. I am trying to use a vLookup to run a comparative analysis between two reports. I am using a part number as a reference and trying to return the cost associated with the part from one of the two reports. So, the first issue that I encountered was due to the fact that some of the part numbers had letters in them and some didn't, so to be consistent I used the following code to clean up the part numbers:
IFERROR(VALUE(F11&C11), F11&C11)
where F11 and C11 are two components of the part number that needed to be concatenated to generate the full number. Now, the vLookup will not return anything except for #N/A for a few of the part numbers that are actually in the sheet. All of the part numbers are formatted the same for the 892 part numbers that I am searching for but get a returned value on 571 of the 892 part numbers but of the remaining 321 part numbers that did not have a return, about a third actually exist in my sheet. Lastly and for example, part number 110874402 exists in both sheets but gets a #N/A from the vLookup. When I copy the value from one sheet and search it in the other sheet using Ctrl + F, I get the following:
(I have an image to show but apparently can't post it without a reputation of 10 or more...oops)
The highlighted cell shows that the value exists but Excel can't find it. Does anyone have any ideas why this is or what I could be doing differently? I've been having this issue for a few months now on separate projects and haven't found any resolution.
Thanks in advance,
try =VLOOKUP("*"&TRIM(F569)&"*", BOBJ!$D$3:$P$2237, 7, FALSE) - I have a feeling spaces may have crept around the part numbers, which means that the exact match will not work.
The TRIM takes the spaces from the cell you are looking at, and the "*"'s will allow a wildcard search - note that this also means that CAT would also match CAT1, but if it produces results where there were none before, it gives you something to check for.

Resources