いきなり答える備忘録

Google Workspace・Microsoft 365・LibreOfficeなどに関するメモ

(Gスプレッドシート)INDEX+MATCH関数で複数条件(AND,OR)を指定する

 GoogleスプレッドシートでINDEX関数とMATCH関数を使って検索・抽出を行う際に、AND条件(かつ)やOR条件(または)を設定する方法です。AND条件の一種であるクロス抽出についても紹介します。

AND条件(かつ)の場合

 次の画像の左側に抽出の対象となる表があります。B列の建物名だけでも、C列の部屋番号だけでも入居者を特定できず、両方の値により入居者を特定できるようになっています。
 右側は検索欄になっており、F3セルに建物名、G3セルに部屋番号が入力されています。
 INDEX/MATCH関数による抽出では検索値を1つしか指定できないので難しそうですが、ちょっと工夫して次のような式で抽出を行っています。

 H3セル

=INDEX(D3:D8,MATCH(F3&G3,B3:B8&C3:C8,0))

 MATCH関数の第1引数(検索値)を「F3&G3」、第2引数(検索範囲)を「B3:B8&C3:C8」としています。
 これにより「表の2つの列の文字列をつないだ文字列」から「2つの検索値をつないだ文字列」を検索していることになり、検索が成立します。
 なおMATCH関数の第3引数は0(完全一致検索)としています。以下の例でも同様です。
 また、ARRAYFORMULA関数が必要な感じに見えますがINDEX関数では必要ありません。




 ただし検索値を拡張して複数の結果を一括取得する場合は注意が必要です。
 次の画像では3つの検索値の組が入力されていますが、上記のMATCH関数の第1日引数を「F3:F5&G3:G5」と拡張しても3つの結果を一括取得することができません。ARRAYFORMULAで囲んでもダメです(この辺りがちょっとよくわからない仕様ですが)。
 そこで絶対参照を使った次のような式にしてH5セルまでフィルコピーしています。また、スマートフィル(数式の提案機能)がはたらくと思うのでそれを利用するのもよいでしょう。

 H3セル(下方にコピー)

=INDEX(D$3:D$8,MATCH(F3:F5&G3:G5,B$3:B$8&C$3:C$8,0))

 


 次の画像ではAND条件のもう1つの方法を実行しています。
 H3セルに最初の画像と異なる式を入力していますが、同じく両方の条件を満たす行の値を取得しています。

 H3セル

=INDEX(D3:D8,MATCH(TRUE,(B3:B8=F3)*(C3:C8=G3)>0,0))

 MATCH関数の第2引数「(B3:B8=F3)*(C3:C8=G3)>0」がポイントです。ここで「*」演算子を使った論理演算を行い、左側の表(B3:C8)のうち両方の条件を満たす行をTRUE、そうでない行をFALSEに変換した6行1列の配列を生成しています。さらに第1引数をTRUEとして配列中のTRUEの位置を特定し、INDEX関数の第2引数(行番号)とすることで、対応する位置にある入居者を取得しています。



 この方法の場合も、検索値を拡張することができません(これは下記のOR条件の場合も同様)。
 次の画像では、絶対参照を使った式をフィルコピーして3つの検索結果を得ています。

 H3セル(下方にコピー)

=INDEX(D$3:D$8,MATCH(TRUE,(B$3:B$8=F3)*(C$3:C$8=G3)>0,0))


OR条件(かつ)の場合

 指定した条件のいずれかを満たす行のうち、最も上にあるものの値を抽出する例です。
 次の画像の左側の表は上記の例と全く同じものです。しかしこちらでは指定した建物名と部屋番号のうちどちらかを満たすもの(のうち最も上のもの)を抽出しています。

 H3セル

=INDEX(D3:D8,MATCH(TRUE,(B3:B8=F3)+(C3:C8=G3)>0,0))

 ここではMATCH関数の第2引数「(B3:B8=F3)+(C3:C8=G3)>0」としています。「+」演算子を使った論理演算により、B3:C8の範囲(左側の表)はTRUEまたはFALSEからなる6行1列の配列に変換されます(TRUE…いずれかを満たす行、FALSE…そうでない行)。さらに第1引数をTRUEとして配列中のTRUEの位置を特定し、INDEX関数の第2引数(行番号)とすることで入居者の値を取得しています。
 AND検索の2つ目の例(3つ目の画像)とは「*」が「+」になった点だけが異なるだけでほとんど同じ式です。

複数の検索値を検索する

 1つ上の例はあまり実用的とは言えませんが、こちらは実際にありそうなOR条件の利用例です。
 1つの列に2つの検索値(商品名)を設定して検索し、いずれか上にある方の価格を取得しています。

 G3セル

=INDEX(C3:C9,MATCH(TRUE,(B3:B9=E3)+(B3:B9=F3)>0,0))

 検索の考え方は全く同じなので式もほとんど同じです。
 同じ列を対象として2つの条件を判定しているだけの違いです。

検索範囲を複数列にする

 1つの検索値を複数列から探すというもので、実用的にもっともありそうなOR条件の利用例です。
 次の画像ではF3セルに入力された担当者名をB列とC列の2つの列から検索し、その担当地区を取得しています。

 G3セル

=INDEX(D3:D6,MATCH(TRUE,(B3:B6=F3)+(C3:C6=F3)>0,0))

 これも上記例とほとんど同じで、2つの列を対象として同一の条件を判定している点だけが異なります。

クロス抽出の場合

 表の縦横の見出しから値を抽出するというクロス抽出の例です。
 次の画像の左側の表には縦の見出し(店舗名)と横の見出し(月)があり、この店舗名と月の組み合わせで売上高を特定できます。
 J3セルにINDEX/MATCH関数を使った式を入力して、H3セルの店舗名とI3セルの月に該当する売上高を取得しています。

 J3セル

=INDEX(C3:F7,MATCH(H3,B3:B7,0),MATCH(I3,C2:F2,0))

 「MATCH(H3,B3:B7,0)」によりH3セルの値が縦の見出し(店舗名)の何行目にあるかがわかります。
 「MATCH(I3,C2:F2,0)」によりI3セルの値が横の見出し(月)の何列目にあるかがわかります。
 これらをINDEX関数の第2,3引数(行番号,列番号)として指定することにより値を取得しています。
 表引き(複数条件含む)についてはXLOOKUP関数を使う方法も考えられますが、クロス抽出はあまりにもINDEX/MATCH関数の機能に適した抽出内容なのでこちらを愛用するユーザも多いと思います。