15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту




Быстрый поиск в массивах, листбоксах и комбобоксах

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