Excel INDEX/MATCHで複数列が0かつ除外条件(<>)を満たす次の行を探す方法

Excelで「複数列がすべて0」かつ「特定の文字列を除外(<>)」した行だけを対象に、INDEX/MATCHで“次の行”を探すなら、条件を文字列連結やANDのネストで組むより、論理値の掛け算で1/0の配列を作る方法が読みやすくて拡張も簡単です。

目次

やりたいこと:複数列が0の行を見つけ、さらに特定文字列の行を除外したい

現場でよくあるのが、ログや工程表、在庫移動などのデータから「次に同じ状態になる行」「次のイベントまでの差分」を取りたいケースです。今回の条件は次のとおりです。

  • 列2・列3・列4がすべて0
  • さらに列5が「Warehouse Upgrade」ではない(列5が「Warehouse Upgrade」の行は検索対象から外す)

この2つを同時に満たす行のうち、現在行の次(下方向)にある最初の行を見つけて、INDEXで取り出したい、というのがゴールです。

連結(0&0&0)やANDのネストがつらくなる理由

複数条件を一気に満たす行を探そうとすると、ありがちな実装は次の2パターンです。

手法よくある書き方困りがちな点
文字列連結で判定(B=0)&(C=0)&(D=0) のように連結して "TRUEFALSE..." を比較意図が読み取りづらく、0以外の条件が混ざると破綻しやすい
ANDのネストAND(AND(AND(...)))条件が増えるほど式が横に長くなり、追加・修正でミスが出やすい

特に「列5は除外(<>)したい」ような条件が混ざると、式の可読性が一気に落ちます。さらに、行範囲(次の20行など)が変わるたびに参照を直す必要が出て、保守が重くなります。

解決のコア:論理値(TRUE/FALSE)を“掛け算”で合成する

Excelでは、(条件) は TRUE/FALSE を返し、計算の文脈では多くの場合 TRUE=1 / FALSE=0 として扱えます。そこで次のように条件を掛け算で束ねます。

(条件1) * (条件2) * (条件3) * ...

掛け算のポイントはシンプルで、全部TRUEのときだけ1、どれか1つでもFALSEなら0になります。つまり「AND条件の塊」を読みやすい形で作れます。

列2=0列3=0列4=0列5<>”Warehouse Upgrade”掛け算結果意味
TRUE(1)TRUE(1)TRUE(1)TRUE(1)1条件を満たす(検索対象)
TRUE(1)TRUE(1)TRUE(1)FALSE(0)0除外文字列なので対象外
TRUE(1)FALSE(0)TRUE(1)TRUE(1)0どれかが0ではないので対象外

この「1/0の配列」が作れたら、あとは MATCH(1, 条件配列, 0) で最初に1になる位置を探し、INDEXで必要な列を引くだけです。

基本形:MATCH(1, 条件配列, 0) で“最初に条件を満たす行”を見つける

まずは“条件配列”だけを単独で考えると理解が速いです。たとえば A2:E10 にデータがあり、3行目以降(A3:E10)を検索対象にするなら、条件配列は次の形になります。

(B3:B10=0) * (C3:C10=0) * (D3:D10=0) * (E3:E10<>"Warehouse Upgrade")

この式は、B~Eの各行について「条件を満たすなら1、満たさないなら0」を返す配列になります。次に、その配列の中から最初の1の位置を取ります。

MATCH(1, (B3:B10=0)*(C3:C10=0)*(D3:D10=0)*(E3:E10<>"Warehouse Upgrade"), 0)

返ってくるのは「検索範囲内での相対位置(1~)」です。ここまで分かれば、INDEXと組み合わせて「該当行のA列」を取り出せます。

INDEX(A3:A10,
      MATCH(1,
            (B3:B10=0)*(C3:C10=0)*(D3:D10=0)*(E3:E10<>"Warehouse Upgrade"),
            0
      )
)

質問の形を保ったまま:R1C1形式で“次の行”を探す式

「現在行の次(下方向)の20行」を探す、という発想はR1C1形式だと非常に書きやすいです。質問の意図(現在行の条件判定→次の該当行を探す)を保ったまま整理すると、次のようになります。

{=IFNA(
   IF((RC2=0)*(RC3=0)*(RC4=0)*(RC5<>"Warehouse Upgrade"),
      INDEX(R[1]C1:R[20]C1,
            MATCH(1,
                  (R[1]C2:R[20]C2=0)*
                  (R[1]C3:R[20]C3=0)*
                  (R[1]C4:R[20]C4=0)*
                  (R[1]C5:R[20]C5<>"Warehouse Upgrade"),
                  0
            )
      )-RC1,
      ""
   ),
"")}

この式でやっていることを、役割ごとに分解すると次のとおりです。

ブロック式の部分役割
現在行が対象か(RC2=0)*(RC3=0)*(RC4=0)*(RC5<>"Warehouse Upgrade")現在行が条件を満たすときだけ、下方向検索を実行する(不要なら外してOK)
検索対象範囲R[1]C?:R[20]C?次の行から20行先までを検索対象にする
条件配列(...=0)*(...=0)*(...=0)*(...<>"Warehouse Upgrade")“全部満たす行だけ1”の配列を作る
MATCHMATCH(1, 条件配列, 0)最初に1になる位置(相対行)を取る
INDEXINDEX(R[1]C1:R[20]C1, 位置)該当行のC1(列1)を返す
差分... - RC1該当行の列1と現在行の列1の差を出す(不要なら削除)
IFNAIFNA( ..., "" )該当行がないとき #N/A を空欄にする

「次の20行」という上限がある場合、このR1C1の書き方は範囲がズレにくく、コピペにも強いのがメリットです。逆に、検索対象が数千行に及ぶなら、後述の“テーブル化”や“補助列”が効いてきます。

A1形式で考えたい人向け:セル参照で同じ発想にする

R1C1に慣れていない場合は、A1形式でも同じロジックで整理できます。例として、A列が返したい値、B~Dが0判定、Eが除外文字列だとします。現在行が2行目で、次の20行(3~22行目)から探すなら、次のようになります。

{=IFNA(
   IF(($B2=0)*($C2=0)*($D2=0)*($E2<>"Warehouse Upgrade"),
      INDEX($A$3:$A$22,
            MATCH(1,
                  ($B$3:$B$22=0)*
                  ($C$3:$C$22=0)*
                  ($D$3:$D$22=0)*
                  ($E$3:$E$22<>"Warehouse Upgrade"),
                  0
            )
      )-$A2,
      ""
   ),
"")}

この形にしておくと、「次の30行に伸ばす」「列6も条件に足す」といった変更が、掛け算の項目を増やすだけで済みます。

Microsoft 365ならLETで“読みやすさ”をもう一段上げられる

条件自体がスッキリしても、範囲参照が長いと式が読みにくいことがあります。Microsoft 365 / Excel 2021以降の LET を使うと、範囲や条件を変数化でき、保守性が上がります(同じ範囲を何度も書かないので、修正点も減ります)。

=LET(
  id, RC1,
  a, R[1]C1:R[20]C1,
  b, R[1]C2:R[20]C2,
  c, R[1]C3:R[20]C3,
  d, R[1]C4:R[20]C4,
  e, R[1]C5:R[20]C5,
  cond, (b=0)*(c=0)*(d=0)*(e<>"Warehouse Upgrade"),
  IFNA(INDEX(a, MATCH(1, cond, 0)) - id, "")
)

LETの利点は、「何を検索しているのか」が式の冒頭で説明される点です。あとから見返したときも、変数名(a,b,c…でも良いですが、業務なら amount, qty, status など)で意図を残せます。

さらに、365なら INDEX/MATCH の代わりに XLOOKUP / XMATCH を使うと式が短くなることもあります。

やりたいこと365向けの書き方例ポイント
該当行の列1を返す=LET(cond,(b=0)*(c=0)*(d=0)*(e<>"Warehouse Upgrade"), XLOOKUP(1, cond, a, "" ,0))“最初の1”を直接引けるので MATCH が不要になる
位置(相対行)だけ欲しい=LET(cond,(b=0)*(c=0)*(d=0)*(e<>"Warehouse Upgrade"), XMATCH(1, cond, 0))位置が取れれば、INDEXや行番号計算にも使える
該当行が複数あるので全部見たい=FILTER(a, (b=0)*(c=0)*(d=0)*(e<>"Warehouse Upgrade"))“一覧で確認”でき、デバッグにも便利

除外条件(<>)の落とし穴:実務データは“見た目どおり”ではない

RC5<>"Warehouse Upgrade" は強力ですが、実データでは次のような“見えない違い”で判定がズレることがあります。

  • 前後スペース:"Warehouse Upgrade "(末尾にスペース)が混ざる
  • 全角・半角:"Warehouse Upgrade"(全角スペース)
  • 表記ゆれ:"Warehouse upgrade" のような大小文字の違い(Excelの通常比較は大小文字を区別しません)
  • 別名やコード:同じ意味の別文字列が存在する

対策としておすすめなのは、式を複雑にする前にデータを正規化することです。たとえば入力側で TRIM(前後スペース除去)や置換を行う、Power Queryでクレンジングしてから取り込む、などです。どうしても式側で吸収するなら、次のように書けます。

(TRIM(R[1]C5:R[20]C5)<>"Warehouse Upgrade")

ただし TRIM を大量行に対して毎回実行すると重くなるため、補助列(クレンジング済み列)を1本作ってそこで整形し、検索条件は整形済み列に対してかける方が高速で安全です。

また、大小文字を区別して除外したい場合は EXACT を使います。EXACTは完全一致(大小文字も区別)なので、除外判定は次のようにします。

--NOT(EXACT(R[1]C5:R[20]C5, "Warehouse Upgrade"))

--(二重マイナス)は TRUE/FALSE を 1/0 に強制変換する定番テクニックです。掛け算でも暗黙変換されますが、EXACTやNOTを挟むときは明示しておくと意図が伝わりやすくなります。

条件の追加・OR条件・空白を0扱いにしたいときの拡張パターン

掛け算による条件合成は、条件が増えても破綻しにくいのが強みです。よくある追加要件を、具体的な式の形でまとめます。

追加したい条件追加する式のパーツ考え方
列6が空白の行だけ*(R[1]C6:R[20]C6="")そのまま“掛け算の項目”を増やす
列2が0または空白をOKにしたい*((R[1]C2:R[20]C2=0)+(R[1]C2:R[20]C2="")>0)ORは足し算で表現し、最後に>0でTRUE/FALSEへ戻す
列5が2種類の除外ワードを含む*ISERROR(SEARCH("Upgrade", R[1]C5:R[20]C5))部分一致の除外は SEARCH + ISERROR が定番(ただし重くなるので注意)
列の値が「0」文字列として入っている*(--(R[1]C2:R[20]C2)=0)数値化してから比較する(データ型の不一致を潰す)

ここで大事なのは、ANDは掛け算、ORは足し算という整理です。ルールが一貫しているので、式が長くなっても迷子になりにくくなります。

大きい表でも遅くしないコツ:範囲と計算回数を管理する

INDEX/MATCHの配列条件は便利ですが、範囲を広げすぎると計算が重くなります。特に B:B のような列全体参照を複数条件で使うと、行数分の配列計算が走りやすくなります。実務で安定させるコツをまとめます。

  • 検索範囲を必要最小限に絞る:今回のように「次の20行」など上限があるなら、その範囲に固定する
  • テーブル(Ctrl+T)を使い、構造化参照で可読性を上げる:列名で条件が書けるので、式の意味が残る
  • 補助列でフラグを作る:条件式を1回だけ計算し、MATCHはそのフラグ列を見る
  • TRIM/SEARCHなど重い関数は“都度判定”にしない:データクレンジング側に寄せる
  • 揮発性関数(OFFSETなど)に依存しない:再計算が増えやすいので、可能ならINDEXベースにする

補助列フラグは、デバッグのしやすさも大きなメリットです。例えばF列に次のようなフラグを作ります(行ごとに1/0)。

=(B2=0)*(C2=0)*(D2=0)*(E2<>"Warehouse Upgrade")

あとは「次の行から下」を探す場合、MATCHの対象がフラグ列だけになり、式がかなり短くなります。複数人で運用するファイルほど、補助列の価値は上がります。

#N/Aや意図しない行が返るときのチェックポイント

配列条件のINDEX/MATCHでつまずくのは、ほとんどが「データの状態」か「範囲ズレ」です。よくある原因と見直し順をまとめます。

症状原因になりやすい点確認・対策
#N/Aになる条件を満たす行が範囲内にない/除外条件が厳しすぎるまず FILTER(365)や補助列で「1になる行があるか」を可視化する
違う行がヒットする検索範囲(R[1]~)が想定とズレている「どの行から検索しているか」を再確認。R1C1なら相対参照のずれを疑う
0のはずが一致しない数値の0ではなく文字列”0″、または空白--で数値化して比較する、または入力ルールを統一する
除外文字列が効かない末尾スペース、全角スペース、表記ゆれTRIMや置換、Power Queryで正規化。必要なら EXACT で大小文字も含めて設計

Excelの「数式の検証」や「評価」も有効ですが、配列条件は一度“条件配列だけ”を別セルに出して目視するのが最短ルートです。例えば同じ条件式をそのまま入力して、1/0が想定どおり並ぶかを見るだけで、原因の切り分けが一気に進みます。

まとめ:INDEX/MATCHの複数条件は“掛け算”で整理すると強い

列2~4がすべて0、さらに列5が特定文字列ではない(<>)行だけを対象に「次の行」を探すなら、条件を連結したりANDをネストするより、論理値の掛け算で条件配列を作るのが読みやすく拡張も簡単です。

  • AND条件は (条件1)*(条件2)*... で合成
  • 条件配列ができたら MATCH(1, 条件配列, 0) で最初の該当行
  • INDEXで必要な列を返し、必要なら差分(-RC1など)も同じ式内で出せる
  • 実務では除外文字列の表記ゆれやスペースに注意し、可能ならデータ側で正規化する

この型を覚えておくと、「除外条件が増えた」「OR条件も混ざった」「検索範囲を動的にしたい」といった追加要件にも、式を壊さずに積み上げられます。まずは条件配列を掛け算で作り、MATCHで1を探す、という流れで組み立ててみてください。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次