doodle-on-web

自分で調べたことや、仕事の中で質問されたことなどをまとめています。

Excelで部分一致する全データを一括抽出する方法【古いバージョン対応の組み合わせ技】

スポンサーリンク


Excelで部分一致する全データを一括抽出する方法【古いバージョン対応の組み合わせ技】

VLOOKUPで部分一致の全件抽出をしようとして、途中で詰まった経験はありませんか?

たとえば「Appleを含む商品名をすべてリストアップしたい」というとき、VLOOKUPやXLOOKUPでは最初の1件しか取れません。かといってFILTER関数はExcel 2019以前では使えない……。

そんなときに頼りになるのが、INDEX・AGGREGATE・ISNUMBER・SEARCHの組み合わせです。スピルなし・古いバージョン対応で、部分一致する全データを上から順に抽出できます。

この記事を読めば、どのバージョンのExcelでも部分一致の全件抽出ができるようになります。ステップごとに分解して解説するので、数式が苦手な方も安心して読み進めてください。


完成数式から全体像をつかむ

まず完成形を見ておきましょう。抽出結果を表示したいセル(例:E2)に入れる数式はこちらです。

=IFERROR(INDEX($A$2:$A$7, AGGREGATE(15, 6, IF(ISNUMBER(SEARCH($D$2,$A$2:$A$7)), ROW($A$2:$A$7)-ROW($A$2)+1, NA()), ROW(A1))), "")

複雑に見えますが、4つのパーツに分解すると意外とシンプルです。以降でステップごとに仕組みを説明します。


使うデータと完成イメージ

今回は以下のデータを使います。

A列(商品名)
Apple Juice
Orange Soda
Apple Cider
Grape Juice
Pineapple Smoothie
Lemon Tea

D2セルに検索キーワード apple を入力すると、E列に次の3件が上から順に抽出されるのがゴールです。

E列(抽出結果)
Apple Juice
Apple Cider
Pineapple Smoothie

「Pineapple」も抽出されるのがポイントです。SEARCH関数は大文字・小文字を区別しないため、appleApplePineapple も拾えます。


使う関数の役割

関数 役割
SEARCH キーワードが何文字目にあるか返す(大文字小文字不問)
ISNUMBER 数値ならTRUE、エラーならFALSEに変換
AGGREGATE エラーを無視しながらk番目の行番号を取得
INDEX 行番号から実際の値を取り出す

数式の組み立てをステップで理解する

ステップ1:SEARCH+ISNUMBERで「含む/含まない」を判定する

=ISNUMBER(SEARCH($D$2, $A$2:$A$7))

SEARCH関数はキーワードが見つかれば位置を数値で返し、見つからなければエラーを返します。ISNUMBERはそれを受け取り、数値ならTRUE・エラーならFALSEに変換します。

A2:A7に対して実行すると、結果はこうなります。

{TRUE; FALSE; TRUE; FALSE; TRUE; FALSE}

Apple Juice・Apple Cider・Pineapple Smoothieの行がTRUEになりました。

ステップ2:TRUEの行だけ行番号を返し、それ以外はエラーにする

=IF(ISNUMBER(SEARCH($D$2, $A$2:$A$7)), ROW($A$2:$A$7)-ROW($A$2)+1, NA())

TRUEの行にはINDEX用の相対行番号(1始まり)を返し、FALSEの行はNA()でエラーにします。

{1; #N/A; 3; #N/A; 5; #N/A}

ここで空文字("")ではなくNA()を使う理由:AGGREGATEはエラーのみを無視します。空文字や0はエラーではないため、誤って行番号として拾われてしまいます。必ずNA()を使いましょう。

ステップ3:AGGREGATEでk番目の行番号を取り出す

=AGGREGATE(15, 6, IF(..., ROW(...)-ROW($A$2)+1, NA()), ROW(A1))
  • 15:SMALL相当の処理(小さい順に取得)
  • 6:エラーを無視するオプション
  • 最後のROW(A1):何番目の値を取るか(1, 2, 3…と変化)

E2ではROW(A1)=1で1番目に小さい行番号(→1)、E3ではROW(A2)=2で2番目(→3)、E4では3番目(→5)が返ります。数式をそのままコピーするだけでkが自動的に増えていくのがポイントです。

ステップ4:INDEXで実際の値を取り出す

=INDEX($A$2:$A$7, AGGREGATE(...))

ステップ3で得た行番号をINDEXに渡すと、対応する商品名が返ります。最後にIFERRORで囲むと、件数を超えた行が空白になりスッキリします。


よくあるエラーと対処法

数式を入れたら全部エラーになる

原因として多いのは行番号の調整ミスです。 ROW($A$2:$A$7) だけを使うと2〜7の絶対行番号が返るため、INDEXの相対位置(1〜6)とずれてしまいます。必ず ROW($A$2:$A$7)-ROW($A$2)+1 と書いてください。

件数より多くコピーしたら#VALUEが表示される

これは正常な動作です。IFERRORでラップしていれば空白になります。まだラップしていない場合は以下を確認してください。

=IFERROR(INDEX(...), "")

大文字・小文字を区別して抽出したい

SEARCHをFINDに置き換えるだけでOKです。FINDは大文字・小文字を厳密に区別します。


次にやること

  1. 小さなデータで動作確認する:6行程度のリストで数式を試し、期待通りに抽出されるか確かめましょう
  2. データが増減するならテーブル化する:Ctrl+Tでテーブル化しておくと、データが増えても数式の範囲が自動で広がります
  3. Excel 365・2021ならFILTER関数も検討する:互換性が不要な環境では、よりシンプルなFILTERも有力な選択肢です
=FILTER($A$2:$A$7, ISNUMBER(SEARCH($D$2,$A$2:$A$7)), "")

古いバージョンとの共有ファイルや、スピルを使いたくない場面では今回のAGGREGATE方式が引き続き活躍します。


まとめ

INDEX・AGGREGATE・ISNUMBER・SEARCHの組み合わせを使えば、古いバージョンのExcelでも部分一致する全データを上から順に抽出できます。

数式の核心は「ISNUMBERで一致判定→NA()でエラー化→AGGREGATEでエラーを飛ばして行番号取得→INDEXで値取得」という流れです。ステップを一つずつ確認しながら組み立てると、複雑に見えた数式も怖くなくなります。

まずは手元の小さなデータで試してみて、動作を確認してから本番データに応用してみてください。


Lookup関数シリーズの他の記事もあわせてご覧ください。