ただしスピル機能がない古いバージョンで配列数式(Ctrl+Shift+Enterで確定する)を使わず実現することがメインとなっており、式の内容も難しくなっています。
スピル機能がある新しいバージョンについても触れますが、XLOOKUP関数を使った方が簡単です。
旧バージョン(スピル機能がない)の場合
内容はExcel2010で確認していますが画像はMicrosoft 365バージョンのものです。
AND条件(かつ)の場合
次の画像の左側に表があります。B列の産地の値だけでは価格を特定できず、またC列の野菜の値だけでも価格を特定できません。両方の値を指定しなければ価格を特定できず検索もできません。
そこで、F3セルに次のような数式を入力して「静岡県」「だいこん」に対応する価格を取得しています。
F3セル
=INDEX(D3:D8,MATCH("静岡県だいこん",INDEX(B3:B8&C3:C8,0),0))
いきなり複雑ですが、まず「INDEX(B3:B8&C3:C8,0)」により「愛知県ごぼう」「静岡県トマト」…のような6つの値からなる配列を生成しています。
そしてMATCH関数で「静岡県だいこん」の位置(配列内で4番目)を取得し、INDEX関数でD3:D8のうち4番目の値、つまり「220」を取得しています。
この内側のINDEX関数を除いて単に「B3:B8&C3:C8」でよいように思えますが、スピル機能がないバージョンで「=INDEX("静岡県だいこん",MATCH(F3&G3,B3:B8&C3:C8,0))」とすると残念ながらエラーになってしまいます。このINDEX関数はおまじないと思ってください。
次の画像も同じことをやっていますが、数式の考え方が少し異なります。
F3セル
=INDEX(D3:D8,MATCH(1,INDEX((B3:B8="静岡県")*(C3:C8="だいこん"),0),0))
1つ上の例のように文字列を連結して扱うのではなく、各条件をカッコで囲み「*」演算子で連結しています。これにより各条件が真(TRUE)なら1、偽(FALSE)なら0とみなす掛け算を行っています。結果として両方の条件が真となる行を「1」、そうでない行を「0」に変換した6つの値の配列が生成されます。
あとはMATCH関数で「1」が何番目にあるかを取得し、INDEX関数で価格を抽出しています。
なお次のようにしても同じ結果となります。
=INDEX(D3:D8,MATCH(TRUE,INDEX((B3:B8="静岡県")*(C3:C8="だいこん")>0,0),0))
次の画像では、最初の画像と同じように文字列をつなげて扱うやり方で抽出しています。
ただし数式内に検索値(静岡県、だいこん)を書き込むのではなく、F3,G3セルに入力された検索値を参照するようにしています。
H3セル
=INDEX(D3:D8,MATCH(F3&G3,INDEX(B3:B8&C3:C8,0),0))
以降ではこのように、セルに入力された検索値を参照するやり方に統一します。
こちらは「*」演算子を使うやり方です。
H3セル
=INDEX(D3:D8,MATCH(1,INDEX((B3:B8=F3)*(C3:C8=G3),0),0))
これは次のようにしても同じです。
=INDEX(D3:D8,MATCH(TRUE,INDEX((B3:B8=F3)*(C3:C8=G3)>0,0),0))
OR条件(または)の場合
こちらは指定した条件のいずれかを満たすもの(のうち最も上にあるもの)を抽出する例です。
次の画像の左側の表は上記の例と同じものですが、指定した産地と野菜のうちどちらかを満たすもの(のうち最も上にあるもの)を抽出しています。最初の「静岡県」の方が上にあるため「230」が得られています(「静岡県」「トマト」の行)。
H3セル
=INDEX(D3:D8,MATCH(TRUE,INDEX((B3:B8=F3)+(C3:C8=G3)>0,0),0))
文字列を連結するやり方は使えません。そこで「+」演算子を使い、各条件が真(TRUE)なら1、偽(FALSE)なら0とみなす足し算を行っています。さらに「>0」を使い、足し算の結果が1以上の行(いずれかの条件をみたす)を「TRUE」、0の行(いずれの条件も満たさない)を「FALSE」に変換した6つの値からなる配列を生成しています。
あとはMATCH関数で「TRUE」が何番目にあるかを取得し、INDEX関数でD列から価格を抽出しています。
次の画像はもう少し実用的と思われる例で、2種類の検索値を1つの列から検索するというものです。
2種の野菜を同時にB列から検索し、最も上にあるものの価格を求めています。
G3セル
=INDEX(C3:C8,MATCH(TRUE,INDEX((B3:B8=E3)+(B3:B8=F3)>0,0),0))
やっていることは上記例と全く同様で、2つの条件をともに1つの列(B列)に課している点だけが異なります。
次の画像は、複数の列を検索し、いずれかの列に該当する値があれば対応する行の値を取得するというものです。OR条件としては最も実用的な内容かと思われます。
F3セルに入力された担当者名をC列とD列の2つの列から検索し、対応する業務名を取得しています。
G3セル
=INDEX(B3:B6,MATCH(TRUE,INDEX((C3:C6=F3)+(D3:D6=F3)>0,0),0))
これも基本的には上記例と同じで、1つの条件を2つの列に課している点が異なります。
クロス抽出の場合
表の縦横の見出しから値を抽出する、クロス抽出(AND条件の一種)です。
次の画像の左側の表には縦横の見出しがあり、店舗名と年の組み合わせで売上の数値を特定できるようになっています。
そこでJ3セルにINDEX/MATCH関数を使った式を入力し、H3セルの店舗名とI3セルの月に対応する売上高を抽出しています。
J3セル
=INDEX(C3:F6,MATCH(H3,B3:B6,0),MATCH(I3,C2:F2,0))
「MATCH(H3,B3:B6,0)」により、H3セルの値が店名の見出しの何行目にあるかを取得しています。
「MATCH(I3,C2:F2,0)」の部分で、I3セルの値が年の見出しの何列目にあるかを取得しています。
これらをINDEX関数の第2,3引数(行番号,列番号)として指定することで、売り上げの数値を抽出しています。
この場合はこれまでの例と異なり、MATCH関数内でINDEX関数を使う必要がありません。
条件が3つ以上の場合
条件を3つ以上に増やす例ですが、上記の内容が理解できれば難しくありません。
次の画像では店名,メニュー,グレードの3つの値のAND条件で価格を取得しています。
J3セル
=INDEX(E3:E10,MATCH(G3&H3&I3,INDEX(B3:B10&C3:C10&D3:D10,0),0))
文字列を連結するやり方で、3つの値(列)を連結しているだけです。
4つ以上の条件でも同様です。
また、「*」演算子を使って次のようにしてもOKです(2通り)。
=INDEX(E3:E10,MATCH(1,INDEX((B3:B10=G3)*(C3:C10=H3)*(D3:D10=I3),0),0)) =INDEX(E3:E10,MATCH(TRUE,INDEX((B3:B10=G3)*(C3:C10=H3)*(D3:D10=I3)>0,0),0))
やはり式をカッコで囲んで「*」でつないでいくだけです。
OR条件の場合は「*」を「+」に代えればよいのですが、この2つの式のうち上のような式では判定を誤るので下のような式を使う必要があります(上記のOR条件の例でも触れたように、足し算の結果が1以上であることを判定しなければならないため)。
ANDとORの混合も可能ですが、「*」が「+」に優先するのでANDの方が優先順位が高いことに注意してください。かなり込み入った内容になるため具体例は省略しますがカッコを使ってこの優先順位を変えることもできます。
スピル機能があるバージョンの場合
XLOOKUP関数を使った方が簡単ですのでそちらをおすすめします。詳しくは次の記事で紹介しています。
(Excel)XLOOKUP関数で複数条件(AND,OR)を指定する方法 - いきなり答える備忘録
よって以下ではAND条件の例のみ簡単に紹介します。基本的には上記例のAND条件の例と同じですので詳しい説明はそちらをご確認ください。
まずは文字列の連結を用いてAND条件とする例です。
H3セル
=INDEX(D3:D8,MATCH(F3&G3,B3:B8&C3:C8,0))
旧バージョンの例と異なり、MATCH関数内にINDEX関数を置かなくてもエラーにならないので式が短くなります。
最後に「*」演算子を用いてAND条件とする例です。
H3セル
=INDEX(D3:D8,MATCH(1,(B3:B8=F3)*(C3:C8=G3),0))
これは次のようにすることもできます。
=INDEX(D3:D8,MATCH(TRUE,(B3:B8=F3)*(C3:C8=G3)>0,0))
OR条件や3つ以上の条件についても上記例と同様です。
OR条件の場合はMATCH関数の第1引数(検索値)を「TRUE」とする形式にしなければならない点に注意が必要です。