How to pull keywords from an excel cell - excel

I work in sourcing and I'm trying to look through a list of cells that contain part numbers and their description, but only pull the part number from the cell and place it in another column.
The part numbers have one of 10 possible prefixes (i.e. ABC, DDA, GHF, AH, etc.). The cells may look something like this:
Tire Pressure ABC123873 Monitor
Oil Life ABC849999999021 gauge
Air conditioner GHF211 maintenance
And I want to be able to search that entire list and only pull the following information into another column:
ABC123873
ABC849999999021
GHF211
As you can see from above, the challenge is that the part numbers are all different lengths and have no particular convention to them. The only thing you know about them is that they can have one of ten possible prefixes as I mentioned above (ABC, GHF, etc.).
The current solution I have looks something like this:
C2=FIND("ABC", A2)
D2=FIND(" ", A2, C2)
E2=MID(A2, C2, D2)
Where cell A2 contains the complete part number and description, C2 finds the beginning location of the part number by searching for its prefix, D2 finds the ending location of the part number by searching for a space, and then E2 pulls the substring between those two locations.
As you can see, this isn't a very robust solution and it only allows me to search for parts that start with ABC. I want to be able to search for all 10 possible prefixes (ABC, DDA, GHF, AH, etc.) but that does not work. I tried the approach below:
C2=FIND({"ABC", "DDA", "GHF", "AH"}, A2)
But that only searches for the ABC parts and disregards the other prefixes. Any help you all can offer will be greatly appreciated!!

This is how I would do it. I created a list of prefixes to search in column G. You could even put them on a separate page to keep it cleaner.
=MID(A1,FIND(G1:G2,A1,1),FIND(" ", A1, FIND(G1:G2, A1, 1))-FIND(G1:G2,A1,1))
I only tested two prefixes but just change G1:G2 to G1:G10 and put all you prefixes in them. The formula looks in A1. The first FIND finds the beginning character number. The rest of the equation is calculating the end of the product number minus the beginning which returns the amount of characters to return. Its important to know that MID isn't wanting the beginning and end character. It wants the beginning character and the number of characters after that to return. So FIND(" ", FIND(G1:G2, A1, 1)) does not work as it returns too many characters. Give it a try.
Oh and don't forget to do Ctrl+Shift+Enter to enter the array formula
The VBA answer would be
Sub findProductCode()
' Variable Declarations
Dim productName As String
Dim productArray() As String
Dim wordCount As Integer
' Sets the active sheet to use
' Change Sheet1 to the name of your sheet
With Sheets("Sheet1")
' Selects the first cell to check
' Change A1 to the first cell with data
Range("A1").Select
' Loops through all rows until an empty row
' It will end if you have any empty rows in the midle of data
Do Until IsEmpty(ActiveCell)
' Reads text out of the cell
'Change A to the proper column
productName = Range("A" & ActiveCell.Row).Text
' Splits the string into individual words
productArray = Split(productName, " ")
' Loops through array to find the product number
For wordCount = LBound(productArray) To UBound(productArray)
' Check if the word has the desired 10 prefixes
' Add more Or Left(productArray(wordCount), 3) = "xxx" until you have 10 of your prefixes you need
If Left(productArray(wordCount), 3) = "ABC" Or Left(productArray(wordCount), 3) = "GHF" Then
' Sends the product number to its cell
' Change B to the correct destination Cell
Range("B" & ActiveCell.Row).Value = productArray(wordCount)
End If
Next
' Increments the active cell to the next cell down
ActiveCell.Offset(1, 0).Select
Loop
End With
End Sub
If you don't know how, you need to enable the developer tab in excel. File->Options->Customize Ribbon Add the Developer to the Ribbon. The save your worksheet as .xlsm It is the macro enabled workbook. Then go to the developer tab, Choose "Visual Basic" and double click "ThisWorkBook". Paste the code in. You can run the code from there for a one time deal or you can create a button on the sheet that you can run this macro whenever you want.
To add a button, go back to the sheet you want the button on. On the developer tab select Insert and choose the first form control Button. Draw the button on your sheet and a dialog box will appear. select the findProductCode macro and select OK. Now every time you click the button it will run the macro.

This isn't the prettiest formula, but it should get you on your way. There's definitely a VBA solution, if you're interested in a macro instead of a formula.
Assuming your Tire Pressure ABC123873 Monitor is in A1, enter this into B1:
=MID(SUBSTITUTE(SUBSTITUTE(A1," ",";",1)," ","-",1),SEARCH("ABC",SUBSTITUTE(SUBSTITUTE(A1," ",";",1)," ","-",1)),SEARCH(" ",SUBSTITUTE(SUBSTITUTE(A1," ",";",1)," ","-",1))-SEARCH("ABC",SUBSTITUTE(SUBSTITUTE(A1," ",";",1)," ","-",1)))
How it works, is it takes your A1, and first uses Substitute. I substitute the first and second [space] for ; and -. (Note, if there are more spaces than two, this will run into issues). Then, I just use Mid to extract the part of the cell starting with ABC and going until it hits the space. If you don't have "ABC" starting the values you want, you need to adjust the Search("ABC"... part (or use an array there). I am still working on it, but hopefully this helps give an idea.

Related

combine all cells, numbers and symbols to a sum

Good day,
I'm at a loss on this problem.
I have a group of cells that contain words, like apple, this word would be the value. It is separated by a symbol for completing the math. They can be changed by the user to make custom calculations.
Cell A1 is "apple", B1 is "+", cell C1 is "apple", cell D1 is "*", cell E1 is "apple", call F1 is "=" and cell G1 is the suggested total, in this case would be "6".
It would be posted as | apple | + | apple | * | apple | = | 6 |
The legend holds the value for the word, so if you enter 2 in the legend, apple would be 2.
The logic would determine that the formula would be 2+2*2= if written in excel, I would like to combine all the cells and calculate this.
I tried using =sum, sumproduct, concate and the like to no avail.
Any head way I did make, I ended up getting BEDMAS wrong as it calculated it as 2+2=4*2=8, instead of the correct 2*2=4+2=6.
Anyone know of a way to combine these cells and properly sum the values to the correct total?
Thank you for your time!
Go to the Name manager and create named range Eval, into Refers to field add formula:
=EVALUATE(CONCATENATE(VLOOKUP(Sheet1!A1,Sheet1!$A$3:$B$5,2,0),Sheet1!B1,VLOOKUP(Sheet1!C1,Sheet1!$A$3:$B$5,2,0),Sheet1!D1,VLOOKUP(Sheet1!E1,Sheet1!$A$3:$B$5,2,0)))
In range A3:B5 I have legend.
Change references as you need. Then in cell G1 write formula =Eval.
Sample:
This is a UDF based solution. Its advantage is that it's more versatile and by far easier to maintain if you learn its elements of code. The disadvantage is in that you do have to learn the elements of code and you have an xlsm macro-enabled workbook which isn't welcome everywhere.
The setup is simple. I created a table with columns Item and Value. I placed it on another sheet than the task. In fact, you could make the sheet with the table VeryHidden so that the user can't look at it without access to the VBA project, which you can password protect. I called the table Legend. The item columns has names like apple, pear, orange. The Value column has the numeric values associated with each name.
Note that, since this is a VBA project, the entire list can be transferred to VBA leaving no trace on the sheet. You could have a function to display the value of each item as the user clicks on it and have it disappear as he clicks elsewhere.
Next I created a data validation drop-down in A1 with the List defined as =INDIRECT("Legend[Item]"). Copy this cell to C1 and E1.
Then I created another Data Validation drop-down in B1 with the list as +,-,*,/. This drop-down must be copied to D1.
Now the code below goes into a standard code module. Find the way to create it because it isn't any of those Excel sets up automatically. It's default name would be Module1. Paste the code there.
Function Evalue(Definition As Range) As Double
Dim Task As String
Dim Fact(2) As Double
Dim C As Long
Dim i As Long
With Definition
For C = 1 To 5 Step 2
On Error Resume Next
Fact(i) = Application.VLookup(.Cells(C).Value, Range("Legend"), 2, False)
i = i + 1
Next C
Task = "(" & Fact(0) & .Cells(2).Value _
& Fact(1) & ")" & .Cells(4).Value _
& Fact(2)
End With
Evalue = Evaluate(Task)
End Function
Now you are ready for testing. Call the function from the worksheet with a call like
=Evalue(A1:E1). You can use it in comparisons like =IF(G6 = Evalue(A1:E1), "Baravo!", "Try again"). As you change any of the components the cell with the function will change.
Remember to use absolute addressing if you copy formulas containing the range. If you need to get a result in VBA while testing, use this sub to call the function.
Private Sub TestEvalue()
Debug.Print Evalue(Range("A1:E1"))
End Sub
My Sheet
Here is what I have.
In cells M - U, i count all the instances of the word from cells E, G and I from the legend.
=SUMPRODUCT((LEN(E3)-LEN(SUBSTITUTE(E3,$B$3,"")))/LEN($B$3))
In cells W - AE, I multiply the instances with the value to give me a total each time the word appears.
=SUM(M3*$C$3)
In cell E8 - I8, i add the three possible values together.
=SUM(W3:Y3) so each worded cell is now a number.
I'd like to take the cells E8 - I8 to make a calculation in k8 and so on.
So, each cell is put together to make an
=SUM(E8:I8)
statement, which all works except E11 - I11 which equates to 26 instead of 43.

Comparing and counting values

I have a table, let's call it my Individuals Table, much like the one below, containing a column of individuals along with their corresponding codes listed in an adjacent cell. Codes for each individual are all listed within the same adjacent cell next to the individual's name, and separated by a carriage return.
Example table
What I'd like to do is the following:
Run through the code cell for each individual
For each code in the individual's code cell, check if this code exists in a separate Codes Table
If the code exists in the Codes Table, add n+1 to the total count for that code in an adjacent cell and add the individual's name to the list of individuals with that same code in another adjacent cell.
If the code does not exist in the Codes Table, add the code to the Codes Table, add n+1 to the total count for that code in an adjacent cell and add the individual's name to the list of individuals with that same code in another adjacent cell.
Result of running the algorithm on the example table
If a similar program can achieve the same results, then I'm open to that too.
I try to give you a possible solution, by minimizing the use of VBA code.
As starting point I would do is rearranging codes for every individuals. Keeping more codes in a single cell separed by a return it is not as easy to manage like having a single code for each cell. Of course I will keep each code associated with each individual. A way to do it is with your data is by using the formula substitute and replace the returns characters with a semicolon. The formula works this:
=SUBSTITUTE(B2,CHAR(13),CHAR(59))
B2 is the cell where you are converting returns to semicolon. You will then use this formula for all values in your B column.
Once you have replaced returns with semicolon, copy and paste values and then with the function "Text to Columns" in Data tab you will convert each cell to a series of columns (depending on how many codes you had listed in the original cell of your sheet). Now you will be in a situation where the first column you have the names of individuals, and then on the same row in the subsequent columns you have all associated codes, like in the picture here below:
In order to create a complete list of all codes you can easily copy all columns with codes. Paste the codes in a suitable space (I suggest in a new worksheet), and then with some copy and paste jobs put all codes under the same column. Select all codes and with the button "Remove Duplicates" always in the Data tab you will have a list of all unique codes included in your original table.
Then you can copy and paste the column with all unique codes you created under your "Codes" column. Now you can count the codes in the converted table with this formula:
=COUNTIF($B$1:$C$4, D2)
Where first argument of COUNTIF refers to the codes in the converted table and the second argument is a code in your column "Codes" where you pasted the unique codes.
Now as far as I know there is no function in Excel to create a list of names separated by commas (but I would be glad to discover that it exists if anybody knows!!!). Therefore I created a custom one with some VBA code with the name List Individuals:
Function ListIndividuals(refCode, NameRange As Range, CodesRange As Range) As String
'Check size in row number of NameRange and CodesRange is same, otherwise give error
If NameRange.Rows.Count <> CodesRange.Rows.Count Then
ListIndividuals = CVErr(xlErrRef)
Exit Function
End If
result = ""
For Col = 1 To CodesRange.Columns.Count
For n = 1 To CodesRange.Rows.Count
If CodesRange.Cells(n, Col).Value = refCode Then
If CodesRange.Cells(n, Col).Value <> "" Then
If result = "" Then
result = NameRange(n)
Else
result = result & ", " & NameRange(n)
End If
End If
End If
Next
Next
ListIndividuals = result
End Function
So last step is to use this formula under your "Individuals" cells as follows:
=ListIndividuals(D2,$A$13:$A$16,$D$13:$E$16)
Where first argument is the Code, the second one is the list of individuals in the converted table (it should be the first column), then the third one are the columns with the codes in the converted table. As a result of this custom formula you will have the list of individuals separated by commas.
All above works on my computer, but if you need more information, please do not hesitate to contact me.

Reference combined cell above

I have a sheet with a lots of columns ordered in a hierarchical way with the cells merged:
I'd like to name those columns (in example: row 5) like this:MainGroupA-SubGroupA-SubSubGroupA.
Simply referencing the columns above in the classic way won't work as the field above isn't available anymore. (In the example: the fields B1 to F1) (i.e. I can't enter A1&A2&A3 / R[-4]C&R[-3]C&R[-2]C as this formula tries to read from the "hidden" cells).
Is there a way to do this without manual work or the need to un-merge the parent-cells? I might be able to do this with some external text editor or even VBA but would prefer an "Excel formula solution" as it would stay updated for new groups and columns.
To Clarify: I'd like all columns in Line 5 to have the text like in A5
If you want:
MainGroupA-SubGroupA-SubSubGroupA
in A5 then this should work:
=A1&"-"&A2&"-"&A3
Edit Then try:
=OFFSET(A1,0,1-MOD(COLUMN(),6))&"-"&OFFSET(A2,0,MOD(COLUMN(),2)-1)&"-"&A3
though this won't give the same text as in A5 across the complete row.
The answer from pnuts is great and helped me solve some test cases. It was however a little difficult to adapt and produced empty strings for the last column, so I also wrote a VBA-Function to do exactly what I need.
Open the VBA Editor (ALT + F11) and enter the following code in a new module:
Public Function checkLeftIfEmpty(start As range) As String
If start.Cells.Count > 1 Then
checkLeftIfEmpty = "Only a single cell allowed as parameter"
Exit Function
End If
Dim currentRange As range
Set currentRange = start
Do While currentRange.Column >= 1
If currentRange.Value <> "" Then
checkLeftIfEmpty = currentRange.Value
Exit Function
Else
Set currentRange = currentRange.Offset(0, -1)
End If
Loop
End Function
You can now use the function checkLeftIfEmpty to find the first cell left-side from your parameter which contains text: (This will be the text of the merged cell itself, if applied to a "hidden by merge" cell)
And also in combination to concatenate a string:

Excel: Formula to extract a string of text delimited by markers from cells

I'm messing with a spreadsheet containing postal addresses that have been inserted in the cells' comments
Each comment contain an address composed of a variable number of lines (damn UK addresses, they can have up to 7 lines!) in the following format:
Line1,
Line2,
Line3,
[...],
State
With my poor skills, I've managed to extract the comment with a VBA script, obtaining the following string on a single cell:
Line1,Line2,Line3,[...],State
At this point each string between commas must be extracted to its own cell.
I've managed to extract the 1st 3 lines with the following formulas:
For Line1:
=LEFT(A8;(SEARCH(",";A8))-1)
For Line2:
=MID(A8; SEARCH(",";A8)+1; SEARCH(","; A8; SEARCH(","; A8)+1)-SEARCH(",";A8)-1)
For Line3:
=MID(A8; SEARCH(",";A8;SEARCH(",";A8;SEARCH(",";A8;SEARCH(",";A8)))+1)+1;SEARCH(","; A8; SEARCH(","; A8;SEARCH(",";A8)+1)+1)-SEARCH(",";A8;SEARCH(",";A8)+1)-1)
From this point I start to get overflow errors from my brain... I probably need some days of sleep.
Can anybody help me to get to "line6", and finally suggest me how to pull out the "State line" which ends without comma?
I thought I could pull out the "State" line with =RIGHT(",";SEARCH(",";A8)-1) but I'm obviously doing something wrong because that pulls out a comma instead of a string.
I guess I could do everything with a VBA script, but I'm not that skilled yet :(
With comma separated data in A1, in B1 enter:
=TRIM(MID(SUBSTITUTE($A1,",",REPT(" ",999)),COLUMNS($A:A)*999-998,999))
and copy across. For example:
Note:
Why not use TextToColumns ?
The row of formulas re-calculates automatically if A1 changes.
The row of formulas will work even if A1, itself, contains a formula.
If you are wanting to do this programmatically instead of using a built-in, check out the split function for chopping up your comma separated string. It will split up your input string into an array. Then you can do whatever you like with the array.
Dim Names() As String
Names() = Split(inputValue, ",")
For i = 0 To UBound(Names)
' do what you want with each piece
Next
Gary's Student's answer is great for using the built-in functions.
If you want a VBA solution:
Sub spitString()
Dim sourceRange As Range
Dim stringArr() As String
Dim i As Integer
Set sourceRange = ActiveSheet.Range("A1")
stringArr = Split(sourceRange.Value, ",")
For i = LBound(stringArr) To UBound(stringArr)
sourceRange.Offset(0, i + 1).Value = stringArr(i)
Next i
End Sub
You could avoid adding comments: Are you aware that users can add line breaks inside a cell by pressing ALT+RETURN?
If having high rows d is a problem and you don't like that formatting, an alternative approach might be to write a simple bit of code that changes the height of the current row when a user clicks in a certain range. It would , make other rows less high. Perhaps.
Just a thought. It has benefits keeping it simple.
Harvey.

Add common prefix to all cells in Excel

I have a column with some text in each cell.
I want to add some text, for example "X", at the start of all cells. For example:
A B
----- >>>> ----
1 X1
2 X2
3 X3
What is the easiest way to do this?
Type this in cell B1, and copy down...
="X"&A1
This would also work:
=CONCATENATE("X",A1)
And here's one of many ways to do this in VBA (Disclaimer: I don't code in VBA very often!):
Sub AddX()
Dim i As Long
With ActiveSheet
For i = 1 To .Range("A65536").End(xlUp).Row Step 1
.Cells(i, 2).Value = "X" & Trim(Str(.Cells(i, 1).Value))
Next i
End With
End Sub
Select the cell you want to be like this,
Go To Cell Properties (or CTRL 1)
under Number tab
in custom
enter
"X"#
Select the cell you want to be like this, go to cell properties (or CTRL 1) under Number tab in custom enter "X"#
Put a space between " and # if needed
Select the cell you want,
Go To Format Cells (or CTRL+1),
Select the "custom" Tab, enter your required format like : "X"#
use a space if needed.
for example, I needed to insert the word "Hours" beside my numbers and used this format : # "hours"
Enter the function of = CONCATENATE("X",A1) in one cell other than A say D
Click the Cell D1, and drag the fill handle across the range that you want to fill.All the cells should have been added the specific prefix text.
You can see the changes made to the repective cells.
Option 1:
select the cell(s), under formatting/number/custom formatting, type in
"BOB" General
now you have a prefix "BOB" next to numbers, dates, booleans, but not next to TEXTs
Option2:
As before, but use the following format
_ "BOB" #_
now you have a prefix BOB, this works even if the cell contained text
Cheers, Sudhi
Michael.. if its just for formatting then you can format the cell to append any value.
Just right click and select Format Cell on the context menu, select custom and then specify type as you wish... for above example it would be X0. Here 'X' is the prefix and 0 is the numeric after.
Hope this helps..
Cheers...
Go to Format Cells - Custom. Type the required format into the list first. To prefix "0" before the text characters in an Excel column, use the Format 0####. Remember, use the character "#" equal to the maximum number of digits in a cell of that column. For e.g., if there are 4 cells in a column with the entries - 123, 333, 5665, 7 - use the formula 0####. Reason - A single # refers to reference of just one digit.
Another way to do this:
Put your prefix in one column say column A in excel
Put the values to which you want to add prefix in another column say column B in excel
In Column C, use this formula;
"C1=A1&B1"
Copy all the values in column C and paste it again in the same selection but as values only.
Type a value in one cell (EX:B4 CELL). For temporary use this formula in other cell (once done delete it). =CONCAT(XY,B4) . click and drag till the value you need. Copy the whole column and right click paste only values (second option).
I tried and it's working as expected.

Resources