Частичное совпадение строк (Как сопоставить любую часть строки, когда я набираю в поле со списком?) - PullRequest
1 голос
/ 14 марта 2020

Что у меня есть:

[Форма: «Intajform»] - [Combobox: «CustomerName_Combobox»] - [Инициализировать событие: Список загрузки]

Private Sub UserForm_Initialize()

   Dim ws As Worksheet, rCell, srr As Range, Key
   Dim Dic As Object: Set Dic = CreateObject("Scripting.Dictionary")

   Set ws = ThisWorkbook.Worksheets("Backend")
   Set srr = ws.Range("b2", ws.Cells(Rows.Count, "b").End(xlUp))

   For Each rCell In srr
      If Not Dic.exists(rCell.Value) Then
         Dic.Add (rCell.Value), Nothing
      End If
   Next rCell

   For Each Key In Dic
      IntajForm.CustomerName_Combobox.AddItem Key
   Next

End Sub

При наборе в этом поле со списком чтобы найти совпадение

Я МОГУ ПОЛНОСТЬЮ СОГЛАСОВАТЬ СТРОКИ ТОЛЬКО ПЕРВЫМ БУКВОМ EX: Если я наберу "M", то найду "Microsoft Corporation"

НО Я НЕ МОГУ ЧАСТИЧНО СРАВНИТЬ СТРОКИ EX: Если Я набираю "r", тогда оно пустое ""

Target

Я хочу частично сопоставить строку, найденную в Combobox, до тех пор, пока буква, которую я набираю, находится в строка.

1 Ответ

0 голосов
/ 14 марта 2020

Используйте событие _Change() в выпадающем списке

У вас есть только ограниченные возможности для определения свойства .MatchEntry в выпадающем списке - ср. Справка MS - свойство MatchEntry :

  • .MatchEntry = fmMatchEntryFirstLetter '
  • .MatchEntry = fmMatchEntryComplete'
  • .MatchEntry = fmMatchEntryNone 'без автоматики c предварительный выбор вообще

Чтобы получить суженный список выбора, следующий за набранными в настоящее время частичными строками, необходимо использовать событие _Change() comboboxe и переместить объявление словаря в заголовок модуля, чтобы сделать его доступным как для init, так и для комбо-изменений.

Идея состоит в том, чтобы представить индивидуализированный выбор после любого входа в комбинированный список [1] ​​и вызвать раскрывающийся список для лучшего обзора [2]:

Option Explicit                               ' declaration head of code module
Dim Dic As Object                             ' make dictionary available at module level

Private Sub CustomerName_Combobox_Change()
    With Me.CustomerName_Combobox
        '[1] narrow data to choose
        .List = Filter(Dic.Keys, .Text, True, vbTextCompare)   ' <~ corrected/2020-03-15
        '[2] expand filter selection (reduced number of valid elements)
        .DropDown
    End With
End Sub

Private Sub UserForm_Initialize()
Dim ws As Worksheet, rCell As Range, srr As Range, Key
Set Dic = CreateObject("Scripting.Dictionary")
Set ws = ThisWorkbook.Worksheets("Backend")
Set srr = ws.Range("b2", ws.Cells(Rows.Count, "b").End(xlUp))

For Each rCell In srr
    If Not Dic.exists(rCell.Value) Then
        Dic.Add (rCell.Value), Nothing
    End If
Next rCell
Me.CustomerName_Combobox.List = Dic.Keys    ' <<  prefix the Me particle to indicate the current instance, not the Userform name itself :-)

End Sub

Дополнительная подсказка: можно назначить все ключи словаря для свойства combobox .List сразу, вместо зацикливания (см. _Initialize()). И избегайте таких конструкций, как IntajForm.CustomerName_Combobox.AddItem Key, просто укажите имя элемента управления или добавьте к нему префикс Me, чтобы указать текущий экземпляр пользовательской формы (класса), предоставляющий вам публикуемые c члены этого объекта.

К вашему сведению - для дальнейшего понимания спецификатора Me и самой пользовательской формы вам может пригодиться чтение

...