Find specifc text in multiple columns in excel - excel

I've got a formula that's been puzzling me for a while - I feel I'm close but the solution is evading me so I'm turning to you wizards. This questions is similar to Excel VLOOKUP and SEARCH combination.
Problem:
I want to look up a value which is a pair of codes separated by a dash, ex.
01-05
A1-B2
AB-90
, within columns A and B and return a result from C.
The issue is that I'm searching in two columns, which may include multiple codes separated by commas:
Col A Col B Col C
01 05, B2 Result1
A1 B2 Result2
AB, AC 90, 91, 92 Result3
I was thinking that a =if(isnumber(search( function would be the key but I can't figure how to have it check the entire column and once found, check the column next to it for the 2nd part of the code.
Ideally, the formula would perform as such, where in the above example, if I were to run this formula on the criteria 01-05 it would return Result1.
Appreciated!

the "formula" approach is, to my knowledge, quite verbose and cumbersome as follows:
=IF(
ISNA(
IFERROR(MATCH(LEFT(D1,SEARCH("-",D1)-1),Codes!$A$1:$A$100,0),
IFERROR(MATCH("*"&LEFT(D1,SEARCH("-",D1)-1)&",*",Codes!$A$1:$A$100,0),
MATCH("*,"&LEFT(D1,SEARCH("-",D1)-1)&"*",Codes!$A$1:$A$100,0)))
*
IFERROR(MATCH(RIGHT(D1,LEN(D1)-SEARCH("-",D1)),Codes!$B$1:$B$100,0),
IFERROR(MATCH("*"&RIGHT(D1,LEN(D1)-SEARCH("-",D1))&",*",Codes!$B$1:$B$100,0),
MATCH("*,"&RIGHT(D1,LEN(D1)-SEARCH("-",D1))&"*",Codes!$B$1:$B$100,0)))
),
"Not Found",
IF(IFERROR(MATCH(LEFT(D1,SEARCH("-",D1)-1),Codes!$A$1:$A$100,0),
IFERROR(MATCH("*"&LEFT(D1,SEARCH("-",D1)-1)&",*",Codes!$A$1:$A$100,0),
MATCH("*,"&LEFT(D1,SEARCH("-",D1)-1)&"*",Codes!$A$1:$A$100,0)))
<>
IFERROR(MATCH(RIGHT(D1,LEN(D1)-SEARCH("-",D1)),Codes!$B$1:$B$100,0),
IFERROR(MATCH("*"&RIGHT(D1,LEN(D1)-SEARCH("-",D1))&",*",Codes!$B$1:$B$100,0),
MATCH("*,"&RIGHT(D1,LEN(D1)-SEARCH("-",D1))&"*",Codes!$B$1:$B$100,0))),
"Different rows",
INDEX(Codes!C:C,IFERROR(MATCH(RIGHT(D1,LEN(D1)-SEARCH("-",D1)),Codes!$B$1:$B$100,0),
IFERROR(MATCH("*"&RIGHT(D1,LEN(D1)-SEARCH("-",D1))&",*",Codes!$B$1:$B$100,0),
MATCH("*,"&RIGHT(D1,LEN(D1)-SEARCH("-",D1))&"*",Codes!$B$1:$B$100,0))))
)
)
where I used a (hopefully) more readable format and assumed:
"Codes" as the sheet name whose columns "A" ("first" code), "B" ("second" code) and "C" ("Results") are placed
codes pairs are to be placed in column "D" of any sheet
formula is to be placed in column "E" adjacent to above mentioned column "D" cells
you may want to consider a "VBA" approach like the following
Sub main()
Dim codesSht As Worksheet
Dim cell As Range, found As Range, codesRng As Range
Dim index1 As Long
Set codesSht = ThisWorkbook.Worksheets("Codes") '<== change "codes" sheet reference as per your needs
Set codesRng = codesSht.Range("A:B").SpecialCells(xlCellTypeConstants, xlTextValues)
With ThisWorkbook.Worksheets("Results") '<== change "Results" sheet reference as per your needs
For Each cell In .Range("D1:D" & .Cells(.Rows.count, "D").End(xlUp).Row).SpecialCells(xlCellTypeConstants, xlTextValues)
Set found = codesRng.Resize(, 1).Find(What:=Split(cell.Value, "-")(0), LookIn:=xlValues, LookAt:=xlPart)
If Not found Is Nothing Then
index1 = found.Row
Set found = codesRng.Offset(, 1).Resize(, 1).Find(What:=Split(cell.Value, "-")(1), LookIn:=xlValues, LookAt:=xlPart)
If Not found Is Nothing Then If found.Row = index1 Then cell.Offset(, 1).Value = codesRng(index1, 3)
End If
Next cell
End With
End Sub

If you put the code you are looking for in Column D, then your formula in Column E, the following formula will accomplish what you are looking for ...
=IF(OR(ISERROR(FIND(LEFT(D2,2),A2)),ISERROR(FIND(RIGHT(D2,2),B2)),LEN(D2)=0),"",C2)
And then fill it down.
The formula searches for the left two characters from the code in Column A. If it's not found, an error is thrown. It also looks for the right two characters from the code in Column B. If it's not found, an error is thrown. If the code you are looking for is blank, no error is thrown, so we need to check that case.
So if there is an error searching for the left part, or an error searching for the right part, or there is no code to look for, return a blank. Otherwise, return the result.
Below are some examples ...
Updated based on comments
On Sheet1, the data looks like this ...
... On Sheet2, we have results like this ...
Where Cell B2 contains this formula (filled down)
{=CONCAT(IF(ISERROR(FIND(LEFT(A2,2),Sheet1!$A$1:$A$3)),"",IF(ISERROR(FIND(RIGHT(A2,2),Sheet1!$B$1:$B$3)),"",IF(LEN(A2)<1,"",Sheet1!$C$1:$C$3))))}
Updated due to version-itis
When all else fails, go to VBA. Attached is an example Function. It gets the same results as shown above. It is invoked with formula in Column B, filled down ...
=FindResult(A2,Sheet1!$A$1:$A$3,Sheet1!$B$1:$B$3,Sheet1!$C$1:$C$3)
Code ...
Function FindResult(inString As String, LeftRange As Range, RightRange As Range, ReturnRange As Range) As String
Dim strArr() As String
Dim myCellLeft As Range, myCellRight
'initial
FindResult = ""
If LeftRange Is Nothing Then GoTo Done:
If RightRange Is Nothing Then GoTo Done:
If ReturnRange Is Nothing Then GoTo Done:
' get the two halfs
strArr = Split(inString, "-")
If UBound(strArr) < 1 Then GoTo Done:
' Search the left range for the left half, the right range for the right half
For Each myCellLeft In LeftRange
If InStr(1, myCellLeft.Value, strArr(0)) > 0 Then
For Each myCellRight In RightRange.Rows(myCellLeft.Row)
If InStr(1, myCellRight.Value, strArr(1)) > 0 Then
FindResult = ReturnRange.Rows(myCellLeft.Row)
Exit For
End If
Next myCellRight
If FindResult <> "" Then Exit For
End If
Next myCellLeft
' clean up
Done:
Erase strArr
Set myCellLeft = Nothing
Set myCellRight = Nothing
End Function

Related

How do I clear content in rows based on cell value?

I copy a lot of information (1000 rows and at least 24 columns) from one sheet to another. A lot of the cells contains "". This makes my other formulas(for example: A1-B1) to show an value error if either of these cells contains "".
I believe I can solve the problem by never pasting "" but a "0" instead. But I would like to delete these "0" afterwards.
There could be values in the first 3 rows but the other 997 rows have "".
I would think I need to tell my macro to (Cell A1 in the "sheet1" sheet displays "G5:H12". the cells I need to delete):
Rowstodelete = Sheets("sheet1").Range("A1").Value
Sheets("sheet1").Range("rowstodelete").clearcontent
This does not work. anyone know how to do this?
Summary(new example)
If cell A1 = "B1:B2" I want to clear the content of B1 and B2, but if A1 now = B4:B6, that is the cells that should be cleared.
Try this one:
With Worksheets(1).Range( _'PLACE YOUR RANGE
)
Set c = .Find(0, lookin:=xlValues)
If Not c Is Nothing Then
firstAddress = c.Address
Do
c.Value = ""
Set c = .FindNext(c)
Loop While Not c Is Nothing
End If
End With
Hope it helps
Anyhow, I think that will be simpler to place a condition in your operation formula: =IF(OR(A1="",B1=""),Make when there is an unexpected value,A1-B1)

VBA code to insert column and formula

I have a file where I need to delete certain columns. I then need to insert a column called 'positive values' and add a formula so that only the positive values from another column are picked up in this new column.
So far I have pieced together the following code to delete the columns I do not need, but I am stuck at how to insert a new column next to an existing column called "net" and then have this column only show the positive values from column net in the relevant cells.
Current code
Sub ArrayLoop()
Dim ColumnsToRemove As Variant
Dim vItem As Variant
Dim A As Range
Sheets("sheet 1").Select
ColumnsToRemove = Array("acronym", "valueusd", "value gbp")
For Each vItem In ColumnsToRemove
Set A = Rows(8).Find(What:=vItem, LookIn:=xlValues, lookat:=xlPart)
Debug.Print vItem, Not A Is Nothing
If Not A Is Nothing Then A.EntireColumn.Delete
Next
End Sub
Currently I manually insert the new column and enter the formula max(E9,0) so the new column either shows 0 or a value if the value in the other column is greater than 0. Is it possible to automate this part as well.
Thanks in advance.
For Insertion locate the cell and issue:
If Not A Is Nothing Then A.EntireColumn.Insert
To insert a formula, use cell.formula= with the coresponding string value, e.g.
Cells(1, A.column - 1).Formula = "=max(" & cells(9, A.column - 2).Address & ",0)"
Note A as a range of the found value will shift to the right when inserting a column that's why you need - 1 nad - 2 in cell references.

vba WorksheetFunction.Match search for multiple values

I am currently searching a HR sheet for a column header that contains specific text. This text can change each week, for example, a column called "State/Province" could have no spaces in it one week, but the following week it could be "State / Province" (notice the space between the words).
I am currently using the below code that looks for one condition
StateProvince = WorksheetFunction.Match("State/Province", hr.Sheets("Open").Rows(1), 0)
This works fine, but I am looking to add to this so that it looks for the second example containing the spaces if this is the case for the column header. Any suggestions?
Use:
StateProvince = WorksheetFunction.Match("State*/*Province", hr.Sheets("Open").Rows(1), 0)
This answer is specific to your question. If you want more generic solution you'll have to provide other examples.
Since the unpredictable appearance of spaces you'd better ignore them altoghether by means of a custom MyMatch() function to which pass "unspaced" string, like follows:
Function MyMatch(textToSearch As String, rng As Range) As Long
Dim txtRng As Range, cell As Range
MyMatch = -1 '<--| default value for no match found
On Error Resume Next
Set txtRng = rng.SpecialCells(xlCellTypeConstants, xlTextValues) '<--| consider only cells with text values
On Error GoTo 0
If Not txtRng Is Nothing Then '<--| If there's at least one cell with text value
For Each cell In txtRng '<--| loop through selected "text" cells
If WorksheeyFunction.Substitute (cell.Value, " ", "") = textToSearch Then '<--|remove every space occurrence from cell value and compare it to your "nospace" searched value
MyMatch = cell.Column - rng.Columns(1).Column + 1
Exit For
End If
Next cell
End If
End With
To be used like follows:
Dim StateProvince As Long
StateProvince = MyMatch("State/Province", hr.Sheets("Open").Rows(1)) '<--| pass an "unspaced" string to search
If StateProvince > 0 Then
' code for handling found StateProvince
Else
' code for handling NOT found StateProvince
End If

if / then formula over many rows

I am trying to produce a code (simple for some) but I am inexperienced and would appreciate help.
Code to look at cell ("J1") and doing an if / then for a result in ("K1"), but I want to have this duplicated to look at the range J2 to J10 cells , to give the result in the range K2 to K10 cells as well.
The code below works for single row formula:
Sub Check()
Dim DDDD As Date, result As String
DDDD = Range("j1").Value
If DDDD >= Date Then
result = "Future"
Else
result = "Now"
End If
Range("k1").Value = result
End Sub
You can use a For Each loop and the Offset method, like this:
Sub Check()
Dim DDDD As Date, result As String
Dim cell as Range
For Each cell in Range("J1:J10")
DDDD = cell.Value
If DDDD >= Date Then
result = "Future"
Else
result = "Now"
End If
' Change value at the right side of the cell
cell.Offset(0,1).Value = result
Next cell
End Sub
But using VBA for this is really overkill. You could just put this formula in K1:
=IF(J1 >= TODAY(), "Future", "Now")
... and then copy/drag that formula down to the other cells below it.
Here is a piece of code that loops through Column J, and the result will be placed at Column K.
Sub Check()
Dim DDDD As Date
Dim result As String
Dim row, NumofRows As Integer
' use NumfofRows as a Dynamic value to decide how many rows of data you want to look at column J
NumofRows = 10
For row = 1 To NumofRows
If Cells(row, 10) >= Date Then
result = "Future"
Else
result = "Now"
End If
Cells(row, 11).Value = result
Next
End Sub
In the future, take a look at the rules of etiquette that make your questions both fun and enticing to answer. For your question, it will be more efficient to deal with Ranges rather than individual cells with dates in them. The For Each...Next loop can cycle through each cell in the range. Then, an If...Then...Else...End If loop can make a decision given various conditions. The Offset(0, 1) method can be used inside the If...Then loop to place results in the column to the right. The following code does what you seem to be asking:
Sub Check()
' Declare your variables
Dim MyDates As Range
Dim result As String
' First, grab all the values in the J2:JX column, where
' X can be any number of dates you choose. Note that
' you must "Set" Object variables, but you must "Dim"
' other types of variables.
Set MyDates = Range(Range("J2"), Range("J2").End(xlDown))
' Loop through every cell in the dates column and give the
' offset column (column K) a string value if the condition
' is met.
Dim Cell As Range
For Each Cell In MyDates
If Cell >= Date Then
result = "Future"
Cell.Offset(0, 1).Value = result
Else
result = "Now (or past)"
Cell.Offset(0, 1).Value = result
End If
Next Cell
End Sub
The End(xlDown) method emulates selecting a cell and pressing Ctrl+Down arrow. Also, note that this code does not handle mistakes at all. For example if you accidentally enter a date as text, the procedure will produce an incorrect result. Also, depending on the time you enter data, you could get confusing results. I've attached an image of the results in Excel here:

Excel compare two columns and highlight duplicates

I have an excel file with 10,000 rows in column A some values are the same.
Example:
A1 - P7767
A2 - P3443
A3 - P7767
A4 - P8746
A5 - P9435
etc...
I then have another column with 100 rows which have some of the values found in column A,
B1 - P7767
B2 - P8746
etc...
I need to highlight all cells in column A where the value is found in any of the values in column B
So basically column B checks to see if it can find the same value anywhere in column A, if true highlight the cell leaving any cells white when the value is not found in column B
I hope I have explained this well, I have done some research and I believe I need to use conditional formatting to get this result but I am really stuck on the formula to use and cannot seem to find an example online (Maybe I am not searching the correct term as I'm not sure on what this is exactly called)
There may be a simpler option, but you can use VLOOKUP to check if a value appears in a list (and VLOOKUP is a powerful formula to get to grips with anyway).
So for A1, you can set a conditional format using the following formula:
=NOT(ISNA(VLOOKUP(A1,$B:$B,1,FALSE)))
Copy and Paste Special > Formats to copy that conditional format to the other cells in column A.
What the above formula is doing:
VLOOKUP is looking up the value of Cell A1 (first parameter) against the whole of column B ($B:$B), in the first column (that's the 3rd parameter, redundant here, but typically VLOOKUP looks up a table rather than a column). The last parameter, FALSE, specifies that the match must be exact rather than just the closest match.
VLOOKUP will return #ISNA if no match is found, so the NOT(ISNA(...)) returns true for all cells which have a match in column B.
A simple formula to use is
=COUNTIF($B:$B,A1)
Formula specified is for cell A1. Simply copy and paste special - format to the whole of column A
NOTE: You may want to remove duplicate items (eg duplicate entries in the same column) before doing these steps to prevent false positives.
Select both columns
click Conditional Formatting
click Highlight Cells Rules
click Duplicate Values (the defaults should be OK)
Duplicates are now highlighted in red:
The easiest way to do it, at least for me, is:
Conditional format-> Add new rule->Set your own formula:
=ISNA(MATCH(A2;$B:$B;0))
Where A2 is the first element in column A to be compared and B is the column where A's element will be searched.
Once you have set the formula and picked the format, apply this rule to all elements in the column.
Hope this helps
A1 --> conditional formatting --> cell value is B1 --> format: whatever you want
hope that helps
Suppose you want to compare a column A and column H in a same spreadsheet .
You need to go another column next to these 2 columns and paste this formula :
=(Sheet1!A:A=Sheet1!H:H)
this will display FALSE or TRUE in the column . So you can use this new column to color the non matching values using conditional color formatting feature .
I was trying to compare A-B columns and highlight equal text, but usinng the obove fomrulas some text did not match at all. So I used form (VBA macro to compare two columns and color highlight cell differences) codes and I modified few things to adapt it to my application and find any desired column (just by clicking it). In my case, I use large and different numbers of rows on each column. Hope this helps:
Sub ABTextCompare()
Dim Report As Worksheet
Dim i, j, colNum, vMatch As Integer
Dim lastRowA, lastRowB, lastRow, lastColumn As Integer
Dim ColumnUsage As String
Dim colA, colB, colC As String
Dim A, B, C As Variant
Set Report = Excel.ActiveSheet
vMatch = 1
'Select A and B Columns to compare
On Error Resume Next
Set A = Application.InputBox(Prompt:="Select column to compare", Title:="Column A", Type:=8)
If A Is Nothing Then Exit Sub
colA = Split(A(1).Address(1, 0), "$")(0)
Set B = Application.InputBox(Prompt:="Select column being searched", Title:="Column B", Type:=8)
If A Is Nothing Then Exit Sub
colB = Split(B(1).Address(1, 0), "$")(0)
'Select Column to show results
Set C = Application.InputBox("Select column to show results", "Results", Type:=8)
If C Is Nothing Then Exit Sub
colC = Split(C(1).Address(1, 0), "$")(0)
'Get Last Row
lastRowA = Report.Cells.Find("", Range(colA & 1), xlFormulas, xlByRows, xlPrevious).Row - 1 ' Last row in column A
lastRowB = Report.Cells.Find("", Range(colB & 1), xlFormulas, xlByRows, xlPrevious).Row - 1 ' Last row in column B
Application.ScreenUpdating = False
'***************************************************
For i = 2 To lastRowA
For j = 2 To lastRowB
If Report.Cells(i, A.Column).Value <> "" Then
If InStr(1, Report.Cells(j, B.Column).Value, Report.Cells(i, A.Column).Value, vbTextCompare) > 0 Then
vMatch = vMatch + 1
Report.Cells(i, A.Column).Interior.ColorIndex = 35 'Light green background
Range(colC & 1).Value = "Items Found"
Report.Cells(i, A.Column).Copy Destination:=Range(colC & vMatch)
Exit For
Else
'Do Nothing
End If
End If
Next j
Next i
If vMatch = 1 Then
MsgBox Prompt:="No Itmes Found", Buttons:=vbInformation
End If
'***************************************************
Application.ScreenUpdating = True
End Sub
Don't wana do soo much work guyss..
Just Press Ctr and select Colum one and Press Ctr and select colum two.
Then click conditional formatting -> Highlight Cell Rules -> Equel To.
and thats it. your done. :)

Resources