Разработчикам VBA проектов. Очень часто пользователи сталкиваются с необходимостью обработки и анализа обширных выборок из массивов данных на десятки тысяч записей. При выполнении таких задач использование стандартных приемов не достаточно для обеспечения требуемого быстродействия. Выкладываю на Ваше внимание оптимизированный цикл поиска записей в индексированных отсортированных массивах Данных с повторными записями. Например: Необходимо выполнить выборку списка индексированных данных с числом элементов 400 -500 записей из индексированного массива данных с числом элементов 4000 -10000.
Задача выполнить поиск с минимальным количеством проходов. Предлагаю Вашему вниманию следующий алгоритм: 1. Формируем отсортированные по индексу (числовому идентификатору) массивы выборки и базы данных. 2. Создаем функции поиска – существования записи и поиска позиций: Функция существования записи в массиве arr:
Public Function NextItemInArray(arr(), Index, Col, j) As Boolean Dim i As Long NextItemInArray = False For i = j To UBound(arr, 1) If CDbl(arr(i, Col)) > Index Then NextItemInArray = False: Exit Function '******** If arr(i, Col) = Index Then NextItemIntArray = True: Exit Function End If Next i End Function
Обратите внимание на запись ********, если Искомый Индекс меньше наименьшего значения в массиве, то цикл поиска отменяется и так понятно, что в массиве его нет.
Функция поиска позиции записи в массиве:
Public Function NextPosItemArray(arr(), Index, Col, j) As Integer Dim i As Long For i = j To UBound(arr, 1) If arr(i, Col)= Index Then NextPosItemArray = i: Exit Function End If Next i End Function
3. Цикл поиска значений списка ListArr в массиве Arr:
S=1 ReDim TArr(UBound(ListArr), 1) For i = 1 To UBound(ListArr) ‘цикл перебора выборки For j = S To UBound(arr) 'цикл поиска значений в массиве If ListArr(i, 1) < CDbl(arr(j, 2)) Then GoTo Pass ' отсекаем минимальные индексы If NextItemInVertArray(arr, ListArr(i, 1), 2, j) Then S = NextPosItemArray(arr, ListArr(i, 1), 2, j) 'цикл следующего поиска начинаем с позиции ранее найденного значения TArr(i, 1) = TArr(i, 1) + arr(S, 3) ' сборка целевого массива Flag = True ' флаг повторного поиска j = S ' сокращение выборки для следующей позиции Else ' если повторный поиск не удался исключаем дальнейший поиск во всем массиве If Flag Then Flag = False: GoTo Pass End If Next j Pass: Next i
Данный алгоритм отрезает избыточные проходы цикла минимальных значений и избыточные проходы после завершения повторного поиска последнего значения.
Всем удачи...
Разработчикам VBA проектов. Очень часто пользователи сталкиваются с необходимостью обработки и анализа обширных выборок из массивов данных на десятки тысяч записей. При выполнении таких задач использование стандартных приемов не достаточно для обеспечения требуемого быстродействия. Выкладываю на Ваше внимание оптимизированный цикл поиска записей в индексированных отсортированных массивах Данных с повторными записями. Например: Необходимо выполнить выборку списка индексированных данных с числом элементов 400 -500 записей из индексированного массива данных с числом элементов 4000 -10000.
Задача выполнить поиск с минимальным количеством проходов. Предлагаю Вашему вниманию следующий алгоритм: 1. Формируем отсортированные по индексу (числовому идентификатору) массивы выборки и базы данных. 2. Создаем функции поиска – существования записи и поиска позиций: Функция существования записи в массиве arr:
Public Function NextItemInArray(arr(), Index, Col, j) As Boolean Dim i As Long NextItemInArray = False For i = j To UBound(arr, 1) If CDbl(arr(i, Col)) > Index Then NextItemInArray = False: Exit Function '******** If arr(i, Col) = Index Then NextItemIntArray = True: Exit Function End If Next i End Function
Обратите внимание на запись ********, если Искомый Индекс меньше наименьшего значения в массиве, то цикл поиска отменяется и так понятно, что в массиве его нет.
Функция поиска позиции записи в массиве:
Public Function NextPosItemArray(arr(), Index, Col, j) As Integer Dim i As Long For i = j To UBound(arr, 1) If arr(i, Col)= Index Then NextPosItemArray = i: Exit Function End If Next i End Function
3. Цикл поиска значений списка ListArr в массиве Arr:
S=1 ReDim TArr(UBound(ListArr), 1) For i = 1 To UBound(ListArr) ‘цикл перебора выборки For j = S To UBound(arr) 'цикл поиска значений в массиве If ListArr(i, 1) < CDbl(arr(j, 2)) Then GoTo Pass ' отсекаем минимальные индексы If NextItemInVertArray(arr, ListArr(i, 1), 2, j) Then S = NextPosItemArray(arr, ListArr(i, 1), 2, j) 'цикл следующего поиска начинаем с позиции ранее найденного значения TArr(i, 1) = TArr(i, 1) + arr(S, 3) ' сборка целевого массива Flag = True ' флаг повторного поиска j = S ' сокращение выборки для следующей позиции Else ' если повторный поиск не удался исключаем дальнейший поиск во всем массиве If Flag Then Flag = False: GoTo Pass End If Next j Pass: Next i
Данный алгоритм отрезает избыточные проходы цикла минимальных значений и избыточные проходы после завершения повторного поиска последнего значения.