Excel ○以上○未満のデータを抽出する方法

Excel ○以上○未満のデータを抽出する方法 Excel

はじめに:そのサイズ、本当に合っていますか?

ネットショッピングで服を買うとき、誰もが一度は見たことがある、この「サイズ表」。

Excel説明画像

「身長161cm、体重56kgの自分に合うサイズは…えーっと…」と、目で追って探すのは、意外と面倒だったり、間違えやすかったりしますよね。

「こんなの、Excelで一発で検索できないの?」

そう思ったあなた、素晴らしい着眼点です!

今回の記事は、まさにこの「○以上○未満」という条件でデータを抽出する、実務でも超頻出のテクニックをマスターする冒険です。

でも、そこは「Excelで暇つぶし」。

ただ王道テクニックを紹介するだけでは終わりません!

実用性を完全に無視した、関数好きの心をくすぐるマニアックな数式パズルにも、たくさん挑戦していきますよ。

目的は、

「近似一致」のロジックを深く理解し、関数の応用力を養うこと!

この冒険が終わる頃には、あなたのExcelスキルが、また一つ上のステージへと進化しているかもしれません!

本記事では、無料のWeb版Excelを使用して検証および画像の作成を行っています。Windowsはもちろん、MacやLinuxの方もブラウザさえあれば挑戦できます!

ステップ1:準備 – 最強の武器「名前付き数式」を創り出す

今回のサイズ表、よく見ると「145~160」のように、見出しが文字列になっています。このままでは、数値として比較できず、非常に使いづらいですよね。

Excel説明画像

「じゃあ、どこか別のセルに {0, 145, 160, …} のような作業用の表を作るの?」

いいえ!もっとスマートな方法があります。

それが「名前の定義に、直接数式を埋め込む」という、超絶クールなテクニックです!

まず、B2:F6のサイズが書かれた本体部分に「範囲」という名前をつけましょう。

Excel説明画像

次に、Web版Excelの「数式」タブ → 「ネームマネージャー」を開き、以下の2つの「名前付き数式」を定義します。

1. 名前: 身長表

参照先: =(0&LEFT(Sheet1!$B$1:$F$1,FIND("~",Sheet1!$B$1:$F$1&"~")-1))+0

Excel説明画像

2. 名前: 体重表

参照先: =(0&LEFT(Sheet1!$A$2:$A$6,FIND("~",Sheet1!$A$2:$A$6&"~")-1))+0

Excel説明画像

この数式、一体何をしているのでしょうか?「身長表」を例に分解してみましょう。

FIND("~", ... &"~"): 「~」という文字が何文字目にあるかを探します。B1:F1&"~"としているのは、「190~」のように~が最後にしかない場合でもエラーを防ぐためのおまじないです。

Excel説明画像

LEFT(..., ...-1): 「~」の手前までの文字(つまり数値)を抜き出します。

Excel説明画像

0&...: 空白を数値に変換すると、エラーになるので、「0」を先頭に追加しています。

Excel説明画像

(...)+0: 最後に、ここまでで作った文字列の配列に0を足すことで、Excelはそれを数値の配列 {0,145,160,175,190} として認識してくれるのです!

Excel説明画像

これで、作業セルを一切使わずに、数式内で使える動的な数値リストが完成しました。すごく便利ですよね!

Excel説明画像

8つのアプローチで、「近似一致」を完全攻略!

それでは、身長(B10セル)と体重(B11セル)の検索値から、正しいサイズをD10セルに表示させる数式を組み立てていきましょう!

Excel説明画像

アプローチ1:INDEX + MATCH(揺るぎなき王道)

考えかた

まずは、実務で最も推奨される、可読性と安定性に優れた王道の組み合わせです。

行方向と列方向、それぞれの位置をMATCH関数の「近似一致」で特定し、最後にINDEX関数でその座標にある値を取り出します。

数式と解説

=INDEX(範囲,MATCH(B11,体重表,1),MATCH(B10,身長表,1))

この数式を、内側から順に見ていきましょう。

MATCH(B11,体重表,1): ここが最大のポイント!

MATCH関数の第3引数を「1」にすると、「検索値以下の、最も大きい値」が検索範囲の何番目にあるかを返してくれます。

例えば、体重「56」を{0,40,55,70,85}から探すと、56以下で最も大きいのは「55」なので、その位置である「3」番目を返します。

Excel説明画像

MATCH(B10,身長表,1): 同様に、身長「161」を{0,145,160,175,190}から探すと、161以下で最も大きい「160」の位置である「3」番目を返します。

Excel説明画像

INDEX(範囲,3,3): 最後に、INDEX関数が、「範囲」の中から「3行目の3列目」の値をピンポイントで取り出し、正しいサイズ「M」を返してくれるのです。

Excel説明画像

アプローチ2:INDEX + SUM(ロジックの核心)

考えかた

MATCH関数の近似一致のロジック、実はSUM関数でも再現できます。

「検索値が、基準値の配列以上になっている箇所がいくつあるか」を数えることで、位置を特定する考え方です。これは配列計算の基本の「き」ですよ!

数式と解説

=INDEX(範囲,SUM((B11>=体重表)*1),SUM((B10>=身長表)*1))

SUM((B11>=体重表)*1): まず、B11>=体重表の部分で、体重「56」が{0,40,55,70,85}の各値以上かどうかを判定し、{TRUE,TRUE,TRUE,FALSE,FALSE}という配列を作ります。

Excel説明画像

これに1を掛けて数値化({1,1,1,0,0})し、SUM関数で合計することで「3」という位置を計算します。MATCH関数と全く同じ結果になりましたね!

Excel説明画像

SUM((B10>=身長表)*1): 同様に、身長「161」の位置も「3」と計算します。

INDEX(範囲,3,3): 結果は、もちろん同じ「M」です。

Excel説明画像

アプローチ3:OFFSET(INDEXの代わりに)

考えかた

アプローチ2とロジックはほぼ同じですが、最後の値の取り出しをINDEX関数の代わりにOFFSET関数で行います。

数式と解説

=OFFSET(A1,SUM((B11>=体重表)*1),SUM((B10>=身長表)*1))

SUM((B11>=体重表)*1): アプローチ2と全く同じ方法で、行方向の移動量(オフセット)「3」を計算します。

SUM((B10>=身長表)*1): 同じく、列方向の移動量「3」を計算します。

OFFSET(A1,3,3): OFFSET関数が、A1セルを基準として、「3行下がり、3列右に移動した」場所にあるセルの値、つまりD4セルの「M」を返します。

Excel説明画像

アプローチ4:LOOKUP + FILTER(合わせ技一本)

考えかた

まず体重の条件で正しい「行」をFILTER関数で抽出し、その行の中から、身長の条件に合う「列」の値をLOOKUP関数で探し出す、という合わせ技です。

数式と解説

=LOOKUP(B10,身長表,FILTER(範囲,体重表=LOOKUP(B11,体重表)))

LOOKUP(B11,体重表): LOOKUP関数は、MATCHの近似一致と似た動きをします。体重「56」を「体重表」{0,40,55,70,85}から探し、56以下で最も大きい値である「55」を返します。

Excel説明画像

FILTER(範囲,体重表=55): 次に、FILTER関数が、「範囲」の中から、「体重表」が「55」である行、つまり3行目にあたる{"S","S","M","L","XL"}だけを抜き出します。

Excel説明画像

LOOKUP(B10,身長表,...): 最後に、身長「161」を「身長表」{0,145,160,175,190}から探します。(見つかるのは160)

・そして、対応する位置にある値を、先ほどフィルターした行配列の中から取り出します。

160は3番目なので、{"S","S","M","L","XL"}の3番目である「M」が返されます。

Excel説明画像

アプローチ5:MAX + INDIRECT(座標からの逆引き)

考えかた

これは完全に趣向を変えた関数パズルです。

まず、条件に合うセルの「絶対的な行番号と列番号」を計算します。

それを元にセル番地の文字列(例: “D4″)を作り、INDIRECT関数で値を参照します。

数式と解説

=INDIRECT("R"&MAX((B11>=体重表)*ROW(範囲))&"C"&MAX((B10>=身長表)*COLUMN(範囲)),FALSE)

MAX((B11>=体重表)*ROW(範囲)): まず(B11>=体重表){TRUE,TRUE,TRUE,FALSE,FALSE}という配列を作ります。

これに「範囲」の実際の行番号{2;3;4;5;6}を掛け合わせると、{2;3;4;0;0}となります。その中の最大値(MAX)である「4」が、目的の行番号となります。

Excel説明画像

MAX((B10>=身長表)*COLUMN(範囲)): 同様に、(B10>=身長表){TRUE,TRUE,TRUE,FALSE,FALSE}という配列を作り、これに「範囲」の実際の列番号{2,3,4,5,6}を掛け合わせると、{2,3,4,0,0}となります。

その最大値である「4」が、目的の列番号となります。

Excel説明画像

INDIRECT("R4C4",FALSE): 計算した行番号と列番号を文字列として連結し、「R4C4」(4行4列目 = D4セル)というR1C1形式のセル番地を作ります。

最後にINDIRECT関数が、この文字列を本物のセル参照に変えて、「M」を返します。

Excel説明画像

アプローチ6:CONCAT(力技の文字列連結)

これは、もはや実用性を完全に無視した、芸術の域の数式です(笑)。

=CONCAT(IF((SUM((B11>=体重表)*1)-1)*5+SUM((B10>=身長表)*1)=SEQUENCE(5,5),範囲,""))

この数式は、一体何をしているのでしょうか?

1. SUM((B11>=体重表)*1): アプローチ2と同じ方法で、体重の位置が「3」番目であることを計算します。

2. SUM((B10>=身長表)*1): 同じく、身長の位置が「3」番目であることを計算します。¥

3. (3-1)*5+3: この計算で、3行3列目が、5×5のマス目の左上から数えて何番目かを特定しています。結果は「13」になります。

Excel説明画像

4. SEQUENCE(5,5): 1から25までの数字が並んだ、5×5の配列を生成します。

Excel説明画像

5. IF(13 = 配列, 範囲, ""): 13番目の位置だけがTRUEになり、そこに対応する「範囲」の値(”M”)だけが残ります。それ以外はすべて空白になります。

Excel説明画像

6. CONCAT(...): 最後にCONCAT関数でこの配列を連結すると、空白は無視され、残った一つの値「M」だけが取り出される、というわけです。

Excel説明画像

VLOOKUP関数で、どうにかできないか!?

「ところで、Excelの検索関数の王様、VLOOKUPは使えないの?」

素晴らしい質問です!

しかし、残念ながら、今の表のままではVLOOKUPを使うのは非常に困難です。

なぜなら、VLOOKUPは「範囲の左端の列」しか検索できないからです。身長のように「上の行」を検索することはできないのです。

HSTACK関数のような新関数を使えば可能だけど、昔からあるVLOOKUP関数とピカピカの新関数を組み合わせるのは、なんだか芸術性に欠けると思いませんか?(笑)」

そこで、諦めるのはまだ早い!表の構造を少しだけ変えてあげれば、VLOOKUPの出番がやってきます!

Excel説明画像

アプローチ7:VLOOKUP + COUNTIF(意外な組み合わせ)

=VLOOKUP(B27,A18:F22,COUNTIF(B17:F17,"<="&B26)+1,TRUE)

VLOOKUP(B27,A18:F22,...,TRUE): まず、VLOOKUPの第4引数をTRUE(近似一致)にして、体重「56」を新しい表のA列から検索します。

これで、正しい「行」(55の行)が特定されます。

Excel説明画像

COUNTIF(B17:F17,"<="&B26)+1: ここがトリック!VLOOKUPの3番目の引数である「列番号」を、COUNTIF関数で動的に計算しています。

身長「161」に対して、見出し行(B17:F17)の中で「161以下の数値」がいくつあるかを数えます。

結果は{0,145,160}の「3」個。これに、A列の分を考慮して1を足し、「4」列目、と指定しているのです!

Excel説明画像

アプローチ8:VLOOKUPネスト(意地のVLOOKUP)

=VLOOKUP(B26,IF({1,0},TRANSPOSE(B17:F17),VLOOKUP(B27,A18:F23,SEQUENCE(5,,2),TRUE)),2,TRUE)

これは、「意地でもVLOOKUPで解決してやる!」という気概が感じられる、超絶技巧の数式です。

VLOOKUP(B27,A18:F23,SEQUENCE(5,,2),TRUE): 内側のVLOOKUPで、まず体重「56」に合う行を特定し、SEQUENCE関数を使ってその行のサイズ5つ{"S","S","M","L","XL"}を配列として一気に取り出します。

Excel説明画像

TRANSPOSE(B17:F17): 身長の見出し行を、TRANSPOSE関数で縦一列の配列に変換します。

Excel説明画像

IF({1,0}, ...): IF({1,0}, …)というテクニックで、先ほど作った2つの配列をメモリ上で無理やり合体させ、左に身長、右にサイズの2列表を仮想的に作り出します。

Excel説明画像

VLOOKUP(B26, ..., 2, TRUE): 最後に、外側のVLOOKUPが、この仮想の表に対して身長「161」を近似一致で検索し、2列目の正しいサイズ「M」を返すのです。

Excel説明画像

IF({1,0}, …)というテクニックを使うと、VLOOKUP関数で左側のデータも取得できます。以下の記事で紹介しています。

まとめ:最強の技は「分かりやすさ」

○以上○未満」という一つのゴールに対して、8つもの異なるアプローチで立ち向かってみました。

実務で使うなら、間違いなくアプローチ1の「INDEX + MATCH」が最強です。

しかし、他の関数パズルたちも、Excelの近似一致のロジックや配列計算の仕組みを、より深く理解するための最高のトレーニングになります。

この知識は、いつかあなたがもっと複雑な問題に直面したとき、きっと新しい解決策への扉を開いてくれるはずですよ!

今回登場した関数リスト

  • INDEX(配列, 行番号, [列番号]): 配列の中から、指定した行と列の位置にある値を返します。
  • MATCH(検索値, 検査範囲, [照合の種類]): 照合の種類に「1」を指定すると近似一致になります。
  • SUM(数値1, [数値2], …): 数値を合計します。配列計算の要としても活躍します。
  • OFFSET(参照, 行数, 列数, [高さ], [幅]): 基準セルから指定した行数・列数だけずれた位置にあるセル範囲への参照を返します。
  • LOOKUP(検索値, 検査ベクトル, [対応ベクトル]): 1行または1列の範囲から値を検索します。
  • FILTER(配列, 含む, [空の場合]): 指定した条件に基づいて、配列をフィルター処理します。
  • INDIRECT(参照文字列, [参照形式]): 文字列をセル参照に変換します。
  • MAX(数値1, [数値2], …): 引数リストの中の最大値を返します。
  • ROW / COLUMN([参照]): セルの行/列番号を返します。
  • CONCAT(文字列1, [文字列2], …): 複数の文字列を一つに連結します。
  • SEQUENCE(行数, [列数], [開始], [ステップ]): 連続した数値の配列を生成します。
  • VLOOKUP(検索値, 範囲, 列番号, [検索方法]): 表の左端の列を検索し、同じ行の指定した列の値を返します。[検索方法]にTRUEを指定すると近似一致になります。
  • COUNTIF(範囲, 検索条件): 指定された範囲内で、検索条件に一致するセルの個数を返します。
  • TRANSPOSE(配列): 配列の行と列を入れ替えます。
タイトルとURLをコピーしました