I have a table with clients and specific markers for each shop:
Client
Markers
Location
Jane
B,D,K,M,f,n,,+
Max
B,D,J,K,M,f,i,n,+
Ted
D,i,a,1,J,Y,K,M
Maria
C,D,J,K,M,n
Alex
A,D,K,M,f,i,n
Tom
A,D,K,M,f,m,o,y,+
Richard
R,D,J,K,M,f,i,n
X
A,D,K,M,f,n
Red
A,D,K,M,f,i,n,+
John
C,D,F,K,M,f,i,n,4
Lex
T,D,a,1,4,T,K,M
Ted
D,a,1,T,K,M
Jane
D,a,1,T,K,M
Another table contains the Locations:
marker
desc
A
New York
B
Amsterdam
C
London
H
Tokyo
Q
Paris
R
Vancouver
T
Sydney
Y
Auckland
Now I want to fill first table with locations but going wrong when first marker isn't the location marker. I used: =VLOOKUP([#Markers],TableLocations[marker],1,TRUE), I've tried the MATCH function but this gives the wrong number again.
So only works fine when first character in the marker column matches the marker in the location table.
To find only for first marker location from comma separated values from each cell in first column, you can use-
=XLOOKUP(TEXTBEFORE(B2,","),$G$2:$G$9,$H$2:$H$9)
For multiple location try-
=TEXTJOIN(", ",TRUE,FILTER($H$2:$H$9,ISNUMBER(XMATCH($G$2:$G$9,TOCOL(TEXTSPLIT(B2,",")),0))))
For dynamic spill array at one go, try-
=BYROW(B2:B14,LAMBDA(x,TEXTJOIN(", ",TRUE,FILTER($H$2:$H$9,ISNUMBER(XMATCH($G$2:$G$9,TOCOL(TEXTSPLIT(x,",")),0))))))
Try this, using tables and structured references (which you can change to normal addressing if you preferred, but the former are more dynamic).
In your comments you indicated there would be only one location per client; if you need more than one, please clarify
Edit: corrected missing structured reference
=INDEX(Location[desc],AGGREGATE(14,6,BYCOL(EXACT(TEXTSPLIT([#Markers],","),Location[marker]),LAMBDA(arr,XMATCH(TRUE,arr))),1))
Note: One can get case-sensitive matches using either EXACT or FIND functions. But, because of the null string in the list in your first row (note the doubled-comma in the Markers), FIND will always return a match for that, potentially causing an incorrect result
Related
I have a homework assignment where I have to merge data of two excel sheets by performing some cleansing operations using formulas.
Sheet 1:
OrderID | Full Name | Customer Status
1001 Waqar Hussain Silver
2002 Ali Moin Gold
Sheet 2:
OrderID | First Name | Last Name | Customer Status
A1003 Junaid Ali 2
A2004 Kamran Hussain 1
Sheet 3:(Combined Sheet) - Expected
OrderID | Full Name | Customer Status
1001 Waqar Hussain Silver
2002 Ali Moin Gold
1003 Junaid Ali Silver
2004 Kamran Hussain Gold
There are probably a lot of ways to do this. First make sure the data is cleaned. If you are already 100% positive the data is clean you can skip this step. If you aren't sure it's better to be safe than sorry. For each column create a new column using the CLEAN and TRIM functions to remove any non-printable characters and any extra spaces. Something similar to =TRIM(CLEAN(A2)). Then drag the formula for each cell.
After this in order to merge the data together we need something to join on. The full name seems to make the most sense. On sheet two we'll write a new function to join the first name and last name together. The =CONCAT formula should work.
=CONCAT(First Name, " " ,Last Name). Make sure to note the extra space added by the quote. That way it matches the Full Name from Sheet 1. Looks like we'll also need to strip out the letter from Order ID in sheet 2. I'm going to assume that all Order IDs are 5 characters long. If this isn't true then you'll need a different solution. You can use =RIGHT(A2,4). This will grab the right 4 characters from the text string.
At this point let's create a distinct list. Copy the Full Names from Sheet1 and Paste them on to sheet 3. Copy the Full Names we created on Sheet2 and Paste VALUES onto sheet 3 below the full names from sheet 1. Then select all the rows in the column and go to the Data tab. Click "Remove Duplicates". This will now generate a distinct list of values.
We can now merge the data together using an INDEX MATCH. There are lots of great tutorials on how to use INDEX match in combination. It's a little long to explain on this thread, but this is a great thread explaining how it works. It's worth taking 10 minutes to fully understand it because it is a formula you will use thousands of times throughout your life.
https://www.deskbright.com/excel/using-index-match/
Let me know if I can clarify anything.
Best,
Brett
The attached image (link: https://i.stack.imgur.com/w0pEw.png) shows a range of cells (B1:B7) from a table I imported from the web. I need a formula that allows me to extract the names from each cell. In this case, my objective is to generate the following list of names, where each name is in its own cell: Erik Karlsson, P.K. Subban, John Tavares, Matthew Tkachuk, Steven Stamkos, Dustin Brown, Shea Weber.
I have been reading about left, right, and mid functions, but I'm confused by the irregular spacing and special characters (i.e. the box with question mark beside some names).
Can anyone help me extract the names? Thanks
Assuming that your cells follow the same format, you can use a variety of text functions to get the name.
This function requires the following format:
Some initial text, followed by
2 new lines in Excel (represented by CHAR(10)
The name, which consists of a first name, a space, then a last name
A second space on the same line as the name, followed by some additional text.
With this format, you can use the following formula (assuming your data is in an Excel table, with the column of initial data named Text):
=MID([#Text],SEARCH(CHAR(10),[#Text],SEARCH(CHAR(10),[#Text])+1)+1,SEARCH(" ",MID([#Text],SEARCH(CHAR(10),[#Text],SEARCH(CHAR(10),[#Text])+1)+1,LEN([#Text])),SEARCH(" ",MID([#Text],SEARCH(CHAR(10),[#Text],SEARCH(CHAR(10),[#Text])+1)+1,LEN([#Text])))+1)-1)
To come up with this formula, we take the following steps:
First, we figure out where the name starts. We know this occurs after the 2 new lines, so we use:
=SEARCH(CHAR(10),[#Text],SEARCH(CHAR(10),[#Text])+1)+1
The inner (occurring second) SEARCH finds the first new line, and the outer (occurring first) finds the 2nd new line.
Now that we have that value, we can use it to determine the rest of the string (after the 2 new lines). Let's say that the previous formula was stored in a table column called Start of Name. The 2nd formula will then be:
=MID([#Text],[#[Start of Name]],LEN([#Text]))
Note that we're using the length of the entire text, which by definition is more than we need. However, that's not an issue, since Excel returns the smaller amount between the last argument to MID and the actual length of the text.
Once we have the text from the start of the name on, we need to calculate the position of the 2nd space (where the name ends). To do that, we need to calculate the position of the first space. This is similar to how we calculated the start of the name earlier (which starts after 2 new lines). The function we need is:
=SEARCH(" ",[#[Rest of String]],SEARCH(" ",[#[Rest of String]])+1)-1
So now, we know where the name starts (after 2 new lines), and where it ends (after the 2nd space). Assuming we have these numbers stored in columns named Start of Name and To Second Space respectively, we can use the following formula to get the name:
=MID([#Text],[#[Start of Name]],[#[To Second Space]])
This is equivalent to the first formula: The difference is that the first formula doesn't use any "helper columns".
Of course, if any cell doesn't match this format, then you'll be out of luck. Using Excel formulas to parse text can be finicky and inflexible. For example, if someone has a middle name, or someone has a initials with spaces (e.g. P.K. Subban was P. K. Subban), or there was a Jr. or something, your job would be a lot harder.
Another alternative is to use regular expressions to get the data you want. I would recommend this thorough answer as a primer. Although you still have the same issues with name formats.
Finally, there's the obligatory Falsehoods Programmers Believe About Names as a warning against assuming any kind of standardized name format.
I've got a input sheet that contains several different variables among which names, location and job. I want to display these values on different sheet, in which I summarize the data by group. So the input is as follows
A B C
1 NAME CIYY WORK
2 Bart NY Plumber
3 Emily NY Firefighter
4 Daniel LA Firefighter
5 Cohen NY Firefighter
6 Sasha LA Plumber
7 Dirk LA Plumber
8 Molly LA Plumber
Now I want to find the names from plumbers in LA, meaning it needs to look like this: (no #NA and no empty cells in between)
A
1 NAME
2 Sasha
3 Dirk
4 Molly
Should be easy with Indexing, Matching etc. However, the input is changed by simply deleting rows and adding rows. How can I achieve this without the risk of #REF errors. When Dirk would be deleted for instance, the output should look as follows:
A
1 NAME
2 Sasha
4 Molly
The solution on this page comes pretty close but leaves me with a #NA when the conditions are not met.
Although the values will be unique, I have a feeling that this solution for extracting unique values will be helpfull, but have been unable to combine them.
You need a two column match using INDEX and AGGREGATE.
=INDEX(A:A, AGGREGATE(15, 6, ROW(A$1:INDEX(A:A, MATCH("zzz", A:A)))/((B$1:INDEX(B:B, MATCH("zzz", A:A))=G$2)*(C$1:INDEX(C:C, MATCH("zzz", A:A))=H$2)), ROW(1:1)))
Fill down for successive matches. Use an IFERROR wrapper if you do not want error codes once you have run out of matches.
Try something like this, giving the whole range, cells and columns:
=INDEX(1:1048576,MATCH("Bart",A:A,0),MATCH("NY",2:2,0))
Thus, you can delete from A:A and from 2:2, the ranges would stay untouched.
I found a way to solve this issue by using INDRECT. I do not like this function however and would still advise to use the solution proposed by Jeeped.
The solution requires three steps.
Add an extra column with the two strings combined: i.e. D2 = B2&C2, and store the row of the first occurence of LAPlumber with =MATCH($M$17;D:D;0)
Now, iteratively, find the row of the next occurence of LAPlumber with: =IFERROR(MATCH($M$17;INDIRECT("$D$"&SUM($N$17:$N17;1)&":$D$16";TRUE);0);""). This function uses the previous row-numbers to redefine the array with INDIRECT. Note, the results of these values are relative to the previous row.
For each row, find the corresponding name: =INDEX($A$1:$C$15;SUM($N$17:N18);O$16). The sum function is used to combine the relative row-numbers.
In the picture I added a screenshot of step 3. Cell H3 contains step 1. The other cells in column H show the row numbers from step 2.
I've got two lists of people and I have to check if they're in both lists. The thing is that characters are not accepted in one of the lists ("-" for instance), and the person might have omitted a last name in case they have two.
For example:
A1 B2
John Paul John Paul Jones
Mary Williams Ryan Roberts
Ryan Roberts-Johnson Mary Williams
My formula is: =IFERROR(MATCH($A1,$B$1:$B$1215,0),IFERROR(MATCH(LEFT($A1,FIND(" ",$A1,1)),$B$1:$B$1215,0),"No Match"))
The idea is: if the name is the same, bring me the line where the person is. If not, look for the first name and see if you find someone with this first and bring it to me. If neither works, reply with "No Match".
But apparently the Match function only retrieves exact matches, so the First Name one doesn't work.
Is there any other way to solve this?
EDIT1: First finding: I can use the SUBSTITUTE formula to replace - with space and do the search once again.
Some of the things I did to save up some time (I probably spent more time figuring out/researching than I would have if I had done ~3500 entries manually, but the learning opportunity was great.)
What I wanted:
To search for for a cell with name + surname when I only had the surname.
What I did: I remembered about the wildcards and used them with VLOOKUP:
First I got the last name and added the star: ="*"&RIGHT($A1,LEN($A1)-FIND(" ",$A1,1))
=VLOOKUP(A1,$B$1:$B$1000,1,FALSE)
And it would try and find the first one. Before that I added a check to make sure that there weren't two people with the surname (so it wouldn't throw another person there) with a simple IF(COUNTIF($C$2:$C$2000,$D219)<=2, and then the rest of the formula.
Something else that I noticed and serves as a reminder: TRIM is very important, as some of the cells had two spaces in between first name/last and some one space after the last letter of the last name. Using TRIM to create a new column made me avoid a lot of mistakes I only took a while to notice.
I believe the case is solved.
You could create a temporary column extracting the first name from B column.
See this example.
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.