VBA - Compare 2 columns for partial matches, and return only last 3 characters of matches

TropicalMagic

New Member
Joined
Jun 19, 2021
Messages
47
Office Version
  1. 365
Platform
  1. Windows
Hi all,

I’m trying to –
  1. Compare Column G from Workbook 1, starting from row 2, to only the first 10 characters in Column A, starting from row 9, from Workbook 2 for matching values
  2. If there are matching values, copy only the last 3 characters in Column A from Workbook 2 to Column F from Workbook 1
However, the macro is continuously running without ending. I'm not sure if there is any error present.

Here is my code:

VBA Code:
Dim Range1 As Range, Range2 As Range, Rng1 As Range, Rng2 As Range
Dim i As Long

Set Range1 = Workbook1.Sheet(1).Range("G9:G" & LASTROW1)
Set Range2 = Workbook2.Sheet(1).Range("A2:A" & LASTROW2)

For i = 9 to LASTROW1
For Each Rng1 in Range1
For Each Rng2 In Range2
If Rng1.Value = Left(Rng2.Value, 10) Then
    Right(Rng2.Value, 3).Copy
    Workbook1.Sheet(1).Range("F" & i).PasteSpecial
End If

Next
Next
Next

Many thanks in advance!
 

Excel Facts

Format cells as time
Select range and press Ctrl+Shift+2 to format cells as time. (Shift 2 is the @ sign).
Could you post your full code, and preferably a sample of your data?
 
Upvote 0
Sure, the full code can be given as:

(I have edited it to align with the sample data layout)

VBA Code:
Option Explicit

Sub LAST_3_CHARACTERS()

Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.AskToUpdateLinks = False

Dim Range1 As Range, Range2 As Range, Rng1 As Range, Rng2 As Range
Dim i As Long

Set Range1 = Workbook1.Sheet(1).Range("G9:G" & LASTROW1)
Set Range2 = Workbook2.Sheet(1).Range("A2:A" & LASTROW2)

For i = 9 to LASTROW1
For Each Rng1 in Range1
For Each Rng2 In Range2
If Rng1.Value = Left(Rng2.Value, 17) Then
    Right(Rng2.Value, 3).Copy
    Workbook2.Sheet(1).Range("G" & i).PasteSpecial
End If

Next
Next
Next

MsgBox "READY!"

Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.AskToUpdateLinks = True

End Sub

Here is the Mini-sheet for Workbook 1:

TEST.xlsx
ABCDEFG
1THIS AREA WILL BE UNUSED
2
3
4
5
6
7
8UNIQUE LOCATIONORIGIN LOCATIONORIGIN COUNTRYDESTINATION LOCATIONDESTINATION COUNTRYSERVICECREATURE
9SELKRMEBAULEVEL 1DOGSELKRMEBAULEVEL 1DOG
10SELKRMEBAULEVEL 2PIGSELKRMEBAULEVEL 2PIG
11SHACNLAXUSLEVEL 1PIGSHACNLAXUSLEVEL 1PIG
12SHACNNYCUSLEVEL 1CATSHACNNYCUSLEVEL 1CAT
13SHACNNYCUSLEVEL 1DOGSHACNNYCUSLEVEL 1DOG
14SHACNCHIUSLEVEL 2PIGSHACNCHIUSLEVEL 2PIG
15SHACNCHIUSLEVEL 1OWLSHACNCHIUSLEVEL 1OWL
16KULMYSINSINLEVEL 1PIGKULMYSINSINLEVEL 1PIG
17KULMYSINSINLEVEL 2PIGKULMYSINSINLEVEL 2PIG
18KULMYSINSINLEVEL 1DOGKULMYSINSINLEVEL 1DOG
19KULMYSINSINLEVEL 2DOGKULMYSINSINLEVEL 2DOG
WORKBOOK 1
Cell Formulas
RangeFormula
A9:A19A9=B9&C9&D9&E9&F9&G9


Here is the Mini-sheet for Workbook 2:

TEST.xlsx
ABCDEFG
1UNIQUE LOCATIONORIGIN LOCATIONORIGIN COUNTRYDESTINATION LOCATIONDESTINATION COUNTRYSERVICECREATURE
2SELKRMEBAULEVEL 1SELKRMEBAULEVEL 1
3SHACNCHIUSLEVEL 2SHACNCHIUSLEVEL 2
4SHACNNYCUSLEVEL 1SHACNNYCUSLEVEL 1
5KULMYSINSINLEVEL 2KULMYSINSINLEVEL 2
6KULMYSINSINLEVEL 1KULMYSINSINLEVEL 1
7KULMYSINSINLEVEL 2KULMYSINSINLEVEL 2
WORKBOOK 2
Cell Formulas
RangeFormula
A2:A7A2=B2&C2&D2&E2&F2


Many thanks!
 
Last edited:
Upvote 0
That's not the full code. I don't see a Sub() End Sub. You're using LASTROW1 as a variable, but nowhere in what you posted is that variable set. Could we see the full code please?
 
Upvote 0
Ignore my last post, & thank you for posting some data, although I still can't see where you set LASTROW1? (y):)
 
Upvote 1
to only the first 10 characters
Actually there are 17.
------------

In book 1, these 2 data (the 17 characters on the left) are repeated, so if you find the data in book 2, then you put CAT first and then DOG. Finally only "DOG" remains in the cell.
What should be done in those cases, or is it a typo in your example and that's not going to happen.
Cell Formulas
RangeFormula
A12:A13A12=B12&C12&D12&E12&F12&G12

-------------

Try the following macro. Set the names of your books in the data highlighted in blue.
Note: the 2 books must be open.
Rich (BB code):
Sub Compare2columns()
  Dim sh1 As Worksheet, sh2 As Worksheet
  Dim c As Range, f As Range
  
  Set sh1 = Workbooks("workbook1.xlsx").Sheets(1)
  Set sh2 = Workbooks("workbook2.xlsx").Sheets(1)

  For Each c In sh1.Range("A9", sh1.Range("A" & Rows.Count).End(3))
    Set f = sh2.Range("A:A").Find(Left(c.Value, 17), , xlValues, xlWhole, , , False)
    If Not f Is Nothing Then
      sh2.Range("G" & f.Row).Value = sh1.Range("G" & c.Row).Value
    End If
  Next
End Sub


--------------
Let me know the result and I'll get back to you as soon as I can.
Cordially
Dante Amor
--------------​
 
Upvote 1
Solution
I'm trying to get my head around your sample data. For example, in your workbook 2 under "UNIQUE LOCATION", some of the values are not unique (there are two KULMYSINSINLEVEL 2 - which doesn't make them unique). Therefore, which value from workbook 1 would you want returned - as there are two KULMYSINSINLEVEL 2 on there too, one for PIG and one for DOG?

Mindful of what I've said above, this code puts the first instance in. Like with Dante's code, you must have both workbooks open when you run it.

VBA Code:
Option Explicit
Sub Compare2columnsVersion2()
    Dim ws1 As Worksheet, ws2 As Worksheet
    Dim a, b, c, i As Long, j As Long
    Set ws1 = Workbooks("workbook1.xlsx").Sheets(1)
    Set ws2 = Workbooks("workbook2.xlsx").Sheets(1)
    
    a = ws2.Range("A2", ws2.Cells(Rows.Count, "A").End(xlUp))
    b = ws1.Range("A9", ws1.Cells(Rows.Count, "G").End(xlUp))
    ReDim c(1 To UBound(a, 1), 1 To 1)
    
    For i = 1 To UBound(a, 1)
        For j = 1 To UBound(b, 1)
            If b(j, 1) Like a(i, 1) & "*" Then
                c(i, 1) = b(j, 7)
                Exit For
            End If
        Next j
    Next i
    ws2.Range("G2").Resize(UBound(c, 1), 1).Value = c
End Sub
 
Upvote 1
Hi both,


Many thanks for responding to my query!

Apologies for being unclear in my initial query, I've simplified what I'm trying to do –
  1. Compare only the first 8 characters in Column A from Workbook 1 to Column A from Workbook 2, for matching values, starting from row 2 for both workbooks
  2. If there are matching values, copy only the last 3 characters in Column A from Workbook 1 to Column E from Workbook 2
  3. Otherwise, return "No Match" in Column E from Workbook 2
* Do note that the number of rows in each workbook is not the same.

Here is my full code used, assuming both workbooks have been opened and will be saved but not closed after being run, still non-functional:

VBA Code:
Option Explicit

Sub LAST_3_CHARACTERS()

Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.AskToUpdateLinks = False

Dim LASTROW1 As Long
LASTROW1 = Workbook1.Sheets(1).Range("A" & Rows.Count).End(xlUp).Row

Dim LASTROW2 As Long
LASTROW2 = Workbook2.Sheets(1).Range("A" & Rows.Count).End(xlUp).Row

Dim Range1 As Range, Range2 As Range, Rng1 As Range, Rng2 As Range
Dim i As Long

Set Range1 = Workbook1.Sheet(1).Range("A2:A" & LASTROW1)
Set Range2 = Workbook2.Sheet(1).Range("A2:A" & LASTROW2)

For i = 2 to LASTROW1
For Each Rng1 in Range1
For Each Rng2 In Range2

If Rng2.Value = Left(Rng1.Value, 10) Then
    Right(Rng1.Value, 3).Copy
    Workbook2.Sheet(1).Range("E" & i).PasteSpecial
End If

Next
Next
Next

MsgBox "READY!"

Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.AskToUpdateLinks = True

End Sub

I have also simplified the layout as follows -

Here is Workbook 1:

Book2
ABCDE
1FILE IDORIGINDESTINATIONSERVICEMOVEMENT
2TSNSIN22DOGTSNSIN22DOG
3TSNSIN11DOGTSNSIN11DOG
4TSNSIN22DOGTSNSIN22DOG
5TSNSIN11OWLTSNSIN11OWL
6SHASIN11DOGSHASIN11DOG
7SHASIN22DOGSHASIN22DOG
8SHASIN11DOGSHASIN11DOG
9SHASIN22DOGSHASIN22DOG
10SHASIN11CATSHASIN11CAT
11SHASIN22CATSHASIN22CAT
12SHASEL11CATSHASEL11CAT
13SHASEL22CATSHASEL22CAT
14SHASEL11DOGSHASEL11DOG
15SHASEL22DOGSHASEL22DOG
16SHASEL11DOGSHASEL11DOG
17SHASEL22DOGSHASEL22DOG
WORKBOOK 1
Cell Formulas
RangeFormula
A2:A17A2=B2&C2&D2&E2
Cells with Data Validation
CellAllowCriteria
D2:D17List=Services


Here is Workbook 2:

Book2
ABCDE
1FILE IDORIGINDESTINATIONSERVICEMOVEMENT
2TSNSIN22TSNSIN22
3TSNSIN11TSNSIN11
4TSNSIN22TSNSIN22
5TSNSIN11TSNSIN11
6SHASEL11SHASEL11
7SHASEL22SHASEL22
8SHASEL11SHASEL11
9SHASEL22SHASEL22
10SHASEL11SHASEL11
11SHASEL22SHASEL22
WORKBOOK 2
Cell Formulas
RangeFormula
A2:A11A2=B2&C2&D2
Cells with Data Validation
CellAllowCriteria
D2:D11List=Services


Here is the expected result in Workbook 2:

Book2
ABCDE
1FILE IDORIGINDESTINATIONSERVICEMOVEMENT
2TSNSIN22TSNSIN22DOG
3TSNSIN11TSNSIN11DOG
4TSNSIN22TSNSIN22DOG
5TSNSIN11TSNSIN11OWL
6SHASEL11SHASEL11CAT
7SHASEL22SHASEL22CAT
8SHASEL11SHASEL11DOG
9SHASEL22SHASEL22DOG
10SHASEL11SHASEL11DOG
11SHASEL22SHASEL22DOG
WORKBOOK 2 FINAL RESULT
Cell Formulas
RangeFormula
A2:A11A2=B2&C2&D2
Cells with Data Validation
CellAllowCriteria
D2:D11List=Services


I'm also trying to figure out how to implement your solutions into the code but I'm also wondering if I missed anything as they are not working as well.

Would appreciate any new ideas too!

Many thanks in advance!
 
Upvote 0
Hi both DanteAmor and kevin9999,


Many thanks to you both for offering solutions!

I have applied DanteAmor's solution and found it to suit my needs!


Here is what I was trying to do –
  1. Compare only the first 8 characters in Column A from Workbook 1 to Column A from Workbook 2, for matching values, starting from row 2 for both workbooks
  2. If there are matching values, copy only the last 3 characters in Column A from Workbook 1 to Column E from Workbook 2

* Do note that the number of rows in each workbook is not the same.

Workbook1:

FORUM LAYOUT.xlsx
ABCDE
1FILE IDORIGINDESTINATIONSERVICEMOVEMENT
2TSNSIN22DOGTSNSIN22DOG
3TSNSIN11DOGTSNSIN11DOG
4TSNSIN22DOGTSNSIN22DOG
5TSNSIN11OWLTSNSIN11OWL
6SHASIN11DOGSHASIN11DOG
7SHASIN22DOGSHASIN22DOG
8SHASIN11DOGSHASIN11DOG
9SHASIN22DOGSHASIN22DOG
10SHASIN11CATSHASIN11CAT
11SHASIN22CATSHASIN22CAT
12SHASEL11CATSHASEL11CAT
13SHASEL22CATSHASEL22CAT
14SHASEL11DOGSHASEL11DOG
15SHASEL22DOGSHASEL22DOG
16SHASEL11DOGSHASEL11DOG
17SHASEL22DOGSHASEL22DOG
WORKBOOK 1
Cell Formulas
RangeFormula
A2:A17A2=B2&C2&D2&E2
Cells with Data Validation
CellAllowCriteria
D2:D17List=Services


Workbook 2:

FORUM LAYOUT.xlsx
ABCDE
1FILE IDORIGINDESTINATIONSERVICEMOVEMENT
2TSNSIN22TSNSIN22
3TSNSIN11TSNSIN11
4TSNSIN22TSNSIN22
5TSNSIN11TSNSIN11
6SHASEL11SHASEL11
7SHASEL22SHASEL22
8SHASEL11SHASEL11
9SHASEL22SHASEL22
10SHASEL11SHASEL11
11SHASEL22SHASEL22
WORKBOOK 2
Cell Formulas
RangeFormula
A2:A11A2=B2&C2&D2
Cells with Data Validation
CellAllowCriteria
D2:D11List=Services


Here is the full working code:

VBA Code:
Option Explicit

Sub LAST_3_CHARACTERS()

Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.AskToUpdateLinks = False

Dim LASTROW1 As Long
LASTROW1 = Workbook1.Sheets(1).Range("A" & Rows.Count).End(xlUp).Row

Dim LASTROW2 As Long
LASTROW2 = Workbook2.Sheets(1).Range("A" & Rows.Count).End(xlUp).Row

Dim sh1 As Worksheet, sh2 As Worksheet
Dim c As Range, f As Range

Set sh1 = Workbook1.Sheets(1)
Set sh2 = Workbook2.Sheets(1)

For Each c In sh1.Range("A2", sh1.Range("A" & Rows.Count).End(3))
Set f = sh2.Range("A:A").Find(Left(c.Value, 8), , xlValues, xlWhole, , , False)
If Not f Is Nothing Then
    sh2.Range("E" & f.Row).Value = sh1.Range("A" & c.Row).Value
End If
Next

MsgBox "READY!"

Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.AskToUpdateLinks = True

End Sub

Many thanks!!

☺️☺️
 
Upvote 0
Actually there are 17.
------------

In book 1, these 2 data (the 17 characters on the left) are repeated, so if you find the data in book 2, then you put CAT first and then DOG. Finally only "DOG" remains in the cell.
What should be done in those cases, or is it a typo in your example and that's not going to happen.
Cell Formulas
RangeFormula
A12:A13A12=B12&C12&D12&E12&F12&G12

-------------

Try the following macro. Set the names of your books in the data highlighted in blue.
Note: the 2 books must be open.
Rich (BB code):
Sub Compare2columns()
  Dim sh1 As Worksheet, sh2 As Worksheet
  Dim c As Range, f As Range
  
  Set sh1 = Workbooks("workbook1.xlsx").Sheets(1)
  Set sh2 = Workbooks("workbook2.xlsx").Sheets(1)

  For Each c In sh1.Range("A9", sh1.Range("A" & Rows.Count).End(3))
    Set f = sh2.Range("A:A").Find(Left(c.Value, 17), , xlValues, xlWhole, , , False)
    If Not f Is Nothing Then
      sh2.Range("G" & f.Row).Value = sh1.Range("G" & c.Row).Value
    End If
  Next
End Sub


--------------
Let me know the result and I'll get back to you as soon as I can.
Cordially
Dante Amor
--------------​

Hello. Thank you for this beautiful symbol as usual. How can you add another column condition so that the comparison is made, for example, in column A and column C?
 
Upvote 0

Forum statistics

Threads
1,224,940
Messages
6,181,887
Members
453,068
Latest member
DCD1872

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top