Compare data in two columns and extract the value to another column - excel

I have a column (B) that contains many cities. I want to search in every row of column (A). If it contains a value from column B this value should be written in column (C).
I made a code that searches a static value. I want this value to be the row of (column A).
Public Function searchColumn()
V_End_Of_Table = ActiveSheet.UsedRange.Rows.Count 'count the number of rows used'
Dim cell As Range
For Each cell In Range("A1:A" & V_End_Of_Table)
If InStr(1, cell.Value, "anfa", vbTextCompare) > 0 Then
Range("C" & cell.Row).Value = "anfa"
Else
Range("C" & cell.Row).Value = "No Match Found"
End If
Next 'move onto next cell'
End Function
Edit
Column A | Column B | Column C
------------+---------------+------------
casa anfa | omar | anfa
rabat hassan| hassan | hassan
casa maarouf| maarouf | maarouf
casa omar | anfa | omar
| sultan |
| driss |
Column C is the column that I want to create.

try this
For i = 1 To V_End_Of_Table 'loop for column A
For j = 1 To V_End_Of_Table 'loop for column B
If InStr(1, Cells(i, 1).Value, Cells(j, 2).Value) > 0 Then
Cells(i, 3).Value = Cells(j, 2).Value 'write found B value in c column
Exit For
Else
Cells(i, 3).Value = "no match found"
End If
If Cells(j + 1, 2).Value = "" Then
Exit For
End If
Next j
Next i

Maybe with a formula:
=IF(ISERROR(MATCH("*"&B1,A:A,0)),"",MID(A1,FIND(" ",A1)+1,LEN(A1)))

try this solution
Sub test()
Dim oCellSearch As Range, oCellSource As Range, KeySource, Key
Dim Source As Object: Set Source = CreateObject("Scripting.Dictionary")
Dim Search As Object: Set Search = CreateObject("Scripting.Dictionary")
'Grab the data from the WorkSheets into Dictionaries
n = Cells(Rows.Count, "B").End(xlUp).Row
For Each oCellSearch In ActiveSheet.Range("B1:B" & n)
If oCellSearch.Value <> "" Then
Search.Add oCellSearch.Row, oCellSearch.Value
End If
Next
n = Cells(Rows.Count, "A").End(xlUp).Row
For Each oCellSource In ActiveSheet.Range("A1:A" & n)
If oCellSource.Value <> "" Then
Source.Add oCellSource.Row, oCellSource.Value
End If
Next
'Match for contain
For Each Key In Search
For Each KeySource In Source
If UCase(Source(KeySource)) Like "*" & UCase(Search(Key)) & "*" Then
ActiveSheet.Cells(Key, "C").Value = Search(Key): Exit For
End If
Next
Next
End Sub

Related

Validate column value against value in another column

I am working on my vba exercise and I have two columns L and I. The value in column I depends on column L.
So if column L has value "s" in a row then column I should have value "0" in the same row, otherwise the I, L column should be colored red.
If column L has one of the values in array in a row then column I should have nothing in the same
row, otherwise the I, L column should be colored red.
The problem is I struggle to make it work in VBA
Also, even if there is a way to do it differently then in VBA I have to do this exercise in VBA.
How can I compare values from the same row that are in two different columns that are not next to each other? Can you help?
Sub validate()
Dim i As Long
Set active_sheet = ActiveSheet
LstRow = active_sheet.Range("I" & active_sheet.Rows.Count).End(xlUp).Row
Set RngOrders = active_sheet.Range("L2:L" & last_row)
Set RngPackages = active_sheet.Range("I2:L" & LstRow)
MValues = Array("M", "kg", "j.m.", "g")
For i = 1 To RngPackages
If RngOrders(i) = "s" And RngPackages(i) <> "0" Then
RngPackages(i).Interior.Color = vbRed
ElseIf RngOrders(i) in MValues And RngPackages(i) <> "" Then
RngPackages(i).Interior.Color = vbRed
Next i
End Sub
Sub validate_someones_homework()
' Tools -> References -> Microsoft Scripting Runtime -> check
Dim ws As Worksheet: Set ws = ActiveSheet
Dim lastRow As Long: lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
Dim MValues As New Scripting.Dictionary
MValues.Add "M", 0
MValues.Add "kg", 0
MValues.Add "j.m.", 0
MValues.Add "g", 0
Dim r As Long
For r = 1 To lastRow
If ws.Cells(r, 12).Value = "s" And Not ws.Cells(r, 9).Value = 0 Then
ws.Cells(r, 9).Interior.Color = vbRed
ElseIf MValues.Exists(ws.Cells(r, 12).Value) And Not ws.Cells(r, 9).Value = "" Then
ws.Cells(r, 9).Interior.Color = vbRed
End If
Next r
End Sub

Excel VBA - If Column A is blank combine Column C of same row with Column C of row above

I have rows of data
Some rows are blank apart from Column C
If Column A is blank then I would like to concatenate Column C with column C from the row above - then delete the row. There could be situations where Column A has 2 or more blank rows, so that would require all those rows in Column C to be merged together
This is the code I used, but I keep getting a mismatch error - not sure where I am going wrong, but the error highlights the line with the offsets in
Sub Merge()
Dim rng As Range
Set ws = Worksheets("test") 'Change your sheet name
Set rng = ws.Range("A1:M5600")
With ws
For i = rng.Rows.Count To 1 Step -1
If .Cells(i, 1) = "" Then
.Cells(i, 3).Offset(-1) = .Cells(i, 3).Offset(-1) & .Cells(i, 3)
.Rows(i).EntireRow.Delete
End If
Next
End With
End Sub
Maybe my comment is not very clear, this is what I mean:
If .Cells(i, 1).Value = "" Then
.Cells(i, 3).Offset(-1).Value = .Cells(i, 3).Offset(-1).Value & ", " & .Cells(i, 3).Value
(I also added ", " for readability purposes)
Edit after comment
.Cells(i, 3).Offset(-1).Value = CStr(.Cells(i, 3).Offset(-1).Value) & ", " & CStr(.Cells(i, 3).Value)
Is that better?

Excel VBA compare columns

I am trying to compare two tables on the same excel sheet between rows. Following is what i am trying to achieve. I have worked something out, but it's not functionnal as it deletes rows...
A B C D E F
E1 40 12 4 4/16/2017 E4
E2 20 1 5 6/22/2016 E2
E1 10 0 4 6/30/2017 E1
E1 40 12 6 4/16/2017 E4
Should turn into :
A B C D E F
E1 40 12 4;6 4/16/2017 E4
E2 20 1 5 6/22/2016 E2
E1 10 0 4 6/30/2017 E1
TASK 1
If column A matches
If column B matches
If column C matches
If column F matches
Then
Concatenate rows on lines D and add a ";" between values
And delete rows that are concatenated.
I have achieved this with this code (just added the condition for F but it's not workind) , but it's not functional already without it, as it doesn't store values in a dictionnary probably and jumps rows, so it doesn't concatenate all of the values in the sheet and skips some too...
Sub TEMPLATE()
Dim lngRow As Long For lngRow = ActiveSheet.Cells(Rows.Count, "B").End(xlUp).Row To 2 Step -1
If StrComp(Range("B" & lngRow), Range("B" & lngRow - 1), vbTextCompare) = 0 And
If StrComp(Range("A" & lngRow), Range("A" & lngRow - 1), vbTextCompare) = 0 And
If StrComp(Range("C" & lngRow), Range("C" & lngRow - 1), vbTextCompare) = 0 And
If StrComp(Range("F" & lngRow), Range("F" & lngRow - 1), vbTextCompare) = 0
Then
If Range("D" & lngRow) <> "" Then
Range("D" & lngRow - 1) = Range("D" & lngRow - 1) & ";" & Range("D" & lngRow)
End If
Rows(lngRow).Delete
End If
Next
End Sub
TASK 2
Since this is an update file, I would like to compare every rows on the old file and make changes, and highloght them, if possible. Let's say, if my E1 line up there has been added a value on B, it would highlight B case and add the value.
I don't know how to do this one, I believe it should loop between the old sheet and the updated sheet where I run the previous macro.
Thanks guys for your help !
The code below should complete your TASK 1. It assumes everything is in the first sheet. It works with your example, but I haven't tested it much further so beware. However, I think it's clear enough so you can edit it if needed.
TASK 1:
Sub filter_data()
'Initialize iterator at row 1
i = 0
'Loop through data until no more rows
Do While Sheets(1).Range("A1").Offset(i, 0).Value2 <> ""
'Get values of row
A_val_1 = Sheets(1).Range("A1").Offset(i, 0).Value2
B_val_1 = Sheets(1).Range("A1").Offset(i, 1).Value2
C_val_1 = Sheets(1).Range("A1").Offset(i, 2).Value2
D_val_1 = Sheets(1).Range("A1").Offset(i, 3).Value2
F_val_1 = Sheets(1).Range("A1").Offset(i, 5).Value2
'Loop through data again to check if duplicates
j = i 'Initialize iterator at row i
Do While Sheets(1).Range("A1").Offset(j, 0).Value2 <> ""
If j <> i Then 'Skip selected row
'Get values of row
A_val_2 = Sheets(1).Range("A1").Offset(j, 0).Value2
B_val_2 = Sheets(1).Range("A1").Offset(j, 1).Value2
C_val_2 = Sheets(1).Range("A1").Offset(j, 2).Value2
D_val_2 = Sheets(1).Range("A1").Offset(j, 3).Value2
F_val_2 = Sheets(1).Range("A1").Offset(j, 5).Value2
'If conditions satisfied
If A_val_1 = A_val_2 And B_val_1 = B_val_2 And C_val_1 = C_val_2 And F_val_1 = F_val_2 Then
'Concatenate on D
Sheets(1).Range("A1").Offset(i, 3).Value2 = Sheets(1).Range("A1").Offset(i, 3).Value2 & ";" & D_val_2
'Delete duplicate row
Sheets(1).Rows(j + 1).Delete
'Decrement incrementor by 1 to make up for deleted row
j = j - 1
End If
End If
j = j + 1 'increment
Loop
i = i + 1 'increment
Loop
End Sub
Maybe (?) I'll get back to TASK 2 later, but that should be very straightforward - you just need to loop through all cells, compare an highlight.
EDIT: Task 2 below as far as I understood it. It only checks for difference in the new sheet, highlights differences from old sheet cell-wise and appends the old value to the LEFT of the new value (can be changed). Again, it works with your example.
TASK 2:
Sub compare_data()
'Initialize sheets to compare; only cells on new sheet will be highlighted
old_sheet_idx = 1 'index of old sheet
new_sheet_idx = 2 'index of updated sheet
'Get number of populated rows & column in new sheet
new_sheet_rows = Range(Sheets(new_sheet_idx).Range("A1"), Sheets(new_sheet_idx).Range("A1").End(xlDown)).Count
new_sheet_cols = Range(Sheets(new_sheet_idx).Range("A1"), Sheets(new_sheet_idx).Range("A1").End(xlToRight)).Count
'Clear all formats in new sheet
Sheets(new_sheet_idx).Cells.ClearFormats
'Loop through all rows of new sheet
For i = 1 To new_sheet_rows
'Loop through all cells of the row
For j = 1 To new_sheet_cols
'Get cell value
new_cell = Sheets(new_sheet_idx).Range("A" & i).Offset(0, j - 1).Value2
old_cell = Sheets(old_sheet_idx).Range("A" & i).Offset(0, j - 1).Value2
'Compare
If new_cell <> old_cell Then
Sheets(new_sheet_idx).Range("A" & i).Offset(0, j - 1).Interior.ColorIndex = 6 'highlight yellow
Sheets(new_sheet_idx).Range("A" & i).Offset(0, j - 1).Value2 = old_cell & ";" & new_cell 'concatenate old value;new value
End If
Next j
Next i
End Sub

How to return parts of a string?

I have these cells:
Strings in cells
I would like to return specific parts of these strings - the "...bar" and "also csatlakozas" or "hatso csatlakozas" - to other cells.
Try below code, this should get you started:
Sub ExtractMatchingCells()
'Define in which column data is located
col = 1
lastRow = Cells(Rows.Count, col).End(xlUp).Rows
For i = 1 To lastRow
' Extract cell value to cell to the right
If InStr(0, Cells(i, col), "bar (also csatlakozas)") > 0 Or InStr(0, Cells(i, col), "bar (hatso csatlakozas)") Then
Cells(i, col + 1) = Cells(i, col)
End If
Next
End Sub

Excel VBA: Compare Delimited String in Cell to Column of Values

I have a list of (semi-colon delimited) genes within column B I want to create from that list, a list of the genes which are found in Column A.
| Keep | List | | Result |
|------------------|----------------------------|---|-------------|
| AASS;SESN1;SEPT5 | AASS | | AASS |
| | ARMC2;SESN1;ARMC2AS1;SEPT5 | | SESN1;SEPT5 |
| | | | |
I have a start on a code, but it only appears to work for some of the gene lists, but not all.
For example, the lists in cells B2 and B3 are extracted to Column C correctly, but cell B4 ends up with 7 extra terms (but running the VBA Script a second time results in the correct number & composition), and B5 results in a strange output "4;5;0;2;3;1;SNORD1161" in D5.
This the code that I have so far, and it was modified from: https://www.mrexcel.com/forum/excel-questions/654920-match-comma-delimited-values-cell-against-individual-values-column.html
Any help would be appreciated! Thanks!
Sub matchups2()
Dim regex_leading As New VBScript_RegExp_55.RegExp
Dim regex_middle As New VBScript_RegExp_55.RegExp
Dim regex_trailing As New VBScript_RegExp_55.RegExp
Set d = CreateObject("scripting.dictionary")
For Each gene In Range("A2", Cells(Rows.Count, "A").End(3)).Value
d(gene) = 1
Next gene
Stop
For Each genelist In Range("B2", Cells(Rows.Count, "B").End(3))
c = genelist.Value
k = genelist.Row
For Each q In Split(c, ";")
If d(q) <> 1 Then
c = Replace(c, q, ";")
End If
Next q
regex_leading.Pattern = "^;{1,}"
With regex_middle
.Pattern = ";{1,}"
.Global = True
End With
regex_trailing.Pattern = ";{1,}$"
c = regex_leading.Replace(c, "")
c = regex_middle.Replace(c, ";")
c = regex_trailing.Replace(c, "")
Cells(k, "D").Value = c
Next genelist
End Sub
I think this should work for you.
Sub GenesDict()
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
'add A genes to dictionary
Dim i As Long
For i = 2 To Cells(Rows.Count, "A").End(xlUp).Row
Dim temp As Variant
temp = Split(Cells(i, "A").Value2, ";")
Dim j As Long
For j = LBound(temp) To UBound(temp)
dict.Add Trim(temp(j)), "text"
Next j
Next i
'clear D
Range("D2:D" & Range("D" & Rows.Count).End(xlUp).Row).ClearContents
'transfer from B to D only genes in A
For i = 2 To Cells(Rows.Count, "B").End(xlUp).Row
temp = Split(Cells(i, "B").Value2, ";")
For j = LBound(temp) To UBound(temp)
If dict.exists(Trim(temp(j))) Then
Cells(i, "D").Value2 = Cells(i, "D").Value2 & Trim(temp(j)) & ";"
End If
Next j
'remove trailing ";"
If Right(Cells(i, "D").Value2, 1) = ";" Then
Cells(i, "D").Value2 = Left(Cells(i, "D").Value2, Len(Cells(i, "D").Value2) - 1)
End If
Next i
End Sub

Resources