Быстрый поиск в массивах, листбоксах и комбобоксахДанный метод удобен, если пользователь вводит данные, по которым потом будет осуществлять поиск. Поисковый запрос в базу данный обычно занимает доволно длительное время. Для уменьшения этого времени, можно хранить поисковую таблицу локально в отсортированном массиве, лист-боксе или комбо-боксе, у которых свойство 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
|