| Код |
|---|
Function ArrAutofilterNew(ByRef arr, ParamArray args() As Variant) As Variant ' Новая версия функции ArrAutofilter, от января 2021 года. © ExcelVBA.ru ' Получает по ссылке массив ARR для фильтрации ' и список критериев фильтрации в формате "3=маска текста" (номер столбца, "=", искомое значение) ' Возвращает двумерный массив с подходящими строками On Error Resume Next ArrAutofilterNew = False ' возвращаемое значение в случае ошибки If UBound(args) = -1 Then Debug.Print "Array filtering error: filters required": Exit Function ReDim Filters(1 To UBound(args) + 1, 1 To 2) Dim i&, ColumnToCheck&, FiltersCount&, j&, ro&, RowsCount&: Err.Clear: i& = UBound(arr, 2) If Err.Number > 0 Then Debug.Print "Array filtering error: two dimensional array required": Exit Function For i& = LBound(args) To UBound(args) ' перебираем все параметры фильтрации If Not IsMissing(args(i&)) Then If args(i&) Like "#*=*" Then ' распознаем параметры фильтрации FiltersCount& = FiltersCount& + 1 Filters(FiltersCount&, 1) = Val(Split(args(i&), "=")(0)) ' столбец массива Filters(FiltersCount&, 2) = Split(args(i&), "=", 2)(1) ' маска для значения Else ' неверно заданный фильтр Debug.Print "ArrAutofilterNew error: invalid filter «" & args(i&) & "»" End If End If Next i& If FiltersCount& = 0 Then Debug.Print "Array filtering error: all filters are empty": Exit Function ReDim arrCheck(LBound(arr, 1) To UBound(arr, 1)) As Boolean ' для результатов проверки For i = LBound(arr, 1) To UBound(arr, 1) ' перебираем все строки массива, и проверяем их arrCheck(i) = True For j& = 1 To FiltersCount& ' перебираем все параметры фильтрации If Not (arr(i, Filters(j&, 1)) Like Filters(j&, 2)) Then arrCheck(i) = False: Exit For Next j& RowsCount& = RowsCount& - arrCheck(i) ' увеличиваем счётчик подходящих строк на 1 Next i If RowsCount& = 0 Then Exit Function ' выход, если нет ни одной подходящей строки в массиве ReDim newarr(1 To RowsCount&, LBound(arr, 2) To UBound(arr, 2)) ' формируем новый массив For i = LBound(arr, 1) To UBound(arr, 1) ' снова перебираем все строки массива If arrCheck(i) Then ' если строка ранее помечена как подходящая ro& = ro& + 1 ' вычисляем номер строки в новом массиве For j = LBound(arr, 2) To UBound(arr, 2) newarr(ro&, j) = arr(i, j) ' заполняем массив значениями из исходного Next j End If Next i ArrAutofilterNew = newarr ' возвращаем результат Erase arrCheck End Function |
Привел весь код, а не ссылку, т.к. вопрос именно по нему. Функция замечательная, работает верно, но можно ли из нее, не затрагивая ничего, извлечь еще один параметр? Поясню: по ходу выполнения кода, при проверке массива на соответствие ключам, он находит положение первой подходящей строки:
| Код |
|---|
If arrCheck(i) Then ' если строка ранее помечена как подходящая ro& = ro& + 1 ' вычисляем номер строки в новом массиве ... |
ну и далее. Так вот, как можно в некую переменную передать в этот момент значение i ? Так-то понятно, дописать типа: if r=empty then r=i, но как и что нужно написать, чтобы наряду с полученным значением функции ArrAutofilterNew = newarr иметь доступ к этому дополнительному значению r? Фактически, мне необходимо знать положение отфильтрованного массива (в моем случае он непрерывный) в исходном массиве и я надеюсь получить это значение вышеописанным методом.
P.S. Заранее спасибо всем откликнувшимся