Auto-Complete with only text and not numbers ComboBox Excel VBA

前端 未结 2 809
南方客
南方客 2020-12-02 01:30

Suppose I have a ComboBox in Excel VBA with the following sorts of info:

1234 apples
2345 pears
2367 oranges

I want the user to be able to

相关标签:
2条回答
  • 2020-12-02 01:43

    So first to give some context to this answer. SectorDropDown1_1 (which is part of a form) is a drop down list that is populated with the concatenated strings of a number value and a string value coming from a column J. In this context the _change() method responds to the user typing in values. I have 2 columns "R", and "S", in a spreadsheet "SectorSearch" that have separated the number and the text. So now if the user enters either the number or the text, then the appropriate value in the Drop Down list is selected. But here is the problem, my code sort of awkwardly jumps to the exact value and so I want to "smooth things out" so to speak so that after the user types more than 2 characters that match the appropriate value that this value is now selected and the drop down list shows the nearby values.

    Option Explicit
    
    Private Sub SectorDropDown1_1_Change()
    
    Dim i As Long
    Dim StringRange1 As String
    Dim StringRange2 As String
    Dim Stringrange3 As String
    Dim LengthOfValue As Integer
    Dim TotalSectorCodes As Integer
    
    If SectorDropDown1_1.Value <> "" And Len(SectorDropDown1_1.Value) > 2 Then
        TotalSectorCodes = Worksheets("SectorSearch").Range("J:J").Cells.SpecialCells(xlCellTypeFormulas).Count
        LengthOfValue = Len(SectorDropDown1_1.Value)
        For i = 2 To TotalSectorCodes
            StringRange1 = "R" & CStr(i)
            StringRange2 = "S" & CStr(i)
            Stringrange3 = "J" & CStr(i)
            Select Case SectorDropDown1_1.Value
                Case Left(Worksheets("SectorSearch").Range(StringRange1).Value, LengthOfValue)
                    SectorDropDown1_1.Value = Worksheets("SectorSearch").Range(Stringrange3).Value
                    Exit For
                Case Left(Worksheets("SectorSearch").Range(StringRange2).Value, LengthOfValue)
                    SectorDropDown1_1.Value = Worksheets("SectorSearch").Range(Stringrange3).Value
                    Exit For
                Case Else
                    '...
            End Select
        Next i
    End If
    
    End Sub
    
    0 讨论(0)
  • 2020-12-02 01:53

    Since you are using a form and form controls I'd like to throw in another solution (which I'd personally prefer). In this case I am not using a ComboBox but rather a ListBox:

    This is the code to populate the ListBox on the form and to show the form:

    Sub Button3_Click()
    
    Dim i As Long
    Dim lngLastRow As Long
    
    Load frmSearchForChoices
    With ThisWorkbook.Worksheets(1)
        lngLastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
        For i = 2 To lngLastRow
            frmSearchForChoices.lstAvailableOptions.AddItem
            frmSearchForChoices.lstAvailableOptions.List(frmSearchForChoices.lstAvailableOptions.ListCount - 1, 0) = .Cells(i, 1).Value2
            frmSearchForChoices.lstAvailableOptions.List(frmSearchForChoices.lstAvailableOptions.ListCount - 1, 1) = .Cells(i, 2).Value2
            frmSearchForChoices.lstAvailableOptions.List(frmSearchForChoices.lstAvailableOptions.ListCount - 1, 2) = .Cells(i, 3).Value2
        Next i
        frmSearchForChoices.Show
    End With
    
    End Sub
    

    The following code resides on the form itself:

    Option Explicit
    Option Compare Text
    
    Private Sub btnCancel_Click()
    
    frmSearchForChoices.Hide
    Unload frmSearchForChoices
    
    End Sub
    
    Private Sub btnOK_Click()
    
    Dim lngMatch As Long
    
    If frmSearchForChoices.lstAvailableOptions.ListCount > 0 Then
        If frmSearchForChoices.lstAvailableOptions.ListIndex >= 0 Then
            For lngMatch = 0 To frmSearchForChoices.lstAvailableOptions.ListCount - 1
                If frmSearchForChoices.lstAvailableOptions.Selected(lngMatch) = True Then
                    MsgBox "You selected" & Chr(10) & _
                        frmSearchForChoices.lstAvailableOptions.List(lngMatch, 1) & " (" & _
                        frmSearchForChoices.lstAvailableOptions.List(lngMatch, 0) & ")" & _
                        IIf(Len(frmSearchForChoices.lstAvailableOptions.List(lngMatch, 2)) > 0, _
                            " from " & frmSearchForChoices.lstAvailableOptions.List(lngMatch, 2), "")
                    frmSearchForChoices.Hide
                    Unload frmSearchForChoices
                End If
            Next lngMatch
        End If
    End If
    
    End Sub
    
    Private Sub txtSearchTerm_Change()
    
    Dim i As Long
    Dim lngMatch As Long
    Dim varArray As Variant
    
    If Len(Trim(frmSearchForChoices.txtSearchTerm.Value)) = 0 Then Exit Sub
    
    For lngMatch = 0 To frmSearchForChoices.lstAvailableOptions.ListCount - 1
        frmSearchForChoices.lstAvailableOptions.Selected(lngMatch) = False
        frmSearchForChoices.lstAvailableOptions.List(lngMatch, 3) = 0
    Next lngMatch
    
    
    varArray = Split(Trim(frmSearchForChoices.txtSearchTerm.Value), " ")
    For i = LBound(varArray) To UBound(varArray)
        For lngMatch = 0 To frmSearchForChoices.lstAvailableOptions.ListCount - 1
            If InStr(1, frmSearchForChoices.lstAvailableOptions.List(lngMatch, 1), varArray(i)) Or _
                InStr(1, frmSearchForChoices.lstAvailableOptions.List(lngMatch, 2), varArray(i)) Then
                    frmSearchForChoices.lstAvailableOptions.List(lngMatch, 3) = Val(frmSearchForChoices.lstAvailableOptions.List(lngMatch, 3)) + 1
            End If
        Next lngMatch
    Next i
    
    For lngMatch = 0 To frmSearchForChoices.lstAvailableOptions.ListCount - 1
        If frmSearchForChoices.chkMatchBoth.Value Then
            If Val(frmSearchForChoices.lstAvailableOptions.List(lngMatch, 3)) >= UBound(varArray) - LBound(varArray) + 1 Then
                frmSearchForChoices.lstAvailableOptions.Selected(lngMatch) = True
            End If
        Else
            If Val(frmSearchForChoices.lstAvailableOptions.List(lngMatch, 3)) >= 1 Then
                frmSearchForChoices.lstAvailableOptions.Selected(lngMatch) = True
            End If
        End If
    Next lngMatch
    
    End Sub
    

    I sure hope that most variables and controls can be identified within the code due to the followed naming convention (starting with frm for forms, lbl for labels on forms, ´lst` for ListBox on form, etc). Yet, do not hesitate to let me know if you have any questions regarding this solution.

    0 讨论(0)
提交回复
热议问题