Excel。INDIRECT関数で文字列で参照されるセルの値を返せます
<関数辞典:INDIRECT関数>
INDIRECT関数
読み方: インダイレクト
分類: 検索/行列
INDIRECT(参照文字列,[参照形式])
文字列で参照されるセルの値を算出します
【Excel・Word・PowerPoint・Access】あなたの「困った」を解決!10年以上の経験が詰まった、現場の疑問から生まれた実践テクニック集。作業効率を劇的に上げるOffice活用術をお届けします。
INDIRECT関数
読み方: インダイレクト
分類: 検索/行列
INDIRECT(参照文字列,[参照形式])
文字列で参照されるセルの値を算出します
会員と一般で、単価が異なる表から、会員なら会員の、一般なら一般の単価を抽出し表示したい場合、どのようにしたらいいのでしょうか。
次の表をつかって説明します。
一般なので、D2の単価は、100と表引きされています。
A2の値を会員にすれば、D2の単価は80となるようにしたいわけです。
このような場合、VLOOKUP関数をつかうといいように思えますが、うまくいきません。
C2の商品名は、VLOOKUP関数で対応することは、できます。
C2の数式は、
=VLOOKUP(B2,A6:D7,2,FALSE)
VLOOKUP関数の最初の引数、検索値は、B2
2つ目の引数は、範囲なので、A6:D7 と設定します。
3つ目の引数は、列番号です。
2つ目の引数で設定した範囲の左から何列目のデータを表示するのかということなので、左から「2」列目なので、2と設定します。
最後の引数の、検索方法は、完全一致ですから、FALSE。
商品名は、VLOOKUP関数でもいいのですが、問題は、列番号です。
会員ならば、3。一般なら4としなければなりません。
このような場合、
=VLOOKUP(B2,A6:D7,IF(A2="会員",3,4),FALSE)
と列番号を判断させるようにIF関数をつかってもいいと思います。
ただし、所属数が会員・準会員・一般・学生のように、増えた場合、IF関数では対応するのが大変になるので、多分岐できる関数を使う必要がでてきます。
また、所属、それぞれの表をつくって、INDIRECT関数をつかって対応する方法があります。
ただ、その方法では、別表を作る必要がありますので、面倒です。
そこで、INDIRECT関数はつかうのですが、VLOOKUP関数よりもXLOOKUP関数で対応する方法があります。
事前に「名前の定義」を設定します。
C6:C7に、「会員」
D6:D7に、「一般」
と名前を設定しました。
=XLOOKUP(B2,A6:A7,INDIRECT(A2),"",0,1)
A2の所属を変更しても、会員と一般、それぞれの数値を表引きしてくれます。
もし、所属数が増えても、名前の定義を増やすだけで、数式を変更する必要はありません。
では、
=XLOOKUP(B2,A6:A7,INDIRECT(A2),"",0,1)
XLOOKUP関数の数式を確認します。
最初の引数は、検索値 なので、B2を設定します。
2つ目の引数は、検索範囲。
検索値が所属されている範囲なので、A6:A7。
3つ目の引数は、戻り範囲。
表示したい範囲です。
ここに、会員なのか、一般なのかで、戻り範囲を対応させたい。
そこで、INDIRECT関数をつかうことで、戻り範囲を変更させています。
INDIRECT関数は、値そのものをつかうことができます。
名前の定義で、会員と一般を設定していますので、切り替えることができるというわけです。
4つ目の引数は、見つからない場合。
見つからない時は「””(ダブルコーテーション×2)」で空白と設定します。
5つ目の引数は、一致モードなので、0の完全一致にしました。
6つ目の引数は、検索モード。
先頭から検索させますので、1と設定します。
このように、XLOOKUP関数とINDIRECT関数を組み合わせることで、値を検索して、複数の列から対応する結果を抽出することができます。
リストから該当するデータを抽出することができる、VLOOKUP関数。
このリストの選択先が複数ある場合、どのようにしたら、手早く抽出することができるのでしょうか。
C2の数式は、
=VLOOKUP(B2,INDIRECT(A2),2,FALSE)
どのような仕組みなのか説明していきます。
A2に、「校庭」「体育館」を入力します。会場番号を入力すると、「校庭」の3番である「陸上」が抽出されるという仕組みです。
この数式を作る場合には、事前に引数の範囲に該当するところに、名前の定義を使って「名前」を設定します。
A5:B7には、「校庭」という名前を設定してあります。
D5:E7には、「体育館」という名前を設定してあります。
あとは、VLOOKUP関数を設定していきます。
最初の引数の検索値には、「B2」を設定します。
2つ目の引数の範囲ですが、ここが2か所あるわけです。
そこで、名前の定義を指定してあげれば、その範囲の検索値からデータを抽出してくれるわけですが、検索する範囲を変更するたびに、数式を変更するのは大変です。
そこで、INDIRECT関数をつかうことで、範囲に、名前の定義で設定した名前を指定することができます。
なので2つ目の引数は、「INDIRECT(A2)」と設定します。
これで、A2に、「校庭」と入力されれば、名前の定義で設定した「校庭」の範囲を選んでくれます。
3つ目の引数の列番号には、「2」。
2つ目の引数で選択した範囲の左から2列目に、抽出したい列がありますので、「2」と設定するわけですね。
最後の引数の検索方法は、「FALSE」。
完全一致で抽出しますので、「FALSE」または、「0」と設定します。
Excelでは、FALSE=0なので、「0」と設定しても大丈夫です。
これで、A2の値を校庭・体育館と切り替えれば、それぞれの範囲から該当するデータを抽出することができます。
このように、VLOOKUP関数は、アイディアを追加することで、様々なビジネスシーンでさらに使えるようになりますので、色々試してみるといいかもしれませんね。
なお、あとプラスするとしたら、A列に入力規則のリストをつかうと、「校庭」「体育館」を選択して選ぶことができますので、おすすめの機能ですね。
集計シートなど、シートごとの値をまとめるシートを作るときに、シート名を含めたセル参照は簡単ですが、面倒な作業といえます。
例えば、次のようなファイルをつかって説明していきます。
B2には、11月1日のシートの値をセル参照させています。
11月1日のシートは、次のようになっています。
つまり、各シートのB4に売上高の合計値があるというわけです。
これを集計シートにまとめた、一覧表を作成したいのが目的です。
では、B2に数式を作って、オートフィルで数式をコピーしてみます。
='11月1日'!B4
として問題は無いのですが、これをオートフィルで数式をコピーしたら、「0(ゼロ)」と算出されてしまいました。
原因は、
B3をクリックすればすぐにわかります。
数式が、
='11月1日'!B5
となっています。
当然ですが、オートフィルで数式をコピーしても、シート名が連動して変わってくれることはありません。
セル番地のB4がB5になっただけです。
これでは、オートフィルで数式をコピーことはできないので、1シートずつ、セル参照で数式を作らないといけないわけで、3日程度ならば、パワープレイでも、いいかもしれませんが、30日分となれば、30回同じ作業を繰り返すのは、面倒でしかありません。
シート名を修正するとしても、シート数が増えれば、これまた面倒な作業でしかありません。
かといって、Excel VBAでつくるとしても、シート間を操作しなければならず、プログラム文が多くなりそうです。
そこで、「INDIRECT関数」をつかった数式をつくることで、オートフィルで数式をコピーすることができます。
そこで、INDIRECT関数をつかった数式に変更していきます。
=INDIRECT(TEXT(A2,"m月d日")&"!b4")
という数式を設定しました。
オートフィルで数式をコピーすると、今度は、希望通りの値を表示することができました。
数式自体も、長くないこともあり、手早く、簡単に処理することができます。
使用しているINDIRECT関数は、文字列をそのまま数式などで使うことができる関数です。
INDIRECT関数の引数にTEXT関数をネストしています。
このTEXT関数をつかっている理由は、シート名が日付だからです。
INDIRECT関数で日付を参照させると、シリアル値になってしまうので、「11月1日」という文字で使用することができません。
そこで、TEXT関数で表示形式を「月日」に変更することで「11月1日」という文字としてつかえるようになります。
数式にシート名が含まれると、修正などの作業も面倒になることがありますので、アイディアが必要になることがあります。
月ごとに集計されているシートがあります。
今回のケースは、サンプルなので、2枚のシートですんでいますが、年間となれば12枚のシートですし、もっと多くのシートからデータをコピーする必要があるとすれば、面倒な作業となってきます。
Excel VBAでプログラムをつくってもいいのですが、数式レベルで、効率よくコピーする方法はないのでしょうか?
このような場合、どのようなパターンがあるのか、ないのかを見つけるところから考えていくといいですね。
集計先のシートのB2に、セル参照の数式を設定してみましょう。
となっています。
横方向に、オートフィルで数式をコピーすれば、
='1月'!C5
='1月'!D5
と、横方向は、うまく参照結果が表示されていますが、縦方向にオートフィルで数式をコピーしても、当たり前ですが、うまくいきません。
理由は、シート名が違うからです。
シート名を変更する”だけ”かもしれませんが、とても面倒な作業です。
よくみると、シート名と、A列のデータが同じになっています。
シート名をA列に入力されている値そのものを使うことができれば、上手くいきそうです。
そこで、登場するのが、「INDIRECT関数」です。
B2にINDIRECT関数をつかって、次のような数式に変更してみましょう。
=INDIRECT($A2&"!b5")
この関数は、
='1月'!B5
という数式をどうやったらつくれるのかをイメージして作る関数です。
A2に1月という文字があるので、それをつかいたいわけです。
オートフィルで数式をコピーすることを前提としていますので、列固定の複合参照にしています。
そして、「&(アンパサンド)」で「"!b5"」という文字を結合させています。
縦方向に、オートフィルで数式をコピーすると、きちんと参照してくれたのですが、横方向にオートフィルで数式をコピーしたら、うまくいきません。
原因は、「"!b5"」。
文字になってしまっているので、オートフィルで数式をコピーしても「b」が「C」に自動的に変わってくれることはありません。
本当は、変わってくれれば、いいのですが…
そこで、どうやったら、「b」を「c」に出来るのかを考えて、B2の数式を次のように修正しました。
=INDIRECT($A2&"!"&SUBSTITUTE(LEFT(CELL("address",B1),2),"$","")&5)
なんか、長くなっちゃいましたが、この数式を、縦方向。
横方向にオートフィルで数式をコピーすると、綺麗に、参照することができました。
では、この長くなった数式の説明をしてきます。「b」を「c」にするための数式が、
SUBSTITUTE(LEFT(CELL("address",B1),2),"$","")
です。
内側から説明しないと、わからないので、最初は、CELL("address",B1)
CELL関数は、セルの情報を算出してくれる関数で、引数にaddressをつかうと、絶対参照がついたセル番地を文字として、算出してくれます。
B1のセル情報なので、「$B$1」という文字が算出されます。
LEFT(CELL("address",B1),2)
は、LEFT(“$B$1”,2)ということなので、LEFT関数をつかって、左から2文字分を抽出します。
これで、「$B」という文字が算出されています。
「$AA$1」だったら3文字分を抽出する必要があります。
SUBSTITUTE($B,"$","") という状態になっていることがわかります。
SUBSTITUTE関数は、置換することが出来る関数なので、「$」を空白に置換させます。
これで、「B」だけを抽出することができるます。
ということで、シート名を参照できるセルをつくることで、INDIRECT関数をつかうことで、別シートから必要なデータを参照することができます。
今回は、IMSQRT関数~INDIRECT関数までをご紹介しております。
IMSQRT関数
アイエムスクエアルート
複素数の平方根を算出する
IMSQRT(複素数)
IMSUB関数
アイエムサブ
複素数の差を算出する
IMSUB(複素数1,複素数2)
IMSUM関数
アイエムサム
複素数の和を算出する
IMSUM(複素数1[,複素数2])
IMTAN関数
アイエムタンジェント
複素数のタンジェントを算出する
IMTAN(複素数)
INDEX関数
インデックス
セル範囲から縦横座標で値を抽出
INDEX(配列,行番号,[列番号])
INDEX(参照,行番号,[列番号],[領域番号])
INDIRECT関数
インダイレクト
文字列で参照されるセルの値を算出
INDIRECT(参照文字列,[参照形式])