23

I'm using a large validation list on which a couple of vlookup() functions depend. This list is getting larger and larger. Is there a way to type the first letters of the list item I'm looking for, instead of manually scrolling down the list searching for the item?

I've done some Googling but this suggests that this is indeed possible in earlier versions of Excel, but not in Excel 2010. Hope you guys can help.

ashleedawg
  • 20,365
  • 9
  • 72
  • 105
Pieter
  • 647
  • 4
  • 9
  • 16
  • Do checkout [this](https://stackoverflow.com/a/22296329/465053) wiki which is the closest possible solution in true sense. A concept called **Don't Break The Chain** or data-link in excel. – RBT Feb 25 '18 at 08:38

6 Answers6

14

Here is a very good way to handle this (found on ozgrid):

Let's say your list is on Sheet2 and you wish to use the Validation List with AutoComplete on Sheet1.

On Sheet1 A1 Enter =Sheet2!A1 and copy down including as many spare rows as needed (say 300 rows total). Hide these rows and use this formula in the Refers to: for a dynamic named range called MyList:

=OFFSET(Sheet1!$A$1,0,0,MATCH("*",Sheet1!$A$1:$A$300,-1),1)

Now in the cell immediately below the last hidden row use Data Validation and for the List Source use =MyList

[EDIT] Adapted version for Excel 2007+ (couldn't test on 2010 though but AFAIK, there is nothing really specific to a version).
Let's say your data source is on Sheet2!A1:A300 and let's assume your validation list (aka autocomplete) is on cell Sheet1!A1.

  1. Create a dynamic named range MyList that will depend on the value of the cell where you put the validation

    =OFFSET(Sheet2!$A$1,MATCH(Sheet1!$A$1&"*",Sheet2!$A$1:$A$300,0)-1,0,COUNTA(Sheet2!$A:$A))

  2. Add the validation list on cell Sheet1!A1 that will refert to the list =MyList

Caveats

  1. This is not a real autocomplete as you have to type first and then click on the validation arrow : the list will then begin at the first matching element of your list

  2. The list will go till the end of your data. If you want to be more precise (keep in the list only the matching elements), you can change the COUNTA with a SUMLPRODUCT that will calculate the number of matching elements

  3. Your source list must be sorted

RBT
  • 24,161
  • 21
  • 159
  • 240
JMax
  • 26,109
  • 12
  • 69
  • 88
  • Thank you for your reply. Are you sure this works for Excel 2010? The article says to 'enable auto complete' which to my knowledge is not an option in 2010. Furthermore, what do you mean by 'use this formula in the Refers to:'? In which cell would I start typing the first letters of the items I'm looking for? – Pieter Nov 04 '11 at 04:05
  • This is very nice... but, cmiiw, only works for a single cell validation because the list source is using match function to a predefined single cell on sheet1. Is there any workaround how to make this works for multiple rows? – Kamal Jan 04 '15 at 04:30
  • The dynamic range formula for Excel 2007+ worked like a real auto complete for me. I was working on a list of companies so the moment I type `Microsof` in the cell targeting `MyList`, excel autocompleted it like Microsof`t Corporation` by showing remaining text `t orporation` in grey background on its own. – RBT Feb 25 '18 at 05:19
  • You don't have to necessarily keep the master list data above the target cell where you are going to show the list with auto-complete feature. This messes up the row numbers shown in extreme left and looks very odd for the end user. Instead, you can keep the master list even way below at the bottom of your worksheet to avoid messing up the row numbers (when you hide them). **An amazing concept** of `don't break the chain` [here](https://stackoverflow.com/a/22296329/465053). – RBT Feb 25 '18 at 08:33
2

Building on the answer of JMax, use this formula for the dynamic named range to make the solution work for multiple rows:

=OFFSET(Sheet2!$A$1,MATCH(INDIRECT("Sheet1!"&ADDRESS(ROW(),COLUMN(),4))&"*",Sheet2!$A$1:$A$300,0)-1,0,COUNTA(Sheet2!$A:$A))
RBT
  • 24,161
  • 21
  • 159
  • 240
2

Here's another option. It works by putting an ActiveX ComboBox on top of the cell with validation enabled, and then providing autocomplete in the ComboBox instead.

Option Explicit

' Autocomplete - replacing validation lists with ActiveX ComboBox
'
' Usage:
'   1. Copy this code into a module named m_autocomplete
'   2. Go to Tools / References and make sure "Microsoft Forms 2.0 Object Library" is checked
'   3. Copy and paste the following code to the worksheet where you want autocomplete
'      ------------------------------------------------------------------------------------------------------
'      - autocomplete
'      Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'          m_autocomplete.SelectionChangeHandler Target
'      End Sub
'      Private Sub AutoComplete_Combo_KeyDown(ByVal KeyCode As msforms.ReturnInteger, ByVal Shift As Integer)
'          m_autocomplete.KeyDownHandler KeyCode, Shift
'      End Sub
'      Private Sub AutoComplete_Combo_Click()
'          m_autocomplete.AutoComplete_Combo_Click
'      End Sub
'      ------------------------------------------------------------------------------------------------------

' When the combobox is clicked, it should dropdown (expand)
Public Sub AutoComplete_Combo_Click()
    Dim ws As Worksheet: Set ws = ActiveSheet
    Dim cbo As OLEObject: Set cbo = GetComboBoxObject(ws)
    Dim cb As ComboBox: Set cb = cbo.Object
    If cbo.Visible Then cb.DropDown
End Sub

' Make it easier to navigate between cells
Public Sub KeyDownHandler(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    Const UP As Integer = -1
    Const DOWN As Integer = 1

    Const K_TAB_______ As Integer = 9
    Const K_ENTER_____ As Integer = 13
    Const K_ARROW_UP__ As Integer = 38
    Const K_ARROW_DOWN As Integer = 40

    Dim direction As Integer: direction = 0

    If Shift = 0 And KeyCode = K_TAB_______ Then direction = DOWN
    If Shift = 0 And KeyCode = K_ENTER_____ Then direction = DOWN
    If Shift = 1 And KeyCode = K_TAB_______ Then direction = UP
    If Shift = 1 And KeyCode = K_ENTER_____ Then direction = UP
    If Shift = 1 And KeyCode = K_ARROW_UP__ Then direction = UP
    If Shift = 1 And KeyCode = K_ARROW_DOWN Then direction = DOWN

    If direction <> 0 Then ActiveCell.Offset(direction, 0).Activate

    AutoComplete_Combo_Click
End Sub

Public Sub SelectionChangeHandler(ByVal Target As Range)
    On Error GoTo errHandler

    Dim ws As Worksheet: Set ws = ActiveSheet
    Dim cbo As OLEObject: Set cbo = GetComboBoxObject(ws)
    Dim cb As ComboBox: Set cb = cbo.Object

    ' Try to hide the ComboBox. This might be buggy...
    If cbo.Visible Then
        cbo.Left = 10
        cbo.Top = 10
        cbo.ListFillRange = ""
        cbo.LinkedCell = ""
        cbo.Visible = False
        Application.ScreenUpdating = True
        ActiveSheet.Calculate
        ActiveWindow.SmallScroll
        Application.WindowState = Application.WindowState
        DoEvents
    End If

    If Not HasValidationList(Target) Then GoTo ex

    Application.EnableEvents = False

    ' TODO: the code below is a little fragile
    Dim lfr As String
    lfr = Mid(Target.Validation.Formula1, 2)
    lfr = Replace(lfr, "INDIREKTE", "") ' norwegian
    lfr = Replace(lfr, "INDIRECT", "") ' english
    lfr = Replace(lfr, """", "")
    lfr = Application.Range(lfr).Address(External:=True)

    cbo.ListFillRange = lfr
    cbo.Visible = True
    cbo.Left = Target.Left
    cbo.Top = Target.Top
    cbo.Height = Target.Height + 5
    cbo.Width = Target.Width + 15
    cbo.LinkedCell = Target.Address(External:=True)
    cbo.Activate
    cb.SelStart = 0
    cb.SelLength = cb.TextLength
    cb.DropDown

    GoTo ex

errHandler:
    Debug.Print "Error"
    Debug.Print Err.Number
    Debug.Print Err.Description
ex:
    Application.EnableEvents = True
End Sub

' Does the cell have a validation list?
Function HasValidationList(Cell As Range) As Boolean
    HasValidationList = False
    On Error GoTo ex
    If Cell.Validation.Type = xlValidateList Then HasValidationList = True
ex:
End Function

' Retrieve or create the ComboBox
Function GetComboBoxObject(ws As Worksheet) As OLEObject
    Dim cbo As OLEObject
    On Error Resume Next
    Set cbo = ws.OLEObjects("AutoComplete_Combo")
    On Error GoTo 0
    If cbo Is Nothing Then
        'Dim EnableSelection As Integer: EnableSelection = ws.EnableSelection
        Dim ProtectContents As Boolean: ProtectContents = ws.ProtectContents

        Debug.Print "Lager AutoComplete_Combo"
        If ProtectContents Then ws.Unprotect
        Set cbo = ws.OLEObjects.Add(ClassType:="Forms.ComboBox.1", Link:=False, DisplayAsIcon:=False, _
                            Left:=50, Top:=18.75, Width:=129, Height:=18.75)
        cbo.name = "AutoComplete_Combo"
        cbo.Object.MatchRequired = True
        cbo.Object.ListRows = 12
        If ProtectContents Then ws.Protect
    End If
    Set GetComboBoxObject = cbo
End Function
tomashm
  • 59
  • 2
0
=OFFSET(NameList!$A$2:$A$200,MATCH(INDIRECT("FillData!"&ADDRESS(ROW(),COLUMN(),4))&"*",NameList!$A$2:$A$200,0)-1,0,COUNTIF($A$2:$A$200,INDIRECT("FillData!"&ADDRESS(ROW(),COLUMN(),4))&"*"),1)
  1. Create sheet name as Namelist. In column A fill list of data.

  2. Create another sheet name as FillData for making data validation list as you want.

  3. Type first alphabet and select, drop down menu will appear depend on you type.

RBT
  • 24,161
  • 21
  • 159
  • 240
0

As other people suggested, you need to use a combobox. However, most tutorials show you how to set up just one combobox and the process is quite tedious.

As I faced this problem before when entering a large amount of data from a list, I can suggest you use this autocomplete add-in . It helps you create the combobox on any cells you select and you can define a list to appear in the dropdown.

0

Excel automatically does this whenever you have a vertical column of items. If you select the blank cell below (or above) the column and start typing, it does autocomplete based on everything in the column.

Joel Spolsky
  • 33,372
  • 17
  • 89
  • 105