vLookup Generation

thumbguy

New Member
Joined
Sep 2, 2023
Messages
1
Office Version
  1. 2019
Platform
  1. Windows
Hello,

I am trying to create a macro to copy/paste a generated vLookup formula using a user selected range ("Reference Data") and with the following criteria:

- The table array starting column needs to increment by 1 until it reaches the 2nd to last column of the user selected range, but the ending column needs to remain locked
- The formula should be copied left to right while decrementing the Column_index (starting with the first column of the user selected range ending with the 2nd to last column of the user selected range). This is so that the Column_index is looking at the same column of the reference data
- This should repeat for each row in the "XYR Data" Table

To do this manually, I first write the vLookup as
Excel Formula:
=VLOOKUP(D2,I2:L6,4,FALSE)
and then lock rows and columns to get
Excel Formula:
=VLOOKUP(D$2,I$2:$L$6,4,FALSE)
This is then flash filled across however many columns are in the reference data less one.
I then go through each filled cell and decrement the Col_Index_Num by 1 until it gets down to 2.
This entire row is then flash filled down for each row of the "XYR Data" table.

I've gotten the code this far. It asks or the reference range and target cell, and generates a vlookup based off of that. But the copy paste is happening in reverse order to what I need and I havent been able to figure out how to lock certain Row/Column references in the formula.

VBA Code:
Sub GenerateVLOOKUPAndCopy()
    Dim SourceRange As Range
    Dim NewRange As Range
    Dim TargetCell As Range
    Dim FormulaString As String
    Dim ColumnIndex As Integer
    Dim LookupValueColumn As Integer
    
    ' Check if a range is selected
    On Error Resume Next
    Set SourceRange = Application.InputBox("Select the BOM range:", Type:=8)
    On Error GoTo 0
    
    If SourceRange Is Nothing Then
        MsgBox "No BOM selected. Exiting the macro."
        Exit Sub
    End If
    
    ' InputBox for the target cell where the VLOOKUP formula will be pasted
    On Error Resume Next
    Set TargetCell = Application.InputBox("Select the target cell where the VLOOKUP formula should be pasted:", Type:=8)
    On Error GoTo 0
    
    If TargetCell Is Nothing Then
        MsgBox "No target cell selected. Exiting the macro."
        Exit Sub
    End If
    
    ' Initialize column index and lookup value column
    ColumnIndex = SourceRange.columns.Count
    LookupValueColumn = 1

    
    ' Loop to generate and copy VLOOKUP formulas
    Do While ColumnIndex >= 2
        ' Generate the VLOOKUP formula
        FormulaString = "=VLOOKUP(" & TargetCell.Offset(0, -1).Address & "," & _
                        SourceRange.Address(True, False) & "," & _
                        ColumnIndex & "," & _
                        False & ")"
        
        ' Paste the formula in the target cell
        TargetCell.Offset(0, ColumnIndex - 2).Formula = FormulaString
        
        ' Decrement the column index and increment the lookup value column
        ColumnIndex = ColumnIndex - 1
        LookupValueColumn = LookupValueColumn + 1
    Loop
End Sub

This is ideally how the final table of formulas would look and how the lookup range would move with each step
Formula C1.png
Formula C2.png

Formula C3.png

And what the final Results would show
Results Values.png


The final cleanup of deleting the #N/A cells and getting the results in column E is done in a separate macro that already works.

Some final information:
The XYR is always in that format, with the first lookup value in cell D2 and the final results ultimately being in column E.
The reference data is a variable number of columns wide but the Index Column is always the very last one.

Any help would be appreciated!
 

Excel Facts

Wildcard in VLOOKUP
Use =VLOOKUP("Apple*" to find apple, Apple, or applesauce
If you're open to a different approach, this is how I would do this:
VBA Code:
Option Explicit
Option Compare Text
Sub thumbguy()
    Dim a, b, c
    Dim i As Long, j As Long, k As Long, m As Long, LCol As Long
    LCol = Cells(1, Columns.Count).End(xlToLeft).Column
    
    a = Range("D2", Cells(Rows.Count, "D").End(xlUp))
    b = Range("I2", Cells(Rows.Count, LCol).End(xlUp))
    m = LCol - 8
    ReDim c(1 To UBound(a, 1), 1 To m - 1)
    
    For i = 1 To UBound(a, 1)
        For j = 1 To UBound(b, 1)
            For k = 1 To m - 1
                If a(i, 1) = b(j, k) Then c(i, k) = b(j, m): Exit For
            Next k
        Next j
    Next i
    Range("E2").Resize(UBound(c, 1), m - 1).Value = c
End Sub

Before:
Book1
ABCDEFGHIJKL
1XYR DataResultsReference data
2221939181621DAC102
3647246905197ABCC105
425316103731BDEFR102
5525446653791HGR2R6
618762533685GHC1005
Sheet1


After:
Book1
ABCDEFGHIJKL
1XYR DataResultsReference data
2221939181621DR102AC102
3647246905197AC102BCC105
425316103731BC105DEFR102
5525446653791HC1005GR2R6
618762533685GR2R6HC1005
Sheet1
 
Last edited:
Upvote 0
The reference data is a variable number of columns wide but the Index Column is always the very last one.
That being the case, the Results table would also be extended to the right, and therefore the first column of the Results data would also shift to the right. As such, the following code would be safer:
VBA Code:
Option Explicit
Option Compare Text
Sub thumbguy_V2()
    Dim a, b, c
    Dim i As Long, j As Long, k As Long, m As Long
    Dim LCol As Long, StartRef As Long, LRow As Long
    LCol = Cells(1, Columns.Count).End(xlToLeft).Column
    LRow = Cells.Find("*", , xlFormulas, , 1, 2).Row
    
    For i = 8 To LCol
        If Application.CountA(Columns(i)) > 0 Then StartRef = i: Exit For
    Next i
    
    a = Range("D2", Cells(Rows.Count, "D").End(xlUp))
    b = Range(Cells(2, StartRef), Cells(Rows.Count, LCol).End(xlUp))
    m = LCol - (StartRef - 1)
    ReDim c(1 To UBound(a, 1), 1 To m - 1)
    
    For i = 1 To UBound(a, 1)
        For j = 1 To UBound(b, 1)
            For k = 1 To m - 1
                If a(i, 1) = b(j, k) Then c(i, k) = b(j, m): Exit For
            Next k
        Next j
    Next i
    Range("E2").Resize(UBound(c, 1), m - 1).Value = c
End Sub
 
Upvote 0
@thumbguy, welcome to the Forum!
The final cleanup of deleting the #N/A cells and getting the results in column E is done in a separate macro that already works.
If the required end result is all in Column E, then couldn't you use the simple formula?

E2: =CONCAT(IF(D2=I$2:K$6,L$2:L$6,""))
 
Upvote 0

Forum statistics

Threads
1,223,880
Messages
6,175,154
Members
452,615
Latest member
bogeys2birdies

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