Фильтрация одномерного массива в VBA Excel с помощью функции Filter. Синтаксис и параметры функции Filter. Пример фильтрации одномерного массива.
Filter – это функция, которая возвращает массив, содержащий строки исходного одномерного массива, соответствующие заданным условиям фильтрации.
Примечания
- исходный (фильтруемый) массив должен быть одномерным и содержать строки;
- индексация возвращенного массива начинается с нуля;
- возвращенный массив содержит ровно столько элементов, сколько строк исходного массива соответствуют заданным условиям фильтрации;
- переменная, которой присваивается возвращенный массив, должна быть универсального типа (As Variant) и объявлена не как массив (не myArray() со скобками, а myArray без скобок).
Функция Filter автоматически преобразует обычную переменную универсального типа, которой присваивается отфильтрованный список, в одномерный массив с необходимым количеством элементов.
Синтаксис
Filter(sourcearray, match, [include], [compare]) |
Параметры
Параметр | Описание |
---|---|
sourcearray | Обязательный параметр. Одномерный массив, элементы которого требуется отфильтровать |
match | Обязательный параметр. Искомая строка. |
include | Необязательный параметр. Значение Boolean, которое указывает:
|
compare | Необязательный параметр. Числовое значение (константа), указывающее тип сравнения строк. По умолчанию – 0 (vbBinaryCompare). |
Compare (значения)
Параметр compare может принимать следующие значения:
Константа | Значение | Описание |
---|---|---|
vbUseCompareOption | -1 | используется тип сравнения, заданный оператором Option Compare |
vbBinaryCompare | 0 | выполняется двоичное сравнение (регистр имеет значение) |
vbTextCompare | 1 | выполняется текстовое сравнение (без учета регистра) |
Пример фильтрации
Фильтрация списка в столбце «A» по словам, начинающимся с буквы «К», и загрузка результатов в столбец «B»:
Пример кода VBA Excel с функцией Filter:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Sub Primer() Dim arr1, arr2, arr3, i As Long ‘Присваиваем переменной arr1 массив значений столбца A arr1 = Range(«A1:A» & Range(«A1»).End(xlDown).Row) ‘Копируем строки двумерного массива arr1 в одномерный arr2 ReDim arr2(1 To UBound(arr1)) For i = 1 To UBound(arr1) arr2(i) = arr1(i, 1) Next ‘Фильтруем строки массива arr2 по вхождению подстроки «К» ‘и присваиваем отфильтрованные строки переменной arr3 arr3 = Filter(arr2, «К») ‘Копируем строки из массива arr3 в столбец «B» For i = 0 To UBound(arr3) Cells(i + 1, 2) = arr3(i) Next End Sub |
Данная функция ищет в массиве все строки, подходящие под заданные критерии, и возвращает результат в виде отфильтрованного массива:
PS: Код обновлён 4 января 2021 года, — теперь он работает в 40 раз быстрее, нежели прежняя версия функции
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
Пример использования:
Sub FilterExample() On Error Resume Next Dim arr As Variant ' отбираем только нужные строки из диапазона a2:t200, ' где текст в третьем столбце начинается с "asy" arr = ArrAutofilterNew(Range("a2:t200").Value, "3=asy*") ' создаем лист, вставляем на него результат Worksheets.Add.Range("a1").Resize(UBound(arr, 1), UBound(arr, 2)).Value = arr End Sub
Return to VBA Code Examples
The VBA Filter Function allows you to quickly filter arrays. There are several settings to consider when filtering arrays. We will discuss them below.
Filter – Match
By default the VBA Filter Function will filter an array for matches. In the example below we will filter the array for matches with “Smith”.
Sub Filter_Match()
'Define Array
Dim strNames As Variant
strNames = Array("Steve Smith", "Shannon Smith", "Ryan Johnson")
'Filter Array
Dim strSubNames As Variant
strSubNames = Filter(strNames, "Smith")
'Count Filtered Array
MsgBox "Found " & UBound(strSubNames) - LBound(strSubNames) + 1 & " names."
End Sub
A couple important points:
- The filtered array variable should be declared as data type variant to avoid defining the array size.
- By default, the Filter function is case sensitive. So filtering on “smith” would give a different result than “Smith”. Below we will show you how to change this setting.
Filter – Case Insensitive
By default, VBA is Case Sensitive. This means that for text to match, the cases must be the same (ex. “smith” does not equal “Smith”). This is true of the Filter Function, as well as all (most?) other VBA functions or comparisons.
Personally, I never want VBA to be case sensitive, so I always add Option Compare Text to the top of all of my code modules. Option Compare Text tells VBA to ignore case so that it’s Case Insensitive:
Option Compare Text
Adding Option Compare Text to the top of your module will make the Filter Function case insensitive. Alternatively, you can tell the Filter Function itself to be case insensitive with the vbTextCompare argument:
strSubNames = Filter(strNames, "smith", , vbTextCompare)
Full example:
Sub Filter_MatchCase()
'Define Array
Dim strNames As Variant
strNames = Array("Steve Smith", "Shannon Smith", "Ryan Johnson")
'Filter Array
Dim strSubNames As Variant
strSubNames = Filter(strNames, "smith", , vbTextCompare)
'Count Filtered Array
MsgBox "Found " & UBound(strSubNames) - LBound(strSubNames) + 1 & " names."
End Sub
Filter – Does Not Match
The Filter Function can also be used to identify array items that DO NOT match the entered criteria by setting the Include argument to FALSE:
strSubNames = Filter(strNames, "Smith", False)
Full Example:
Sub Filter_NoMatch()
'Define Array
Dim strNames As Variant
strNames = Array("Steve Smith", "Shannon Smith", "Ryan Johnson")
'Filter Array
Dim strSubNames As Variant
strSubNames = Filter(strNames, "Smith", False)
'Count Filtered Array
MsgBox "Found " & UBound(strSubNames) - LBound(strSubNames) + 1 & " names."
End Sub
Filter Function
The VBA Filter function returns an Array subset of a supplied string array.
The Filter Function Syntax is:
Filter( SourceArray, Match, [Include], [Compare] )
The Function arguments are:
- SourceArray – The original Array to filter
- Match – The string to search for
- [Include] – OPTIONAL TRUE (Returns matches), FALSE (Returns elements that do not match)
- [Compare] – OPTIONAL vbBinaryCompare – binary comparison, vbTextCompare – text comparison, vbDatabaseCompare – database comparison
VBA Coding Made Easy
Stop searching for VBA code online. Learn more about AutoMacro — A VBA Code Builder that allows beginners to code procedures from scratch with minimal coding knowledge and with many time-saving features for all users!
Learn More!
Arrays are not very flexible: in particular not easy to resize (though you can do so using Redim Preserve
.
Personally I would use a Collection if you want a variable number of items and or want to filter items in VBA.
First define a Class Module with properties or fields that represent the columns of your 2D array. You should give the class and it’s properties meaningful names, and appropriate data types, but I don’t know your application so I’ll use:
Class Module "MyClass":
Public Col1 As Variant
Public Col4 As Variant
Public Col6 As Variant
You can then create a Collection and add instances of your class to it as follows:
Dim col As Collection
Set col = New Collection
For i = LBound(myArray, 1) To UBound(myArray, 1)
If myArray(i, 1) > 1 Then
Dim c As MyClass
Set c = New MyClass
c.Col1 = myArray(i, 1)
c.Col4 = myArray(i, 4)
c.Col6 = myArray(i, 6)
col.Add c
End If
Next I
You can then filter it further, e.g.:
Dim col2 As Collection
Set col2 = New Collection
For Each c In col
If c.Col1 = 5 Then
col2.Add c
End If
Next c
And finally copy it back to a 2D array so you can write it back to an Excel Sheet:
Dim myArray2() As Variant
Dim c As MyClass
ReDim myArray2(0 To col2.Count - 1, 0 To 6)
For i = 0 To col2.Count - 1
Set c = col2(i + 1) ' Collection indexes are 1-based
myArray2(i, 1) = c.Col1
myArray2(i, 4) = c.Col4
myArray2(i, 6) = c.Col6
Next i
You could even write a Class Module that is a strongly-typed collection of MyClass
objects, a class module MyClassCollection
as described in the linked blog article.
VBA Array Filter Function in Excel. The filter function returns an array, which contains subset of string based on specified criteria.
Table of Contents:
- Objective
- Syntax of VBA Filter Function in Excel
- Includes all filtered strings – case sensitive
- Extract all filtered strings – not a case sensitive
- Excludes or doesn’t contain filtered string – Case Sensitive
- Instructions to Run VBA Macro Code
- Other Useful Resources
Here is the Syntax of the Filter Function in Excel VBA.
Filter(SourceArray, Match, [Include], [Compare] )
Where SourceArray: Required parameter. The array of strings to be searched. It shouldn’t be null. If it is null then returns an error.
Match: Required parameter. The string to search for.
Include: An optional Boolean parameter. It represents to include or exclude the matching string.
Compare: An optional parameter. It represents type of comparison(Binary or Textual or Database). Default value is ‘0’ i.e vbBinaryCompare.
VBA Constant | Value | Explanation |
vbUseCompareOption | -1 | Performs a comparison using the ‘option compare’ |
vbBinaryCompare | 0 | Performs a Binary comparison |
vbTextCompare | 1 | Performs a Textual comparison |
vbDatabaseCompare | 2 | Microsoft Access only. Performs a comparison based on information in your database. |
Includes all filtered strings – case sensitive
Let us see the example vba macro code using array filter function in Excel. In the below example we have specified an array with values. We are filtering or extracting substrings values which are case sensitive.
'Case: Case Sensitive and includes all filtered data Sub VBA_Array_Filter_Function_Ex1() 'Variable declaration Dim myArray As Variant Dim SubStringArray As Variant Dim FilterValue As Variant 'Create an Array myArray = Array("Sunday", "MonDay", "Tuesday", "WednesDay", "Thursday", "FriDay", "Saturday") 'Etract string contains 'Day' from specified array SubStringArray = Filter(myArray, "day") 'or 'SubStringArray = Filter(myArray, "day", True) 'or 'SubStringArray = Filter(myArray, "day", True,vbBinaryCompare) 'Loop through array values For Each FilterValue In SubStringArray Debug.Print FilterValue Next End Sub
Here is the screenshot of above vba macro code.
Extract all filtered strings – not a case sensitive
Let us see the example vba macro code using array filter function in Excel. In the below example we have specified an array with values. We are filtering or extracting substrings values which are not a case sensitive.
'Case: Ignores Case Sensitive while filtering data Sub VBA_Array_Filter_Function_Ex2() 'Variable declaration Dim myArray As Variant Dim SubStringArray As Variant Dim FilterValue As Variant 'Create an Array myArray = Array("Sunday", "MonDay", "Tuesday", "WednesDay", "Thursday", "FriDay", "Saturday") 'Ignores Case Sensitive while filtering data SubStringArray = Filter(myArray, "day", True, vbTextCompare) 'Loop through array values For Each FilterValue In SubStringArray Debug.Print FilterValue Next End Sub
Here is the screenshot of above vba macro code.
Excludes or doesn’t contain filtered string – Case Sensitive
Let us see the example vba macro code using array filter function in Excel. In the below example we have specified an array with values. We are filtering or extracting sub-strings which are not containing specified filter sub-string.
'Case: Excludes or doesn't contain filtered string and Case Sensitive Sub VBA_Array_Filter_Function_Ex3() 'Variable declaration Dim myArray As Variant Dim SubStringArray As Variant Dim FilterValue As Variant 'Create an Array myArray = Array("Sunday", "MonDay", "Tuesday", "WednesDay", "Thursday", "FriDay", "Saturday") 'Excludes filtered string which contains 'day' from specified array SubStringArray = Filter(myArray, "Day", False) 'or 'SubStringArray = Filter(myArray, "day", False, vbBinaryCompare) 'Loop through array values For Each FilterValue In SubStringArray Debug.Print FilterValue Next End Sub
Here is the screenshot of above vba macro code.
Instructions to Run VBA Macro Code or Procedure:
You can refer the following link for the step by step instructions.
Instructions to run VBA Macro Code
Other Useful Resources:
Click on the following links of the useful resources. These helps to learn and gain more knowledge.
VBA Tutorial VBA Functions List VBA Arrays VBA Text Files VBA Tables
VBA Editor Keyboard Shortcut Keys List VBA Interview Questions & Answers Blog