Merge Data from Two Tables Based on a Lookup Value

theabdulrab

New Member
Joined
Feb 26, 2018
Messages
4
Hi,

I have two tables that have one column with similar values. I need to create a table that would merge the data from both the tables based on the matched values.

I have prepared a Sample Sheet.

https://www.dropbox.com/s/wq1nin6x6v0gfxg/Sample for Help.xlsx?dl=0

Concatenating the tables and VLooking up the data is not an option since only the lookup values are same but not the corresponding data.

I have searched extensively but unable to find anything.

Any help would be greatly appreciated.

Thank you.
 

Excel Facts

Control Word Wrap
Press Alt+Enter to move to a new row in a cell. Lets you control where the words wrap.
Try this for results on sheet2.

Code:
[COLOR="Navy"]Sub[/COLOR] MG26Feb56
[COLOR="Navy"]Dim[/COLOR] Rng [COLOR="Navy"]As[/COLOR] Range, Dn [COLOR="Navy"]As[/COLOR] Range, n [COLOR="Navy"]As[/COLOR] [COLOR="Navy"]Long,[/COLOR] T1 [COLOR="Navy"]As[/COLOR] Range, T2 [COLOR="Navy"]As[/COLOR] Range, ac [COLOR="Navy"]As[/COLOR] [COLOR="Navy"]Long[/COLOR]
[COLOR="Navy"]Dim[/COLOR] Ray() [COLOR="Navy"]As[/COLOR] Variant, c [COLOR="Navy"]As[/COLOR] [COLOR="Navy"]Long,[/COLOR] R [COLOR="Navy"]As[/COLOR] Range
Set T1 = Range("B3:B9") '[COLOR="Green"][B]Change Range address as required[/B][/COLOR]
Set T2 = Range("G3:G9") '[COLOR="Green"][B]Change Range address as required[/B][/COLOR]
[COLOR="Navy"]With[/COLOR] CreateObject("scripting.dictionary")
.CompareMode = vbTextCompare
    [COLOR="Navy"]For[/COLOR] [COLOR="Navy"]Each[/COLOR] Dn [COLOR="Navy"]In[/COLOR] T2
        [COLOR="Navy"]If[/COLOR] Not .exists(Dn.Value) [COLOR="Navy"]Then[/COLOR]
            .Add Dn.Value, Dn
        [COLOR="Navy"]Else[/COLOR]
            [COLOR="Navy"]Set[/COLOR] .Item(Dn.Value) = Union(.Item(Dn.Value), Dn)
        [COLOR="Navy"]End[/COLOR] If
    [COLOR="Navy"]Next[/COLOR]
[COLOR="Navy"]For[/COLOR] [COLOR="Navy"]Each[/COLOR] Dn [COLOR="Navy"]In[/COLOR] T1
  [COLOR="Navy"]If[/COLOR] .exists(Dn.Value) [COLOR="Navy"]Then[/COLOR]
    [COLOR="Navy"]For[/COLOR] [COLOR="Navy"]Each[/COLOR] R [COLOR="Navy"]In[/COLOR] .Item(Dn.Value)
        c = c + 1
        ReDim Preserve Ray(1 To 7, 1 To c)
        [COLOR="Navy"]For[/COLOR] ac = 1 To 7
            [COLOR="Navy"]If[/COLOR] ac <= 4 [COLOR="Navy"]Then[/COLOR]
            Ray(ac, c) = Dn(, ac)
            [COLOR="Navy"]Else[/COLOR]
            Ray(ac, c) = R.Offset(, ac - 4).Value
            [COLOR="Navy"]End[/COLOR] If
        [COLOR="Navy"]Next[/COLOR] ac
    [COLOR="Navy"]Next[/COLOR] R
  [COLOR="Navy"]End[/COLOR] If
[COLOR="Navy"]Next[/COLOR] Dn
[COLOR="Navy"]End[/COLOR] With
[COLOR="Navy"]With[/COLOR] Sheets("Sheet2").Range("A1").Resize(c, 7)
    .Value = Application.Transpose(Ray)
    .Borders.Weight = 2
    .Columns.AutoFit
    .HorizontalAlignment = xlCenter
[COLOR="Navy"]End[/COLOR] [COLOR="Navy"]With[/COLOR]
[COLOR="Navy"]End[/COLOR] [COLOR="Navy"]Sub[/COLOR]
Regards Mick
 
Upvote 0
Thank you so much Mick. This works perfectly.

Just one question. If my Table are present in different files, then how will the T1 and T2 value be set. For example: Table1 filename is List.xlsx and Table2 Filename is Prod.xlsx.

Thank again for taking out time to help.

Kind Regards.
 
Upvote 0
Try this:-
Code:
[COLOR="Navy"]Sub[/COLOR] MG26Feb00
[COLOR="Navy"]Dim[/COLOR] Rng [COLOR="Navy"]As[/COLOR] Range, Dn [COLOR="Navy"]As[/COLOR] Range, n [COLOR="Navy"]As[/COLOR] [COLOR="Navy"]Long,[/COLOR] T1 [COLOR="Navy"]As[/COLOR] Range, T2 [COLOR="Navy"]As[/COLOR] Range, ac [COLOR="Navy"]As[/COLOR] [COLOR="Navy"]Long[/COLOR]
[COLOR="Navy"]Dim[/COLOR] Ray() [COLOR="Navy"]As[/COLOR] Variant, c [COLOR="Navy"]As[/COLOR] [COLOR="Navy"]Long,[/COLOR] R [COLOR="Navy"]As[/COLOR] Range
[COLOR="Navy"]With[/COLOR] Workbooks("List.xlsx").Sheets("sheet1")
    Set T1 = .Range("B3:B9") '[COLOR="Green"][B]Change Range address as required[/B][/COLOR]
[COLOR="Navy"]End[/COLOR] With
[COLOR="Navy"]With[/COLOR] Workbooks("Prod.xlsx").Sheets("sheet1")
    Set T2 = .Range("G3:G9") '[COLOR="Green"][B]Change Range address as required[/B][/COLOR]
[COLOR="Navy"]End[/COLOR] With
[COLOR="Navy"]With[/COLOR] CreateObject("scripting.dictionary")
.CompareMode = vbTextCompare
    [COLOR="Navy"]For[/COLOR] [COLOR="Navy"]Each[/COLOR] Dn [COLOR="Navy"]In[/COLOR] T2
        [COLOR="Navy"]If[/COLOR] Not .exists(Dn.Value) [COLOR="Navy"]Then[/COLOR]
            .Add Dn.Value, Dn
        [COLOR="Navy"]Else[/COLOR]
            [COLOR="Navy"]Set[/COLOR] .Item(Dn.Value) = Union(.Item(Dn.Value), Dn)
        [COLOR="Navy"]End[/COLOR] If
    [COLOR="Navy"]Next[/COLOR]
[COLOR="Navy"]For[/COLOR] [COLOR="Navy"]Each[/COLOR] Dn [COLOR="Navy"]In[/COLOR] T1
  [COLOR="Navy"]If[/COLOR] .exists(Dn.Value) [COLOR="Navy"]Then[/COLOR]
    [COLOR="Navy"]For[/COLOR] [COLOR="Navy"]Each[/COLOR] R [COLOR="Navy"]In[/COLOR] .Item(Dn.Value)
        c = c + 1
        ReDim Preserve Ray(1 To 7, 1 To c)
        [COLOR="Navy"]For[/COLOR] ac = 1 To 7
            [COLOR="Navy"]If[/COLOR] ac <= 4 [COLOR="Navy"]Then[/COLOR]
            Ray(ac, c) = Dn(, ac)
            [COLOR="Navy"]Else[/COLOR]
            Ray(ac, c) = R.Offset(, ac - 4).Value
            [COLOR="Navy"]End[/COLOR] If
        [COLOR="Navy"]Next[/COLOR] ac
    [COLOR="Navy"]Next[/COLOR] R
  [COLOR="Navy"]End[/COLOR] If
[COLOR="Navy"]Next[/COLOR] Dn
[COLOR="Navy"]End[/COLOR] With
[COLOR="Navy"]With[/COLOR] Sheets("Sheet2").Range("A1").Resize(c, 7)
    .Value = Application.Transpose(Ray)
    .Borders.Weight = 2
    .Columns.AutoFit
    .HorizontalAlignment = xlCenter
[COLOR="Navy"]End[/COLOR] [COLOR="Navy"]With[/COLOR]
[COLOR="Navy"]End[/COLOR] [COLOR="Navy"]Sub[/COLOR]
Regards Mick
 
Upvote 0
Hello Mick,

I have added some codes from various places to the code that you provided in order for users to select a file instead of hard-coding the file name. I am stuck at setting the dynamic ranges
and
. The actual files will have close to 150K records in each file. So, instead of hard-coding the range, I am trying to dynamically set the values of
and
.

Would you please let me know how to set the ranges dynamically.

Here is the entire code:

Code:
Sub GetFilesAndMerge()
' Keyboard Shortcut: Ctrl+Shift+V

'First-off setting the current workbook in a workbook variable so that after opening First & Second Files, The Data is Merged in this File instead of any other File
'https://stackoverflow.com/questions/12386448/vba-changing-active-workbook

Dim CurrentWorkBook As Workbook
Set CurrentWorkBook = ActiveWorkbook

'Following is the code I searched for on the internet.
'https://www.mrexcel.com/forum/excel-questions/551609-vba-how-open-file-input-user-via-browse.html

'The Following Code is Going to Ask User To Select The First File

Dim ListFileNameandPath As Variant, LWB As Workbook
ListFileNameandPath = Application.GetOpenFilename(FileFilter:="Excel Files (*.XLSX), *.XLSX", Title:="Select First File")
If ListFileNameandPath = False Then Exit Sub
Set LWB = Workbooks.Open(ListFileNameandPath)

'The Following Code is Going to Ask User To Select The Second File

Dim ModelFileNameandPath As Variant, MWB As Workbook
ModelFileNameandPath = Application.GetOpenFilename(FileFilter:="Excel Files (*.XLSX), *.XLSX", Title:="Select Second File")
If ModelFileNameandPath = False Then Exit Sub
Set MWB = Workbooks.Open(ModelFileNameandPath)


'Following is the code that I received from Mick
'https://www.mrexcel.com/forum/excel-questions/1045163-merge-data-two-tables-based-lookup-value.html#post5017132

Dim Rng As Range, Dn As Range, n As Long, T1 As Range, T2 As Range, ac As Long
Dim Ray() As Variant, c As Long, R As Range

With LWB.Sheets("sheet1")
    Set T1 = .Range("A1:A7") 'Change Range address as required
End With

With MWB.Sheets("sheet1")
    Set T2 = .Range("A1:A7") 'Change Range address as required
End With

With CreateObject("scripting.dictionary")
.CompareMode = vbTextCompare
    For Each Dn In T2
        If Not .exists(Dn.Value) Then
            .Add Dn.Value, Dn
        Else
            Set .Item(Dn.Value) = Union(.Item(Dn.Value), Dn)
        End If
    Next
For Each Dn In T1
  If .exists(Dn.Value) Then
    For Each R In .Item(Dn.Value)
        c = c + 1
        ReDim Preserve Ray(1 To 7, 1 To c)
        For ac = 1 To 7
            If ac <= 4 Then
            Ray(ac, c) = Dn(, ac)
            Else
            Ray(ac, c) = R.Offset(, ac - 4).Value
            End If
        Next ac
    Next R
  End If
Next Dn
End With

'Activating the workbook where the data will be merged. The variable CurrentWorkBook was defined at the start of the script
'https://stackoverflow.com/questions/12386448/vba-changing-active-workbook

CurrentWorkBook.Activate

With ActiveSheet.Range("A1").Resize(c, 7)
    .Value = Application.Transpose(Ray)
    .Borders.Weight = 2
    .Columns.AutoFit
    .HorizontalAlignment = xlCenter
End With

LWB.Close savechanges:=False 'or false
MWB.Close savechanges:=False 'or false

End Sub

Thanks for all your help Mick.
 
Upvote 0
Try this:-
NB:- When you selecting files I think the first file selected, is the first in the folder list, so it important to know your files are in the correct order, other wise there will be problems.
Also its important that the selected files relate to the same sheets/Ranges as the code!!.
This code relies entirely on the correct selection of the files !!!
Code:
[COLOR="Navy"]Sub[/COLOR] MG28Feb02
[COLOR="Navy"]Dim[/COLOR] Rng [COLOR="Navy"]As[/COLOR] Range, Dn [COLOR="Navy"]As[/COLOR] Range, n [COLOR="Navy"]As[/COLOR] [COLOR="Navy"]Long,[/COLOR] T1 [COLOR="Navy"]As[/COLOR] Range, T2 [COLOR="Navy"]As[/COLOR] Range, ac [COLOR="Navy"]As[/COLOR] [COLOR="Navy"]Long[/COLOR]
[COLOR="Navy"]Dim[/COLOR] Ray() [COLOR="Navy"]As[/COLOR] Variant, c [COLOR="Navy"]As[/COLOR] [COLOR="Navy"]Long,[/COLOR] R [COLOR="Navy"]As[/COLOR] Range
[COLOR="Navy"]Dim[/COLOR] LWB [COLOR="Navy"]As[/COLOR] Workbook, MWB [COLOR="Navy"]As[/COLOR] Workbook
  [COLOR="Navy"]Dim[/COLOR] myFile [COLOR="Navy"]As[/COLOR] Variant
    [COLOR="Navy"]Dim[/COLOR] i [COLOR="Navy"]As[/COLOR] [COLOR="Navy"]Integer[/COLOR]
    myFile = Application.GetOpenFilename(FileFilter:="Excel files (*.xlsx), *.xlsx", MultiSelect:=True)
        If IsArray(myFile) Then  '[COLOR="Green"][B]<~~ If user selects multiple file[/B][/COLOR]
        [COLOR="Navy"]For[/COLOR] i = LBound(myFile) To UBound(myFile)
           DoEvents
           '[COLOR="Green"][B] MsgBox myFile(i)[/B][/COLOR]
            Workbooks.Open (myFile(i))
            [COLOR="Navy"]If[/COLOR] i = 1 [COLOR="Navy"]Then[/COLOR]
                [COLOR="Navy"]Set[/COLOR] LWB = Workbooks(Dir(myFile(i)))
            [COLOR="Navy"]Else[/COLOR]
                [COLOR="Navy"]Set[/COLOR] MWB = Workbooks(Dir(myFile(i)))
            [COLOR="Navy"]End[/COLOR] If
        [COLOR="Navy"]Next[/COLOR] i
    Else '[COLOR="Green"][B]<~~ If user selects single file[/B][/COLOR]
        MsgBox myFile
        [COLOR="Navy"]If[/COLOR] myFile = False [COLOR="Navy"]Then[/COLOR] [COLOR="Navy"]Exit[/COLOR] [COLOR="Navy"]Sub[/COLOR]
    [COLOR="Navy"]End[/COLOR] If
'[COLOR="Green"][B]###################[/B][/COLOR]
[COLOR="Navy"]With[/COLOR] LWB.Sheets("sheet1")
    Set T1 = .Range("B3:B9") '[COLOR="Green"][B]Change Range address as required[/B][/COLOR]
[COLOR="Navy"]End[/COLOR] With
[COLOR="Navy"]With[/COLOR] MWB.Sheets("sheet1")
    Set T2 = .Range("G3:G9") '[COLOR="Green"][B]Change Range address as required[/B][/COLOR]
[COLOR="Navy"]End[/COLOR] With
[COLOR="Navy"]With[/COLOR] CreateObject("scripting.dictionary")
.CompareMode = vbTextCompare
    [COLOR="Navy"]For[/COLOR] [COLOR="Navy"]Each[/COLOR] Dn [COLOR="Navy"]In[/COLOR] T2
        [COLOR="Navy"]If[/COLOR] Not .exists(Dn.Value) [COLOR="Navy"]Then[/COLOR]
            .Add Dn.Value, Dn
        [COLOR="Navy"]Else[/COLOR]
            [COLOR="Navy"]Set[/COLOR] .Item(Dn.Value) = Union(.Item(Dn.Value), Dn)
        [COLOR="Navy"]End[/COLOR] If
    [COLOR="Navy"]Next[/COLOR]
[COLOR="Navy"]For[/COLOR] [COLOR="Navy"]Each[/COLOR] Dn [COLOR="Navy"]In[/COLOR] T1
'[COLOR="Green"][B] MsgBox T1.Address(external:=True)[/B][/COLOR]
  [COLOR="Navy"]If[/COLOR] .exists(Dn.Value) [COLOR="Navy"]Then[/COLOR]
    [COLOR="Navy"]For[/COLOR] [COLOR="Navy"]Each[/COLOR] R [COLOR="Navy"]In[/COLOR] .Item(Dn.Value)
        c = c + 1
        ReDim Preserve Ray(1 To 7, 1 To c)
        [COLOR="Navy"]For[/COLOR] ac = 1 To 7
            [COLOR="Navy"]If[/COLOR] ac <= 4 [COLOR="Navy"]Then[/COLOR]
            Ray(ac, c) = Dn(, ac)
            [COLOR="Navy"]Else[/COLOR]
            Ray(ac, c) = R.Offset(, ac - 4).Value
            [COLOR="Navy"]End[/COLOR] If
        [COLOR="Navy"]Next[/COLOR] ac
    [COLOR="Navy"]Next[/COLOR] R
  [COLOR="Navy"]End[/COLOR] If
[COLOR="Navy"]Next[/COLOR] Dn
[COLOR="Navy"]End[/COLOR] With
[COLOR="Navy"]With[/COLOR] Workbooks("MyActivesht.xlsm").Sheets("Sheet2").Range("A1").Resize(c, 7)
    .Value = Application.Transpose(Ray)
    .Borders.Weight = 2
    .Columns.AutoFit
    .HorizontalAlignment = xlCenter
[COLOR="Navy"]End[/COLOR] With
LWB.Close savechanges:=False '[COLOR="Green"][B]or false[/B][/COLOR]
MWB.Close savechanges:=False '[COLOR="Green"][B]or false[/B][/COLOR]
[COLOR="Navy"]End[/COLOR] [COLOR="Navy"]Sub[/COLOR]
Regards Mick
 
Upvote 0

Forum statistics

Threads
1,215,727
Messages
6,126,512
Members
449,316
Latest member
sravya

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