特定の条件に合うデータを行ごと抽出したい場合、従来はオートフィルターで絞り込んでコピー&ペーストしたり、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からのデータ抽出が劇的に変わります。
WorksheetFunction.Filter
を使い、条件に合うデータを配列として一括で取得する。- 取得した配列のサイズを**
UBound
**で確認する。 - 出力先のセル範囲を**
.Resize
**で配列のサイズに合わせる。 - 範囲の**
.Value
**に配列を代入し、一括で書き出す。
この新しいアプローチは、従来のオートフィルターやループ処理に比べてコードが非常に簡潔になり、処理速度も向上します。Excel 365や2021をお使いの方は、ぜひこの強力なテクニックをご活用ください。