I am trying to build an excel formula, that will reference another column based off of the first word. The first word does not need to have an exact match, it will however, need to find words that are “very similar” to each other. If the words, are not a close match, I would need the original cell to show in the results tab (as seen below). I would need the excel formula to do the following:
Column A......….Column B (with desired info)......….Column C (results)
Upper Body...……….Upper...………………......………………......……Upper
Upper Arms...…………….....………………......………………......…… Upper
Upper Legs...…………….....………………......………………......…… Upper
Lower Legs...…………….....………………......………………......…… Lower Legs
I have tried, the VLookup with the range lookup, as “True”, however the above example will be a lot more complex, with the real data set I am using. Any help would be greatly appreciated.
You can extract first word and then use Index() and Match().
You will first need to get the first word of column A. You can do this by splitting column A by a delimiter (split after first space) or by using a formula.
Formula example: =IF(ISERR(FIND(" ",A2)),"",LEFT(A2,FIND(" ",A2)-1)) where A2 is the cell you are looking at.
When you have that value you can then use =Index(Match()) to look up value. Match allows for fuzzy matching as long as you do not set the last parameter to 0.
Related
I have some data in Col"K" where from i am just trying to get the left characters as i tried in Col"H" using formula.
But what i used is Left function like =Function(cell,10) that is not the correct way characters can be more than 10 or less than 10.
1st formula should be dynamic to get the left numeric values.
2nd Formula should copy and paste the same numeric values until next value comes as available in Col"I"
I tried to make it but what i can do is to create left function and do not know how to develop it dynamic.
Any help will be appreciated.
Sheet Link
https://docs.google.com/spreadsheets/d/1nJZeWDZ0EWgmWB0z17xU93fjIOFsu46EL37IJqJzZ_0/edit?usp=sharing
This formula should do the job.
[J2] =IFERROR(TRIM(LEFT(L2,FIND("-",L2)-1)),J1)
Note that it will fail if placed in row 1 and there is no dash in L1.
Use find function to get numeric characters length.
=iferror(trim(left(L3,FIND("-",L3)-1)),M2)
Here we are finding the separator "-" in your text and it gives us index number of separator.
Then picking text from start to before index number i.e., Numeric value and removing blank spaces, if any, using trim function. If we don't have number/separator in the text then showing previous cell value using iferror function. So, Make sure first row always has numeric value.
Same has implemented in the sheet you have shared
As per the latest data I have updated my answer as below , now it is checking output is numeric or not:
=IF(COUNT(FIND({0,1,2,3,4,5,6,7,8,9},J9))=0,K8,TRIM(LEFT(J9,FIND("-",J9)-1)))
Worksheet 1 contains a list of names and quantities that are updated daily below (i.e. AAA is a name and 1 is the quantity):
Name
look.AAA :1
look.BBB :2
look.CCC :3
I'm trying to get the table in Worksheet 2 to search for text within the column range and extract the quantities using formulas.
So far i've tried search, lookup, vlookup, find & match functions (and combinations of these) but everything produces errors. I've tried to see if someone else has done something similar but I could not find anything online:
=match(aaa,sheet1!A2:A4)
I'm expecting to retrieve the quantity number by searching for the name and finding it within the text of a cell range.
You are on the right track. There are several ways to do this. VLOOKUP, LOOKUP, and a combination INDEX/MATCH are some of the more common methods. Since you started with match, this solution will carry on with your methodology.
Match is going to tell you which row of the selected range you are looking for. What you need to do is return the value from the same row but in a difference column. For starters we just need to tweak you match formula. Since you are looking for a string (text), and are hard coding it, the text value should be in quotes. Your Match formula becomes:
MATCH("AAA",sheet1!A2:A4,0)
That zero at the end tells match you are looking for an exact match. The other possible values for 0 are 1 and -1, but you need to have a sorted list and they will do an approximate match going forward or in reverse respectively. For a reverse search the list needs to be sorted in reverse order.
Now that you have a formula for the correct row within the selected range, you can use that in an INDEX formula from a matching size range somewhere else in the workbook. In this case you have it in the adjacent column. Your ultimate formula becomes:
INDEX(Sheet1!B2:B4,MATCH("AAA",sheet1!A2:A4,0))
Alternative options
VLOOKUP
VLOOKUP("AAA",sheet1!A2:B4,2,0)
See below revised solution:
I have given a name "Look_Rng" to the list which contains the original data.
My logic is to use a combination of MID, LEN and FIND functions to extract a number range and a text range from the original range first:
Number Range: {=--MID(Look_Rng,FIND(":",Look_Rng)+1,LEN(Look_Rng)-FIND(":",Look_Rng))}
which will return {1;20;300;3;2}
Text Range: {=MID(Look_Rng,MIN(IFERROR(FIND(D2,Look_Rng),33000)),LEN(D2))}
which will return {"AA";"oo";"CC";"e.";"lo"}
Then use MATCH function to find the position of the given name in the Text Range. For instance, if you are looking for CC in the Text Range, it will return 3.
Lastly, use INDEX function to locate the value in the corresponding position in the Number Range. For instance, CC is in the 3rd place in the Text Range, so its corresponding position in the Number Range is 300.
The full formula is quite long, and you MUST press Ctrl+Shift+Enter when exiting the formula to make it work because it is an ARRAY FORMULA.
{=INDEX(--MID(Look_Rng,FIND(":",Look_Rng)+1,LEN(Look_Rng)-FIND(":",Look_Rng)),MATCH(D2,MID(Look_Rng,MIN(IFERROR(FIND(D2,Look_Rng),33000)),LEN(D2)),0))}
Let me know if you have further questions.
P.s. I agree with #ForwardEd that it would be much easier if you use a couple helper columns to break the original data down and use simple INDEX+MATCH or VLOOKUP to look for the value. My answer used the same logic anyway.
This pictures shows my table and formula's yield
I have used following formula to extract result from a table.
Its working perfectly fine but I am hoping to level up my understanding of Excel formulas.
The trouble is that I use IF in Excel way to often.
what I wanted to know is if its possible to use a different approach, something that can work similar to if but is perhaps more sophisticated.
=IF(OR(J2="08L",J2="08R"),IF(ISNUMBER(MATCH(LEFT(I2,3),'SID separations'!$D$34,0)),"LAM",IF(ISNUMBER(MATCH(LEFT(I2,3),'SID separations'!$D$35:$E$35,0)),"West",IF(ISNUMBER(MATCH(LEFT(I2,3),'SID separations'!$D$36:$G$36,0)),"East",IF(ISNUMBER(MATCH(LEFT(I2,3),'SID separations'!$D$37,0)),"SFD",NA())))),0)
I very much appreciate any help.
Now that there is an example, I think this is a good question. You've recognised that your formula is fairly messy and also can't be easily expanded if there are more routes.
The problem is that Excel is very good for searching for a value in a single row or column, but not as good for searching for a value in a block of data.
You can simplify this problem by creating an additional column that has each entire route in a single cell. You can do this just by concatenating values. In your example, use column H:
=B2&" "&C2&" "&D2&" "&E2&" "&F2&" "&G2
This will create a string with the entire route in a single cell. Spaces are added in between each part of the route to make sure you don't accidentally create a sequences of letters that matches part of another route. It doesn't matter if there are blank cells, there will just be some extra spaces at the end which doesn't matter. Fill this down the column to get the entire path for each route in a single cell.
Then, you can create a formula that tries to find the 3 letters anywhere in any of the full routes.
=INDEX($A$2:$A$5,MATCH("*"&left(I2,3)&"*",$H$2:$H$5,0))
This formula is basically a deconstructed vlookup. It determines where the 3 characters can be found in column H, then gives back the corresponding value from column A.
The MATCH function tries to find the left 3 characters of I2 in column H. The MATCH function normally tries to find a complete exact match (with the last parameter being equal to 0), but we can just add wildcards to the search value. The MATCH function then returns the index of the range where it was found. I.e., if it was found in the 2nd cell of the range H2:H5, it returns the number 2.
The INDEX function then just gets a value from a range based on an index. In this case, it will get the 2nd value from range A2:A5.
EDIT: I have revived the source data source to remove the ambiguity of my last screen shots
I am trying to transpose spreadsheet data where there are many rows where the customer name may be duplicated but each row contains a different product.
For instance
revised original data source
to
revised proposed data format
I would like to do it with formulae if possible as I struggle with VB
Thank you for any help
I realise this is a huge answer, apologies but I wanted to be clear. If you need anything from me, drop me a comment and I'll help out.
Here's the output from my formula:
EDITED ANSWER - Named ranges used for ease of understanding:
These are just an example of a few of the named ranges I have used, you can reference the ranges directly or name them yourself (simplest way is to highlight the data then put the name in the drop down next to the formula bar [top left])
Be wary that as we will be using Array formulas for AccNum and AccType, you will not want to select the entire column and instead opt for either the exact data length or overshoot it by 100 or so. Large array formulas tend to slow down calculation and will calculate every cell individually regardless of it being empty.
First formula
=IF(COUNTIF(D2:D11,">""")>0,CONCATENATE("Account Number ",LEFT((COLUMN(A:A)+1)/2,1)),"")
This formula is identical to the one in the original answer apart form the adjusted heading title.
=IF(Condition,True,False) - There are so many uses for the IF logic, it is the best formula in Excel in my opinion. I have used to IF with COUNTIF to check whether there is more than 0 cells that are more than BLANK (or ""). This is just a trick around using ISBLANK() or other blank identifiers that get confused when formula is present.
If the result is TRUE, I use CONCATENATE(Text1,Text2,etc.) to build a text string for the column header. ROW(1:1) or COLUMN(A:A) is commonly used to initiate an automatically increasing integer for formulas to use based on whether the count increase is required horizontally or vertically. I add 1 to this increasing integer and divide it by 2 so that the increase for each column is 0.5 (1 > 1.5 > 2 > 2.5) I then use LEFT formula to just take the first digit to the left of this decimal answer so the number increases only once every 2 columns.
If the result is FALSE then leave the cell blank ,""). Standard stuff here, no explanation needed.
Second Formula
=CONCATENATE(INDEX(Forename,MATCH(Sheet4!$A2,Reference,0)))
=CONCATENATE(INDEX(Surname,MATCH(Sheet4!$A2,Reference,0)))
CONCATENATE has only been used here to force blank cells to remain blank when pulled by INDEX. INDEX will read blank cells as values and therefore 0's whereas CONCATENATE will read them as text and therefore "".
INDEX(Range,Row,Column): This is a lookup formula that is much more advanced than VLOOKUP or HLOOKUP and not limited in the way that they are.
The range i have used is the expected output range - Forename or Surname
The row is then calculated using MATCH(Criteria,Range,Match Type). Match will look through a range and return the position as an integer where a match occurs. For this I have set the criteria to the unique reference number in column A for that row, the range to the named range Reference and the match type as 0 (1 Less than, 0 Exact Match, -1 Greater than).
I did not define a column number for INDEX as it defaults to the first column and I am only giving it one column of data to output from anyway.
Third Formula
Remember these need to be entered as an array (when in the formula bar hit Ctrl+Shift+Enter)
=IFERROR(INDEX(AccNum,SMALL(IF(Reference=Sheet4!$A2,ROW(Reference)-ROW(INDEX(Reference,1,1))+1),ROUNDDOWN((COLUMN(A:A)+1)/2,0))),"")
=IFERROR(INDEX(AccType,SMALL(IF(Reference=Sheet4!$A2,ROW(Reference)-ROW(INDEX(Reference,1,1))+1),ROUNDDOWN((COLUMN(B:B)+1)/2,0))),"")
As you can see, one of these is used for AccNum and the other for AccType.
IFERROR(Value): The reason that this has been used is that we are not expecting the formula to always return something. When the formula cannot return something or SMALL has run out of matches to go through then an error will occur (usually #VALUE or #NUM!) so i use ,"") to force a blank result instead (again standard stuff).
I have already explained the INDEX formula above so let's just dive in to how I have worked out the rows that match what we are looking for:
SMALL(IF(Reference=Sheet4!$A2,ROW(Reference)-ROW(INDEX(Reference,1,1))+1),ROUNDDOWN((COLUMN(B:B)+1)/2,0))
The IF statement here is fairly self explanatory but as we have used it as an array formula, it will perform =Sheet4!$A2 which is the unique reference on every cell in the named range Reference individually. In your mock data this returns a result of: {FALSE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE} for the first entry (I included titles in the range, hence the initial FALSE). IF will do my row calculation* for every true but leave the FALSEs as they are.
This leaves a result of {FALSE;2;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE} that SMALL(array,k) will use. SMALL will only work on numeric values and will display the 'k'th result. Again the column trick has been used but to cover more ground, I used another method: ROUNDDOWN(Number,digits) as opposed to using LEFT() Digits here means decimal places so I used 0 to round down to a whole integer for the same result. As this copies across the columns like so: 1, 1, 2, 2, 3, 3, SMALL will alternatively (as the formulas alternate) grab the 1st smallest AccNum then the 1st Smallest AccType before grabbing the 2nd AccNum and Acctype and so forth.
*(Row number of the match minus the first row number of the range then plus 1, again fairly common as a foolproof way to always get the correct row regardless of where the data starts; actually as your data starts on row 1 we could just do ROW(Reference) but I left it as is incase you had data in a different format)
ORIGINAL ANSWER - Same logic as above
Here's your solution in 3 parts
Part 1 being a trick for the auto completion of the titles so that they will hide when not used (in case you will just copay and paste values the whole lot to speed up use again).
=IF(COUNTIF(C2:C11,">""")>0,CONCATENATE("Product ",LEFT((COLUMN(A:A)+1)/2,1)),"") in C
=IF(COUNTIF(D2:D11,">""")>0,CONCATENATE("Prod code ",LEFT((COLUMN(B:B)+1)/2,1)),"") in D
Highlight both of the cells and drag across to stagger the outputs "Product " and "Prod code "
Part 2 would be inputting the unique IDs to the new sheet, I would suggest copying your entire column A across to a new sheet and using DATA > REMOVE DUPLICATES > Continue with current selection to trim out the multiple occurrences of unique IDs.
In column B use =INDEX(Sheet2!$B$1:$B$7,MATCH(Sheet4!$A2,Sheet2!$A$1:$A$7,0)) to get the names pulled across.
Part 3, the INDEX
Once again, we are doing a staggered input here before copying the formula across the page to cover the entirety of the data.
=IFERROR(INDEX(Sheet2!$C$1:$D$11,SMALL(IF(Sheet2!$A$1:$A$11=Sheet4!$A2,ROW(Sheet2!$A$1:$A$11)-ROW(INDEX(Sheet2!$A$1:$A$11,1,1))+1),ROUNDDOWN((COLUMN(A:A)+1)/2,0)),1),"") in C
=IFERROR(INDEX(Sheet2!$C$1:$D$11,SMALL(IF(Sheet2!$A$1:$A$11=Sheet4!$A2,ROW(Sheet2!$A$1:$A$11)-ROW(INDEX(Sheet2!$A$1:$A$11,1,1))+1),ROUNDDOWN((COLUMN(B:B)+1)/2,0)),2),"") in D
The formulas of Part 3 will need to be entered as an array (when in the formula bar hit Ctrl+Shift+Enter) . This will need to be done before copying the formulas across.
These formulas can now be dragged / copied in all directions and will feed off of the unique ID in column A.
My Answer is already rather long so I haven't gone on to break the formula down. If you have any trouble understanding how this works, let me know and I will be happy to write up a quick guide, breaking it down chunk by chunk for you.
My problem explained in Excel
Column A1:A22 have some binary numbers (0, 1). As you can see I highlighted numbers with GREEN fill color that match my pattern I want to find.
Column C5:C22 have formula as you can see in formula box, that CONCATENATE first four numbers ( A1:A4, A2:A5 etc..) in data set and check if it matches my pattern.
If this first four numbers match my pattern, I want Excel to count all NEXT numbers that are right after this pattern.
The biggest problem is that I can't do this this way because I have data set that have approximately 30.000 binary records in it, and my RAM memory can't handle that much of CONCANTENATE formula to count all NEXT values, after my pattern occurs.
I want someone to help me find other way without making HELPER columns, I want Excel formula, that in steps:
Search for pattern in data set..
IF pattern in data set matches my desired pattern, make AVERAGE of all values right after pattern occurs. So in example above my AVERAGE in cells C5:C22 = 0,66
I hope that I explain this in details so you know my problem, I need formula to do all the math stuff, I can't use helper columns like in example above.
Thanks in advance.
Concatenate once then Substitute Pattern to find
You can use CONCATENATE function in one cell, getting all the 1's and 0's into one cell.
Then SUBSTITUTE the Pattern to find with empty string "".
Then count how many Patterns were "Substitued" (Matched).
Like so:
Formulas in cells
D5-Concat all: =CONCAT(A1:A22)
E5-Len all: =LEN(D5)
F5-Substitute: =SUBSTITUTE(D5;Pattern;"")
G5-Len after: =LEN(F5)
H5-Matches: =(E5-G5)/PatternLen
To get it into one cell:
=(LEN(CONCAT(A1:A22))-LEN(SUBSTITUTE(CONCAT(A1:A22);Pattern;"")))/PatternLen