Excel data validation with suggestions/autocomplete

后端 未结 7 2219
一整个雨季
一整个雨季 2020-12-03 07:42

Apologies for my low level of Excel understanding, maybe what I am looking to do is not possible.

I have a list of 120 entries that I want to use as data validatio

7条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-03 08:00

    I adapted the answer by ChrisB. Like in his example a temporary combobox is made visible when a cell is clicked. Additionally:

    1. List of Combobox items is updated as user types, only matching items are displayed
    2. if any item from combobox is selected, filtering is skipped as it makes sense and because of this error

    Option Explicit
    
    Private Const DATA_RANGE = "A1:A16"
    Private Const DROPDOWN_RANGE = "F2:F10"
    Private Const HELP_COLUMN = "$G"
    
    
    Private Sub Worksheet_SelectionChange(ByVal target As Range)
        Dim xWs As Worksheet
        Set xWs = Application.ActiveSheet
        
        On Error Resume Next
        
        With Me.TempCombo
            .LinkedCell = vbNullString
            .Visible = False
        End With
        
        If target.Cells.count > 1 Then
            Exit Sub
        End If
        
        Dim isect As Range
        Set isect = Application.Intersect(target, Range(DROPDOWN_RANGE))
        If isect Is Nothing Then
           Exit Sub
        End If
           
        With Me.TempCombo
            .Visible = True
            .Left = target.Left - 1
            .Top = target.Top - 1
            .Width = target.Width + 5
            .Height = target.Height + 5
            .LinkedCell = target.Address
    
        End With
    
        Me.TempCombo.Activate
        Me.TempCombo.DropDown
    End Sub
    
    Private Sub TempCombo_Change()
        If Me.TempCombo.Visible = False Then
            Exit Sub
        End If
        
        Dim currentValue As String
        currentValue = Range(Me.TempCombo.LinkedCell).Value
        
        If Trim(currentValue & vbNullString) = vbNullString Then
            Me.TempCombo.ListFillRange = "=" & DATA_RANGE
        Else
            If Me.TempCombo.ListIndex = -1 Then
                 Dim listCount As Integer
                 listCount = write_matching_items(currentValue)
                 Me.TempCombo.ListFillRange = "=" & HELP_COLUMN & "1:" & HELP_COLUMN & listCount
                 Me.TempCombo.DropDown
            End If
    
        End If
    End Sub
    
    
    Private Function write_matching_items(currentValue As String) As Integer
        Dim xWs As Worksheet
        Set xWs = Application.ActiveSheet
    
        Dim cell As Range
        Dim c As Range
        Dim firstAddress As Variant
        Dim count As Integer
        count = 0
        xWs.Range(HELP_COLUMN & ":" & HELP_COLUMN).Delete
        With xWs.Range(DATA_RANGE)
            Set c = .Find(currentValue, LookIn:=xlValues)
            If Not c Is Nothing Then
                firstAddress = c.Address
                Do
                  Set cell = xWs.Range(HELP_COLUMN & "$" & (count + 1))
                  cell.Value = c.Value
                  count = count + 1
                 
                  Set c = .FindNext(c)
                  If c Is Nothing Then
                    GoTo DoneFinding
                  End If
               Loop While c.Address <> firstAddress
            End If
    DoneFinding:
        End With
        
        write_matching_items = count
    
    End Function
    
    Private Sub TempCombo_KeyDown( _
                    ByVal KeyCode As MSForms.ReturnInteger, _
                    ByVal Shift As Integer)
    
        Select Case KeyCode
            Case 9  ' Tab key
                Application.ActiveCell.Offset(0, 1).Activate
            Case 13 ' Pause key
                Application.ActiveCell.Offset(1, 0).Activate
        End Select
    End Sub

    Notes:

    1. ComboBoxe's MatchEntry must be set to 2 - fmMatchEntryNone. Don't forget to set ComboBox name to TempCombo
    2. I am using listFillRange to set ComboBox options. The range must be continuous, so, matching items are stored in a help column.
    3. I have tried accomplishing the same with ComboBox.addItem, but it turned out to be hard to repaint list box as user types

提交回复
热议问题