Something I never got about the Design of VLookup

Oorang

Well-known Member
Joined
Mar 4, 2005
Messages
2,071
Why does vlookup use the Column parameter? It's so unnecessary. It can only retrieve from one column. So so why would you ever define a table as wider then that lookup column? It should just automatically pull from the rightmost column of the defined lookup table. Every time I count the columns in a table I think to myself what a waste of time! Is there some utility that I'm missing where it might be helpful to define a table 6 columns wide, lookup from the 1st column, pull from the 3rd column, and just have the other 3 there for moral support?

:banghead:
 
Last edited:

Excel Facts

Move date out one month or year
Use =EDATE(A2,1) for one month later. Use EDATE(A2,12) for one year later.
I agree with you very much on that. I feel that they missed the ball by not having an option to look to the left with the formula rather than having to use index/match. Have the furthest column right be what you are looking up and enter a negative column. If the number is negative it uses the column K as lookup and if it is positive it uses D as lookup:

=vlookup(A1,B:E,4,0) would match A1 in column B and return the value in E

OR

=vlookup(A1,B:E,-4,0) would match A1 in column E and return the value in B

That gave me an idea for a little UDF.

But it does make it nice when copying the formula across a range and have the column number increment.

=vlookup($A1,Sheet2!$A:E,column(E:E),0)

Then drag the formula over to column D and have:

=vlookup($A1,Sheet2!$A:I,column(I:I),0)

But the column would still be irrelevant if you always had your lookup reference the correct last column.
 
The real question is why do people insist on feeding VLookUp() a Range that's bigger than the vector they eventually want to pull from? Let's fire as big of an array into memory as possible, necessary or not?

Index(Match()). ;)
 
Perhaps I am not understanding what you are asking, but I find the Vlookup to be fine.
I have a spreadsheet with 20 columns of data each row being an inventory item from size, to quantity, to pricing. On another sheet I can write one formula referencing the table copy it everywhere and just modify which column to return. Which is not always the rightmost column.
 
Very interesting discussion. AS schielrn pointed out, you can start with a 2 column lookup array, and as dragged right it expands as needed.

=vlookup(a1,$E:F,Column(B1),False)

as dragged right, the array and column ref adjust accordingly.

However, I can see the need for it if you use Named Ranges. You can't expand the columns of the array when dragged right using a named range..So it would be necessary to use the entire range, and specify column ref.

But I think at the very least it could be made an OPTIONAL argument. If omitted, it uses the far right column. At least that's what I did in my VlookupNth UDF.


All arguments aside, Index/match is probably the better solution than vlookup anyway...
 
Last edited:
I'm in agreement somewhat...something more along the lines of the vba .offset() method would be more efficient. Just define the lookup data, and tell it to offset from where it finds the match...and as was stated above, let negative values be used. This would limit the array size and still let you lookup multiple column values. I've had cases where I'm looking up more than one column from the same vlookup table, and I don't want to have to define multiple tables to get the data.
 
Perhaps I am not understanding what you are asking, but I find the Vlookup to be fine.
It does work fine. The point I am making is that the because the lookup column is always the leftmost column of the lookup table. And you can only return the value from one column, the lookup table you specify (barring sloppiness) is never going to be wider then lookup column to return column. So it should be a give that the return column number is the number of the rightmost column. There is no need for that parameter. Instead of =VLOOKUP(A1,B2:C24,2,0) It should just be =VLOOKUP(A1,B2:C24,0) and it's a given the return column is C.
 
Because it's me I couldn't resist making my own :rolleyes: It could be optimized for speed, but this is something that functions the way I was thinking. But to be honest I tend to steer clear of UDFs because people either won't have the add-in you make, or have macro's enabled etc.

Code:
'-------------------------------------------------------------------------------
' Module       : UserDefinedFunctions
' Author       : Aaron Bush
' Date         : 05/30/2008
' Purpose      : Contains Functions intended to be available to user in
'                Microsoft Excel.
' References   : Visual Basic For Applications
'                C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\
'                VBE6.DLL
'                Microsoft Excel 11.0 Object Library
'                C:\Program Files\Microsoft Office\OFFICE11\EXCEL.EXE
' Dependancies : None
'-------------------------------------------------------------------------------
Option Explicit
Option Compare Binary
Option Base 0
'Option Public Module

'Setting this to True will turn off all error handling:
#Const m_blnErrorHandlersOff_c = False


Public Function SVLOOKUP(ByVal value As String, ByVal lookupTable As _
    Excel.Range, Optional ByVal matchCase As Boolean = False) As Variant

    '---------------------------------------------------------------------------
    ' Procedure : SLOOKUP
    ' Author    : Aaron Bush
    ' Date      : 05/30/2008
    ' Purpose   : Simple Lookup. Provides a simpler VLOOKUP syntax by assuming
    '             the return column is the left column in the range and an
    '             replaces the esoteric Range Lookup paramter with an
    '             optional Case-Sensitivity paramter.
    ' Input(s)  : value       - The value to be looked up.
    '             lookupTable - The table that contains the data you want a
    '                           lookup performed on.
    '             matchCase   - Optional. Determines case-sensitivity. Default
    '                           is false.
    ' Output(s) : If value is encountered in the left-most column of the lookup
    '             table, the return value will be the value of the same row,
    '             but the rightmost column of the lookup table. The first value
    '             encountered is used.
    ' Remarks   : Variant return type used to accomdate excel numbers and
    '             strings.
    ' Revisions :
    '---------------------------------------------------------------------------

    Const strNotFnd_c As String = "#NotFound!"
    Const lngLkupClmn_c As Long = 1
    Dim wsParnt As Excel.Worksheet
    Dim rngLkup As Excel.Range
    Dim cll As Excel.Range
    Dim varRtnVal As Variant

    'Conditionally Invoke Error Handler:
#If Not m_blnErrorHandlersOff_c Then
    On Error GoTo Err_Hnd
#End If
    Set wsParnt = lookupTable.Parent
    Set rngLkup = Excel.Intersect(lookupTable.Columns(lngLkupClmn_c), _
        wsParnt.UsedRange)
    If matchCase Then
        For Each cll In rngLkup.Cells
            If cll.value = value Then
                varRtnVal = wsParnt.Cells(cll.Row, lookupTable.Column + _
                    lookupTable.Columns.Count - lngLkupClmn_c).value
                Exit For
            End If
        Next
    Else
        value = LCase$(value)
        For Each cll In rngLkup.Cells
            If LCase$(cll.value) = value Then
                varRtnVal = wsParnt.Cells(cll.Row, lookupTable.Column + _
                    lookupTable.Columns.Count - lngLkupClmn_c).value
                Exit For
            End If
        Next
    End If
    If cll Is Nothing Then
        varRtnVal = strNotFnd_c
    End If
    '******* Exit Procedure *******
Exit_Proc:
    'Supress Error Handling to Prevent Error-Loops:
    On Error Resume Next
    'Release Objects:
    Set wsParnt = Nothing
    Set rngLkup = Nothing
    'Set Return Value:
    SVLOOKUP = varRtnVal
    Exit Function
    '******* Error Handler *******
Err_Hnd:
    varRtnVal = Err.Description
    Resume Exit_Proc
End Function
 
Yes, VLookup is expensive, but only if you let yourself be conned.

Wide tables definitely make VLookup expensive -- so do very tall ones. A few years ago I built a spreadsheet that used nested VLookups on two large tables. The workbook was unusable -- about 10 minutes to refresh after each edit. Restricting the VLookups so they only looked above the current row (the data was chronological) made a huge difference, along the lines of the Column() comment above.
If I'd though harder about it, Index / Match would have been much better.

Denis
 
It does work fine. The point I am making is that the because the lookup column is always the leftmost column of the lookup table. And you can only return the value from one column, the lookup table you specify (barring sloppiness) is never going to be wider then lookup column to return column. So it should be a give that the return column number is the number of the rightmost column. There is no need for that parameter. Instead of =VLOOKUP(A1,B2:C24,2,0) It should just be =VLOOKUP(A1,B2:C24,0) and it's a given the return column is C.

While I agree that vlookup is zoolander flawed in that it can't look to the left (and here is a udf I wrote sometime ago to address it:

http://www.mrexcel.com/forum/showthread.php?t=154622&highlight=vlookup )

Surely, if the table is more than two columns wide then the column number is needed? Or did I miss something?
 

Forum statistics

Threads
1,222,674
Messages
6,167,531
Members
452,118
Latest member
djjamesp

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