ExcelのINDIRECT関数を使ってみて、壁にぶつかったことはありませんか。「なぜか#REF!エラーが消えない」「ファイルが急に重くなった」という悩みは、よく聞く声です。
INDIRECT関数は「文字列をセル参照に変える」便利な関数です。一方で、別シート参照のクォートの書き方や、揮発性(再計算が頻繁に走る性質)の重さを知らないと、思わぬトラブルにつながります。
この記事では、INDIRECT関数の基本から別シート参照の正確なルール、#REF!エラーの状況別対処までを解説します。さらに、INDEXへの乗り換え判断もまとめて紹介します。「正しく動かす」と「使うべき場面を見極める」の両方が一度でわかる内容です。
INDIRECT関数とは?
ExcelのINDIRECT関数は、文字列をセル参照に変換する関数です。ふつうの数式では =A1 のように参照先を直接書きます。INDIRECT関数を使うと、「A1」という文字列を渡すだけでセルA1の値を取得できます。
ポイントは、参照先を「文字列で」コントロールできることです。セルの値やドロップダウンの選択内容に応じて、参照先をその場で切り替えられます。
たとえばセルA1に「B2」という文字が入っているとします。=INDIRECT(A1) と書くと、INDIRECT関数はこの文字を読み取ってセルB2を参照します。A1の中身を「C5」に変えれば、数式はそのままで参照先がC5に切り替わります。
読み方・語源
読み方は「インダイレクト」です。英語の「indirect」は「間接的な」という意味です。
セルを直接指さすのではなく、文字列を経由して間接的に参照することから、この名前がついています。この「間接性」が便利さの源であり、同時にエラーや重さの原因にもなります。
INDIRECT関数でできること
INDIRECT関数を使うと、次のようなことが実現できます。
- セル番地を文字列で指定して、参照先を動的に切り替える
- 別シートのデータを、シート名の文字列で参照する
- ドロップダウンの選択に連動して、表示内容を変える
- VLOOKUP関数の検索範囲を、シートごとに切り替える
どれも「参照先を動的に変えたい」場面で役立つ使い方です。順番に見ていきましょう。
なお、Googleスプレッドシートにも同じINDIRECT関数があります。構文はExcelとほぼ同じです。Sheetsでの使い方はスプレッドシートのINDIRECT関数の使い方で解説しています。
基本構文と引数
INDIRECT関数の構文は次のとおりです。
=INDIRECT(参照文字列, [参照形式])
第1引数の「参照文字列」だけを指定すれば動きます。第2引数の「参照形式」は省略可能です。それぞれの引数の意味は次の表のとおりです。
| 引数 | 必須/省略可 | 説明 |
|---|---|---|
| 参照文字列 | 必須 | セル参照を表すテキスト文字列。セル番地・範囲・定義された名前を指定できる |
| 参照形式 | 省略可 | TRUE(省略時のデフォルト)= A1形式で解釈。FALSE = R1C1形式で解釈 |
第2引数の「参照形式」は、ほとんどの場面でTRUE(A1形式)を使います。R1C1形式を扱うケースはまれです。基本的には省略してかまいません。
ここで「参照文字列」とは、「B2」や「Sheet1!A1」のような、セルの場所を表す文字のことです。INDIRECT関数はこの文字を読み取り、本物のセル参照として扱います。
最小サンプルで動きを確認する
一番シンプルな例を見てみましょう。セルA1に「B」という文字を入れておきます。そのうえで次の数式を入力します。
=INDIRECT(A1&"2")
A1&"2" の部分で「B」と「2」がつながり、「B2」という文字列ができます。INDIRECT関数がこれをセル参照と解釈し、セルB2の値を返します。
文字列を直接指定することもできます。
=INDIRECT("B2")
この場合は常にB2を参照します。ただし切り替える必要がないなら、ふつうに =B2 と書くほうがシンプルです。INDIRECTの価値は「参照先を変えられること」にあります。
別シート参照の書き方
INDIRECT関数が本領を発揮するのは、別シートの参照です。ここはエラーが起きやすいポイントなので、シングルクォートのルールを正確に押さえましょう。
基本パターン(スペースなしのシート名)
シート名に空白や記号が含まれない場合は、シンプルに書けます。セルA1にシート名が入っている前提で見てみましょう。
=INDIRECT(A1&"!B2")
A1に「1月」と入力されていれば、A1&"!B2" が「1月!B2」という文字列になります。そのまま「1月」シートのB2セルを参照できます。
A1の値を「2月」に変えれば、参照先も「2月」シートのB2に切り替わります。月別シートの集計などで重宝するパターンです。
シート名にスペース・記号がある場合(シングルクォート必須)
ここが最大の落とし穴です。シート名にスペースやハイフン、記号が含まれる場合、シングルクォーテーション(')で囲まないと#REF!エラーになります。
たとえばシート名が「売上 データ」のように空白を含むとします。この場合は次のように書きます。
=INDIRECT("'"&A1&"'!B2")
少し複雑に見えるので、分解して確認しましょう。
"'"… 開きのシングルクォート1文字A1… シート名(例:「売上 データ」)"'!B2"… 閉じのシングルクォートと、セル番地
これらがつながると、'売上 データ'!B2 という文字列になります。Excelの正式なシート参照の形と一致するため、正しく参照できます。
手入力でシート参照を書いたとき、Excelが自動で '売上 データ'!B2 のようにクォートを付ける挙動と同じです。INDIRECTでは自動で付かないので、自分で組み込む必要があります。
実務ではスペース入りのシート名も少なくありません。迷ったらクォート付きの書き方を使うのが安全です。スペースのないシート名にクォートを付けても問題なく動きます。
よくある書き間違いと確認方法
別シート参照でつまずいたら、まず「文字列が正しく組み立てられているか」を確認します。確認には、INDIRECTを外して文字列だけを表示させる方法が有効です。
="'"&A1&"'!B2"
この数式をどこかの空きセルに入れると、INDIRECTが受け取る文字列がそのまま表示されます。表示結果が '売上 データ'!B2 のような正しい形になっているかを目で確認できます。
ここで 売上 データ'!B2(先頭のクォート抜け)のように崩れていれば、数式の "'" の部分が抜けています。文字列さえ正しければ、INDIRECTは必ず正しく参照します。
実務で使えるINDIRECT関数の活用パターン
連動ドロップダウン(名前の定義を使う)
INDIRECT関数の代表的な使い方が連動ドロップダウンです。1つ目のドロップダウンで選んだ値に応じて、2つ目の選択肢が自動で切り替わります。
たとえば1つ目で「果物」を選ぶと、2つ目に「リンゴ・ミカン・バナナ」が表示されます。「野菜」に変えると別の選択肢に切り替わる、というイメージです。手順を順に見ていきましょう。
ステップ1: 選択肢のデータを用意する
カテゴリごとの選択肢を、シートに縦方向で並べておきます。
ステップ2: 名前の定義を登録する
選択肢の範囲を選びます。次に「数式」タブの「名前の定義」を開きます。ここで範囲に名前を付けます。
ポイントは、名前をカテゴリ名と一致させることです。
- 「リンゴ・ミカン・バナナ」の範囲 → 名前:果物
- 「ニンジン・キャベツ・トマト」の範囲 → 名前:野菜
名前の定義の登録手順はExcelの「名前の定義」完全ガイドで詳しく解説しています。
ステップ3: 第1ドロップダウンを設定する
B2セルを選びます。「データの入力規則」を開きます。ソースに「果物,野菜」とカンマ区切りで入力します。
ステップ4: 第2ドロップダウンにINDIRECTを設定する
C2セルを選びます。「データの入力規則」を開きます。ソースに次の数式を入力します。
=INDIRECT(B2)
B2で「果物」を選ぶと、INDIRECT関数が「果物」という文字列を名前の定義として解釈します。結果として、名前「果物」に登録された範囲がドロップダウンの選択肢になります。
なお、名前の定義にはスペースが使えません。カテゴリ名に空白が入る場合は、名前側をアンダースコアにします。そのうえで次のように対処するのが実務での定番です。
=INDIRECT(SUBSTITUTE(B2," ","_"))
これはB2の空白をアンダースコアに置き換えてから名前を呼び出すTipsです。連動ドロップダウンの作り方そのものはExcelの入力規則(プルダウン)完全ガイドも合わせて参考にしてください。
別シートをドロップダウンで動的に切り替える
「東京」「大阪」「名古屋」など、支店ごとにシートが分かれている場合を考えます。集計シートにドロップダウンを置きます。選択した支店のデータを自動で表示させる方法です。
A1セルで支店名を選べるようにします。データを取得したいセルに次のように入力します。
=INDIRECT(A1&"!B2")
A1で「東京」を選べば東京シートのB2が表示されます。「大阪」を選べば大阪シートのB2に切り替わります。
SUM関数と組み合わせれば、範囲集計も動的に切り替えられます。
=SUM(INDIRECT(A1&"!B2:B10"))
シートをまたいだ切り替えがドロップダウン1つで完結します。レポート作成がぐっとラクになります。支店名にスペースが入る場合は、前述のクォート付きの書き方を使ってください。
VLOOKUPの検索範囲をシートごとに切り替える
VLOOKUP関数の検索範囲を、INDIRECTで動的に指定するテクニックです。部署ごとにシートが分かれている場面で便利です。
=VLOOKUP(A2,INDIRECT(B1&"!A:C"),2,0)
B1セルにシート名(部署名)を入れておきます。同じ数式のまま、検索対象のシートを切り替えられます。
VLOOKUPとINDEX+MATCHの使い分けに迷ったら、VLOOKUP・XLOOKUP・INDEX MATCH使い分けガイドを参考にしてください。なお、Excel 365ならXLOOKUP関数とINDIRECTを組み合わせても同じことができます。
ADDRESS関数との組み合わせ
ADDRESS関数は、行番号と列番号からセル番地の文字列を生成します。これをINDIRECT関数に渡すと、行と列の両方を数値でコントロールできます。
=INDIRECT(ADDRESS(B1,C1))
B1に行番号(例:3)、C1に列番号(例:2)を入れます。ADDRESS関数が「$B$3」という文字列を生成します。INDIRECT関数がこれをセル参照に変換し、B3の値を返します。
ただし、ここまで複雑になるならINDEX関数のほうがシンプルです。後の章で、この置き換えを詳しく見ていきます。
#REF!エラー状況別フローと対処法
INDIRECT関数のエラーは、ほとんどが#REF!です。原因は1つではありません。状況ごとに対処が違うので、Q&A形式で4つの分岐を整理します。
まず、自分のエラーがどの状況に当てはまるかを次の順で確認してください。
- 別シートを参照していて、シート名にスペース・記号があるか → 状況1
- 参照文字列に余分なスペースが混ざっていないか → 状況2
- 外部の別ブックを参照していて、そのブックを閉じていないか → 状況3
- 名前の定義を参照していて、その名前が登録済みか → 状況4
状況1: シート名にスペースがある(クォート漏れ)
最も多い原因が、シングルクォートの付け忘れです。シート名にスペースやハイフン、記号が含まれると、クォートなしでは#REF!になります。
たとえば次の書き方は、シート名が「売上 データ」だと失敗します。
=INDIRECT(A1&"!B2")
クォートを付けた次の形に直してください。
=INDIRECT("'"&A1&"'!B2")
判断に迷う場合は、シート名に関係なく常にクォート付きで書くのがおすすめです。スペースのないシート名でも、クォート付きで問題なく動きます。
状況2: 参照文字列に余分なスペース(TRIM処理)
シート名やセルの値に、目に見えない余分なスペースが混ざっているケースです。ほかのシステムからコピーしたデータでよく起こります。
「東京」のつもりが「東京 」(末尾に空白)になっていると、シート名が一致せず#REF!になります。この場合はTRIM関数で前後の空白を取り除きます。
=INDIRECT(TRIM(A1)&"!B2")
TRIM関数は文字列の前後の空白を削除します。スペースが原因かどうかを切り分けるには、=LEN(A1) で文字数を数えてみてください。想定より多ければ、余分な空白が混ざっています。
状況3: 外部ブックが閉じている(キャッシュ不可の仕様)
INDIRECT関数で別のExcelブックを参照する場合、参照先のブックを開いておく必要があります。ブックを閉じると#REF!になります。
これは仕様です。ふつうのセル参照(=[Book1.xlsx]Sheet1!A1)なら、ブックを閉じていてもキャッシュ(保存済みの値)が表示されます。一方、INDIRECT関数は毎回文字列を評価して参照を組み立て直します。そのためキャッシュが効きません。
対処は2つです。参照先のブックを開いたまま使うか、別ブック参照をやめてふつうのリンク数式に切り替えるかです。なお、Excel Online(ブラウザ版)では、そもそも外部ブック参照に対応していません。
状況4: 名前の定義が未登録・スペルミス
連動ドロップダウンなどで名前の定義を参照しているのに、その名前が登録されていないケースです。=INDIRECT(B2) でB2が「果物」でも、名前「果物」が未登録なら#REF!になります。
確認手順は次のとおりです。「数式」タブの「名前の管理」を開きます。一覧に該当の名前があるかを確かめます。
スペルや表記ゆれ(全角・半角の違いなど)にも注意してください。エラーを事前に防ぎたい場合は、ISREF関数で参照の有効性を判定できます。
=ISREF(INDIRECT(B2))
参照が有効ならTRUE、無効ならFALSEを返します。IFERROR関数と組み合わせて、エラー時に空白や代替文字を表示するのも有効です。
揮発性の重さとINDEX置換パターン
INDIRECT関数の「重さ」に悩んでいる方も多いはずです。原因は揮発性にあります。ここでは仕組みと、INDEXへの具体的な置き換え方法を解説します。
揮発性関数とは何か・再計算の仕組み
INDIRECT関数は揮発性関数(Volatile Function)です。揮発性関数とは、シート内のどこかのセルが変わるたびに、自分も毎回再計算される関数のことです。
通常の関数は、自分が参照しているセルが変わったときだけ再計算されます。一方、揮発性関数は無関係なセルの変更でも再計算が走ります。同じ仲間には、TODAY関数・NOW関数・RAND関数・OFFSET関数などがあります。
問題は、再計算が連鎖することです。INDIRECTを参照している重い関数(VLOOKUPやSUMIFなど)も、つられて毎回計算し直されます。数個なら影響はありません。しかし数百から数千セルで使うと、ファイルを開くたび・セルを編集するたびに処理が重くなります。
INDEXに置き換えられるパターン・できないパターン早見表
重さを解消する王道が、非揮発性のINDEX関数への置き換えです。INDEXは参照先のデータが実際に変わったときだけ再計算されます。
ただし、すべてのINDIRECTがINDEXに置き換えられるわけではありません。代表的な3パターンの可否を整理します。
| 元のINDIRECT | 置換可否 | 置換後(INDEX等) |
|---|---|---|
INDIRECT(ADDRESS(3,2)) | 置換可 | INDEX(A:Z,3,2) |
INDIRECT("B"&A1) | 置換可 | INDEX(B:B,A1) |
INDIRECT(A1&"!B2") | 置換不可 | INDIRECTが唯一の手段 |
1つ目は、行・列を数値で指定するパターンです。ADDRESS(3,2) は「$B$3」を作るので、参照先はB3です。INDEX(A:Z,3,2) も範囲A:Zの3行2列目、つまりB3を返します。戻り値は同じで、揮発性だけが消えます。
2つ目は、列を固定して行だけ可変にするパターンです。A1が「5」なら、INDIRECT("B"&A1) は「B5」を参照します。INDEX(B:B,A1) も列Bの5番目、つまりB5を返します。こちらも結果は一致します。
3つ目の別シートを動的に切り替えるパターンは置換できません。INDEXはシート名を文字列で受け取れないからです。連動ドロップダウンの =INDIRECT(B2)(名前を動的に呼ぶ形)も同様で、INDIRECTが唯一の選択肢です。
パフォーマンス改善の判断基準
置き換えるかどうかの判断は、次の基準で考えると迷いません。
- 参照先を行番号・列番号の数値で決められる → INDEXに置き換える(軽量化できる)
- 参照先をシート名や名前(文字列)で決めている → INDIRECTのまま使う
つまり「数値で参照先が決まるか」「文字列で決めたいか」が分かれ目です。文字列ベースの動的参照は、INDIRECTにしかできない仕事です。ここは無理に置き換えず、使う個数を抑える方向で対処します。
実務では、すべてを置き換える必要はありません。同じ計算を数百セルで繰り返している箇所だけINDEXに直せば、体感速度は大きく改善します。
スピル時代(Excel 365)のINDIRECTの位置づけ
Excel 365では、FILTER・UNIQUE・XLOOKUPといったスピル関数(1つの数式で複数セルに結果が自動展開される関数)が使えます。「これがあればINDIRECTは不要では?」と感じる方もいるでしょう。結論から言うと、用途次第です。
同一シート内の条件絞り込みは、FILTER関数のほうがシンプルです。たとえば「同じシートの一覧から、特定カテゴリだけ抜き出す」用途を考えます。従来はINDIRECTや作業列を駆使していました。Excel 365なら、FILTERで1行書くだけで動的に絞り込めます。再計算の重さもなく、可読性も高くなります。同じシート内でデータを引きたいだけなら、まずスピル関数を検討してください。
一方、シート名そのものを動的に切り替える用途は、スピル関数では代替できません。次のような場面です。
- 連動ドロップダウン(選択値から名前の定義を呼ぶ)
- 月別・支店別シートを、選択に応じて切り替える集計
FILTERが扱えるのは、あくまで「指定した範囲の中の絞り込み」です。「どのシートを見るか」を文字列で切り替える芸当はできません。ここはExcel 365でもINDIRECTの独壇場です。つまりExcel 365では、同一シート内の絞り込みはスピル関数、シート横断の動的参照はINDIRECTという役割分担になります。両者は競合せず、補い合う関係です。
まとめ・使い分け早見表
INDIRECT関数は、文字列をセル参照に変換する関数です。便利な反面、別シート参照のクォートと揮発性の重さに注意が必要でした。最後に要点を整理します。
| 場面 | 結論 |
|---|---|
| 別シート参照(スペースなし) | =INDIRECT(A1&"!B2") で参照できる |
| 別シート参照(スペースあり) | =INDIRECT("'"&A1&"'!B2") とクォートで囲む |
| #REF!が出た | クォート漏れ・余分なスペース・閉じたブック・名前未登録の4点を順に確認 |
| 数値で参照先が決まる | INDEX関数に置き換えて軽量化 |
| 文字列で参照先を切り替える | INDIRECTが唯一の選択肢 |
| Excel 365で同一シート内を絞り込む | FILTERなどスピル関数を優先 |
迷ったときの判断はシンプルです。「シート名や名前を文字列で動的に切り替えたい」ならINDIRECT、「行番号・列番号で参照先が決まる」ならINDEXを選んでください。
揮発性による重さが気になったら、置換可能なパターンだけをINDEXに直すと効果的です。まずは別シート参照と連動ドロップダウンから試してみてください。Googleスプレッドシートでも使いたい方は、スプレッドシートのINDIRECT関数の使い方も参考にしてください。

