【Excel VBA】FILTER関数を使ってフィルター結果を配列として取得する方法

特定の条件に合うデータを行ごと抽出したい場合、従来はオートフィルターで絞り込んでコピー&ペーストしたり、Forループで1行ずつ判定したりといった方法が主流でした。

しかし、Excel for Microsoft 365およびExcel 2021以降では、FILTER関数という非常に強力な動的配列関数が登場し、VBAからこれを利用することで、驚くほどシンプルかつ高速にデータ抽出が可能になりました。

この記事では、VBAからWorksheetFunction.Filterを使い、抽出結果を配列として取得し、シートに一括で書き出す方法を解説します。


目次

【重要】FILTER関数が使える環境

このテクニックを利用するには、お使いのExcelが**FILTER関数をサポートしているバージョン(Microsoft 365 または Excel 2021以降)**である必要があります。

また、FILTER関数はExcelのテーブル機能と非常に相性が良いため、元となるデータは事前にテーブル化(Ctrl+Tでテーブルに変換)しておくことを強くお勧めします。


完成したVBAコード

以下は、「売上テーブル」という名前のテーブルから、「担当者」列が「山田」であるレコードをすべて抽出し、結果をF2セル以降に書き出すVBAコードです。

Sub ExtractDataWithFilterFunction()

    ' 変数を宣言します
    Dim sourceTable As Range
    Dim criteriaColumn As Range
    Dim criteria As String
    Dim filteredData As Variant

    '--- 設定 ---
    ' データが格納されているテーブル全体
    Set sourceTable = ThisWorkbook.Worksheets("SalesData").ListObjects("売上テーブル").Range
    ' 条件を判定する列(テーブルの"担当者"列)
    Set criteriaColumn = ThisWorkbook.Worksheets("SalesData").ListObjects("売上テーブル").ListColumns("担当者").DataBodyRange
    ' 抽出条件
    criteria = "山田"
    '--- 設定ここまで ---

    ' --- 1. FILTER関数でデータを抽出し、結果を配列に格納 ---
    On Error Resume Next ' 該当データがない場合にエラーになるのを防ぐ
    filteredData = WorksheetFunction.Filter(sourceTable, criteriaColumn = criteria, "該当データなし")
    On Error GoTo 0
    
    ' エラーが発生した、または結果が1行しかない("該当データなし"の)場合
    If IsEmpty(filteredData) Or Not IsArray(filteredData) Then
        MsgBox "「" & criteria & "」に一致するデータは見つかりませんでした。", vbInformation
        Exit Sub
    End If
    
    ' --- 2. 抽出結果の配列を、指定したセルに一括で書き出す ---
    Dim outputCell As Range
    Set outputCell = ThisWorkbook.Worksheets("Summary").Range("F2")
    
    ' Resizeで配列の大きさに合わせて出力先のセル範囲を拡張
    outputCell.Resize(UBound(filteredData, 1), UBound(filteredData, 2)).Value = filteredData

    MsgBox "データの抽出が完了しました。"
    
End Sub

コードのポイント解説

WorksheetFunction.Filter

filteredData = WorksheetFunction.Filter(sourceTable, criteriaColumn = criteria, "該当データなし")

FILTER関数をVBAから呼び出します。引数は以下の通りです。

  • 第1引数 array: フィルターをかけたい配列またはセル範囲全体(sourceTable
  • 第2引数 include: TRUEまたはFALSEを返す条件式(criteriaColumn = criteria)。ここで指定した列の各セルが、条件と一致するかどうかが判定されます。
  • 第3引数 [if_empty] (任意): フィルター結果が1件もなかった場合に返す値("該当データなし")。これを指定しておくと、結果が0件だった場合の処理が簡単になります。

この関数の戻り値は、抽出されたデータが格納された2次元配列です。そのため、受け取る変数(filteredData)はVariant型で宣言します。

② 抽出結果の配列をシートに書き出す

outputCell.Resize(UBound(filteredData, 1), UBound(filteredData, 2)).Value = filteredData

VBAの配列をセル範囲に一括で書き出すための定番テクニックです。

  • UBound(filteredData, 1): 配列の行数(高さ)を取得します。
  • UBound(filteredData, 2): 配列の列数(幅)を取得します。
  • .Resize(...): outputCell(F2セル)を、取得した配列の行数・列数に合わせて、適切な大きさのセル範囲に拡張します。
  • .Value = filteredData: 拡張されたセル範囲のValueプロパティに配列を直接代入することで、すべてのデータが一瞬でシートに書き込まれます。これは、セルを一つずつループで書き込むよりも圧倒的に高速です。

まとめ

FILTER関数が利用できるモダンなExcel環境では、VBAからのデータ抽出が劇的に変わります。

  1. WorksheetFunction.Filterを使い、条件に合うデータを配列として一括で取得する。
  2. 取得した配列のサイズを**UBound**で確認する。
  3. 出力先のセル範囲を**.Resize**で配列のサイズに合わせる。
  4. 範囲の**.Value**に配列を代入し、一括で書き出す。

この新しいアプローチは、従来のオートフィルターやループ処理に比べてコードが非常に簡潔になり、処理速度も向上します。Excel 365や2021をお使いの方は、ぜひこの強力なテクニックをご活用ください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次