Быстрый поиск в массивах, листбоксах и
комбобоксах
Данный метод удобен, если пользователь вводит
данные, по которым потом будет осуществлять
поиск. Поисковый запрос в базу данный обычно
занимает доволно длительное время. Для
уменьшения этого времени, можно хранить
поисковую таблицу локально в отсортированном
массиве, лист-боксе или комбо-боксе, у которых
свойство Sorted установлено в True. Для больших
отсортированных массивов строк, листбоксов или
комбо-боксов с большим количеством строк (около
10,000), бинарный поиск в 10-20 раз быстрее, чем вызов API
функций и в сотни раз быстрее, чем
последовательный поиск. Различии скорости
поиска увеличивается в несколько раз, если поиск
надо сделать несколько раз. Итак, следующий код
можно использовать для массива:
'Вход:
'Массив для поиска
Dim rasArray() As String
'Строка для поиска
Dim vsName As String
'Выход:
'Индекс в массиве строки, если найдено
Dim rlIndex As Long
'Локальные переменные:
'Индекс в массиве
Dim lnIdx As Long
'Нижний предел интервала поиска
Dim lnMin As Long
'Верхний предел интервала поиска
Dim lnMax As Long
'Если строка не найдена, то в индексе возвращаем ошибку
rlIndex = LBound(rasArray) - 1
lnMax = UBound(rasArray)
lnMin = LBound(rasArray)
'ищем vsName в rasArray()
Do While lnMin <= lnMax
lnIdx = (lnMax + lnMin) \ 2
If vsName = rasArray(lnIdx) Then
rlIndex = lnIdx
Exit Do
ElseIf vsName < rasArray(lnIdx) Then
lnMax = lnIdx - 1
Else
lnMin = lnIdx + 1
End If
Loop
Так же этот код можно легко переделать как для
combo-box, так и для list-box:
'Вход:
'Combo для поиска
' (change into As ListBox for listbox controls
' or use As Controls to use with both types
' of controls)
Dim rcboCombo As ComboBox
'Строка для поиска
Dim vsName As String
'Выход:
'Если строка найдена, то это индекс в combo
Dim rlIndex As Long
'Локальные переменные
'Индекс в массиве
Dim lnIdx As Long
'Нижний предел интервала поиска
Dim lnMin As Long
'Верхний предел интервала поиска
Dim lnMax As Long
'Если строка не найдена, то в индексе возвращаем ошибку
rlIndex = -1
lnMin = 0
lnMax = rcboCombo.ListCount - 1
lnIdx = lnMax \ 2
'ищем имя в combo
Do While rlIndex = -1 And lnMin <= lnMax
If vsName = rcboCombo.List(lnIdx) Then
rlIndex = lnIdx
ElseIf vsName < rcboCombo.List(lnIdx) Then
lnMax = lnIdx - 1
lnIdx = (lnMax + lnMin) \ 2
Else
lnMin = lnIdx + 1
lnIdx = (lnMax + lnMin) \ 2
End If
Loop
|