Vba excel фильтрация массива

Фильтрация одномерного массива в VBA Excel с помощью функции Filter. Синтаксис и параметры функции Filter. Пример фильтрации одномерного массива.

Filter – это функция, которая возвращает массив, содержащий строки исходного одномерного массива, соответствующие заданным условиям фильтрации.

Примечания

  • исходный (фильтруемый) массив должен быть одномерным и содержать строки;
  • индексация возвращенного массива начинается с нуля;
  • возвращенный массив содержит ровно столько элементов, сколько строк исходного массива соответствуют заданным условиям фильтрации;
  • переменная, которой присваивается возвращенный массив, должна быть универсального типа (As Variant) и объявлена не как массив (не myArray() со скобками, а myArray без скобок).

Функция Filter автоматически преобразует обычную переменную универсального типа, которой присваивается отфильтрованный список, в одномерный массив с необходимым количеством элементов.

Синтаксис

Filter(sourcearray, match, [include], [compare])

Параметры

Параметр Описание
sourcearray Обязательный параметр. Одномерный массив, элементы которого требуется отфильтровать
match Обязательный параметр. Искомая строка.
include Необязательный параметр. Значение Boolean, которое указывает:

  • True – возвращаются строки, содержащие match (значение по умолчанию);
  • False – возвращаются строки, не содержащие match.
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

vba filter array 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!
vba save as

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

Понравилась статья? Поделить с друзьями:
  • Vba excel умные таблицы
  • Vba excel удалить одну строку
  • Vba excel фильтр по значению ячейки
  • Vba excel умножить ячейки
  • Vba excel удалить объект excel