doodle-on-web

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

列追加でも数式が壊れない|INDEX+MATCHを動的列指定に書き換える4つの方法【旧バージョンからExcel 365まで全対応】

スポンサーリンク


はじめに:「列を追加したら数式が全滅した」を二度と繰り返さない

VLOOKUPやINDEX+MATCHをある程度使いこなしていても、こんな経験はないでしょうか。

「列を1つ追加したら、数式の列番号が全部ズレて修正に1時間かかった…」

列番号を 35 と直接入力(ハードコーディング)している限り、この問題は避けられません。

この記事を読み終えると、列を追加・削除しても一切手を加えなくてよい数式が書けるようになります。 旧バージョンのExcelから最新のExcel 365まで使える方法を段階的に解説するので、どの環境の方でも実践できます。


前提:サンプルデータと問題の確認

以下のような社員テーブルを例に使います。

A B C D
社員ID 氏名 部署 給与
E001 田中太郎 営業部 350,000
E002 鈴木花子 総務部 280,000
E003 佐藤次郎 開発部 420,000

よくある数式はこうです。

=INDEX(A:D, MATCH(E2, A:A, 0), 3)

この 3(部署列)が問題です。仮に「電話番号」列をC列に追加すると、部署はD列にズレるため、数式の 34 に手動修正しなければなりません。列が多いほど、修正漏れのリスクも増大します。


4つの方法を選ぶ基準

各方法に入る前に、選択の目安を示します。

状況 選ぶ方法
旧バージョン(2016以前)を使っている 方法① INDEX + MATCH(二重)
Excel 365/2019でシンプルに書きたい 方法② INDEX + XMATCH
直感的な書き方にしたい 方法③ XLOOKUP
複数列を一括で取得したい 方法④ XLOOKUP + CHOOSECOLS

方法①:MATCH で列番号を動的取得する【旧バージョン対応】

こんな場合に使う: Excel 2016以前の環境や、職場共有ファイルでバージョンを選ばず動かしたいとき。

ヘッダー行を活用し、MATCH関数を2つ重ねます。

=INDEX(A:D, MATCH(E2, A:A, 0), MATCH(F1, A1:D1, 0))
  • E2:検索したい社員ID(例:E001)
  • F1:取得したい列名(例:「給与」と入力)

動作のポイント:

  • MATCH(E2, A:A, 0) → 社員IDが何行目にあるか返す
  • MATCH(F1, A1:D1, 0) → 「給与」がヘッダー行の何列目にあるか返す
  • F1を「部署」に変えれば部署を、「氏名」に変えれば氏名を自動参照

列を追加しても、ヘッダー行のMATCHが自動で列番号を再計算するため、数式の修正は一切不要です。


方法②:XMATCH でさらに堅牢に【Excel 365/2019以降】

こんな場合に使う: Excel 365または2019以降を使っており、コードをよりシンプル・厳密に書きたいとき。

=INDEX(A:D, XMATCH(E2, A:A), XMATCH(F1, A1:D1))

MATCHとXMATCHの主な違い

機能 MATCH XMATCH
デフォルトの一致モード 要指定(0) 完全一致がデフォルト
逆順(末尾から)検索 不可 -1 で指定可
見つからない場合の戻り値 IFERRORが必要 第4引数で指定可

重複データがある場合の最新レコード取得:

=INDEX(A:D, XMATCH(E2, A:A, 0, -1), XMATCH(F1, A1:D1))

-1 を指定すると末尾から検索するため、同じ社員IDが複数行ある場合でも最新データを返します。


方法③:XLOOKUP で直感的に書く【Excel 365以降】

こんな場合に使う: 数式の構造をシンプルに保ちたい、VLOOKUPに近い感覚で書きたいとき。

=XLOOKUP(E2, A:A, INDEX(A:D, 0, XMATCH(F1, A1:D1)))

INDEX(A:D, 0, 列番号) のポイント: 行番号に 0 を指定すると、その列全体を返します。これをXLOOKUPの「戻り範囲」として渡すことで、参照列を動的に切り替えられます。


方法④:CHOOSECOLS で複数列を一括取得【Excel 365以降・スピル対応】

こんな場合に使う: 1つの数式で複数列のデータをまとめて取り出したいとき。

まず CHOOSECOLS の基本を押さえましょう。

=CHOOSECOLS(A:D, 1, 3, 4)

これで「A列・C列・D列」だけを抽出した仮想テーブルが生成されます。

XLOOKUPと組み合わせて複数列を返す

=XLOOKUP(E2, A:A, CHOOSECOLS(A:D, MATCH({"氏名","給与"}, A1:D1, 0)))

実行結果のイメージ(スピル表示):

田中太郎  |  350,000

{"氏名","給与"} のように配列で列名を渡すと、対応する列番号がまとめて計算され、1つのセルに入力するだけで横方向に結果が展開されます。従来なら列ごとに数式を用意していた作業が、これ1本で完結します。


実践例:ドロップダウン連動ダッシュボード

ここまでの技術を組み合わせると、実務で使えるセルフサービス型ダッシュボードが作れます。

設定セル: - G1:検索したい社員ID(手入力) - G2:表示したい列名(データ入力規則でドロップダウンリストを設定)

出力セル H1:

=IFERROR(
  INDEX($A:$D,
    XMATCH($G$1, $A:$A),
    XMATCH($G$2, $A$1:$D$1)
  ),
  "該当なし"
)

G2のドロップダウンで「氏名」「部署」「給与」を切り替えるだけで、H1の表示が自動更新されます。データ管理者でなくても誰でも使えるため、集計依頼の削減や入力ミスの防止に直結します。


よくあるエラーと対処法

#N/A が出る場合

  • 検索値の前後にスペースが混入していないか確認 → TRIM(E2) で除去
  • 数値と文字列の型不一致 → セルの書式と実際のデータ型を確認

#REF! が出る場合

  • CHOOSECOLS/INDEXで範囲外の列番号を指定していないか確認
  • XMATCHが一致しなかった場合の戻り値を明示する
=XMATCH(F1, A1:D1, 0, 0)  ' 見つからない場合は0を返す(エラー回避)

今日から使えるアクションステップ

記事の内容を実践に移すための3ステップです。

  1. 既存シートの INDEX(..., ..., 3) を探す → 列番号が直書きになっている数式を特定する
  2. 列番号を MATCH(見出し名, ヘッダー行, 0) に置き換える → まず方法①を試す
  3. Excel 365環境なら XMATCH に切り替える → エラー処理も引数で完結させ、数式をすっきりさせる

小さな修正でも、積み重ねることでメンテナンスコストは大幅に下がります。まず1つの数式から試してみてください。


まとめ

列番号をハードコーディングする習慣を手放すと、「列を追加するたびに数式を直す」という作業から解放されます。

  • 旧バージョンなら INDEX + MATCH の二重使いが最も汎用的
  • Excel 365/2019なら XMATCH でより厳密に、XLOOKUPでよりシンプルに
  • 複数列をまとめて返したいなら CHOOSECOLS との組み合わせが最強

次回は「複数条件での縦横クロス検索」を解説します。INDEXとXMATCHを使って、行・列ともに動的に指定する応用テクニックを紹介予定です。ぜひブックマークしておいてください。