LET関数 深掘り①:VLOOKUPの重複評価を排除して速度を劇的改善

💡 やりたいこと

1つのセルの中で「同じ VLOOKUP(または XLOOKUP)」が何度も登場する数式を書いてしまっていませんか?
LET関数で検索結果を変数に1回だけ格納すれば、計算回数を激減させて体感速度が大幅に変わります。

まず "よくあるダメな例" を見る

商品コード(A2)からマスタを引いて「商品名が空なら"未登録"、そうでなければ商品名+単価を表示」という処理を考えます。

❌ VLOOKUPが3回重複
=IF( VLOOKUP(A2, マスタ!A:D, 2, FALSE) = "", "未登録", VLOOKUP(A2, マスタ!A:D, 2, FALSE) & "/" & TEXT(VLOOKUP(A2, マスタ!A:D, 3, FALSE), "#,##0") & "円" )

この数式には VLOOKUP が 3回 書かれています。
Excel は数式内の各 VLOOKUP をそれぞれ独立に評価するため、マスタが10万行ならVLOOKUPの検索処理が3回×行数ぶん走ります。

⚠ なぜ遅い?
VLOOKUP / XLOOKUP は呼び出しのたびにマスタ範囲を先頭から走査します(完全一致の場合)。数式内に同じ検索を3回書くと、Excelは「同じ引数だから省略しよう」とは判断してくれません。3回とも律儀にフルスキャンします。これが1万行のシートに入っていれば、VLOOKUP の実行回数は 3万回 です。

LET で1回だけ検索する

=LET( 商品名, VLOOKUP(A2, マスタ!A:D, 2, FALSE), 単価, VLOOKUP(A2, マスタ!A:D, 3, FALSE), IF(商品名 = "", "未登録", 商品名 & "/" & TEXT(単価, "#,##0") & "円") )

VLOOKUPが 3回 → 2回 に減りました。商品名の検索が1回で済むようになっています。
さらに、変数名「商品名」「単価」のおかげで何をしている数式かが一目瞭然です。

XLOOKUP ならさらに1回で済む

=LET( 行, XLOOKUP(A2, マスタ!A:A, マスタ!B:D, ""), 商品名, INDEX(行, 1), 単価, INDEX(行, 2), IF(商品名 = "", "未登録", 商品名 & "/" & TEXT(単価, "#,##0") & "円") )

XLOOKUP は戻り値に複数列を指定できるため、検索自体が たった1回 で完了します。LETの変数「行」にまとめて受け取り、INDEX で分解する構成です。

⚡ 速度比較の目安(10万行マスタ × 1万行の数式)
LETなし(VLOOKUP×3回):再計算 約8~12秒
LET使用(VLOOKUP×2回):再計算 約5~8秒
LET+XLOOKUP(検索1回):再計算 約2~4秒
※環境により異なりますが、検索回数にほぼ比例して速くなる傾向があります。

実務でよくあるシナリオ3選

シナリオ①:「該当なし」の分岐 + 値の表示

VLOOKUPの結果が #N/A かどうかで分岐し、見つかった場合はその値を使う ── これは IFERROR の中にもう一度同じ VLOOKUP を書くパターンで頻出します。

=IFERROR(VLOOKUP(A2,マスタ!A:B,2,FALSE), "該当なし")

↑ これは実は1回しかVLOOKUPしていないので問題なし。IFERRORが評価を制御してくれます。
ただし次のようにエラー時に別の検索をする場合は話が変わります。

❌ 正規マスタのVLOOKUPが2回重複
=IF( ISNA(VLOOKUP(A2, 正規マスタ!A:B, 2, FALSE)), VLOOKUP(A2, 旧マスタ!A:B, 2, FALSE), VLOOKUP(A2, 正規マスタ!A:B, 2, FALSE) )
✅ LETで1回に
=LET( 正規, VLOOKUP(A2, 正規マスタ!A:B, 2, FALSE), IF(ISNA(正規), VLOOKUP(A2, 旧マスタ!A:B, 2, FALSE), 正規) )

正規マスタの VLOOKUP が2回→1回に。旧マスタ側は「正規で見つからなかったときだけ」評価されるので、LET内で先に実行する必要はありません(IFの遅延評価を活用)。

シナリオ②:VLOOKUP結果を複数の計算に使う

単価を引いてきて、小計・消費税・合計の3列に使うケース。

❌ 3列すべてでVLOOKUPが重複
小計列: =VLOOKUP(A2,マスタ!A:C,3,FALSE)*B2 税額列: =VLOOKUP(A2,マスタ!A:C,3,FALSE)*B2*0.1 合計列: =VLOOKUP(A2,マスタ!A:C,3,FALSE)*B2*1.1

この場合、各列に1回ずつ計3回VLOOKUPが走ります。これは LET で1セルにまとめるより、ヘルパー列(作業列)に単価を1回だけ引いてくるほうが構成としてシンプルです。

✅ 作業列で1回だけ検索
作業列(C列): =VLOOKUP(A2, マスタ!A:C, 3, FALSE) ← 1回だけ 小計列(D列): =C2*B2 税額列(E列): =D2*0.1 合計列(F列): =D2+E2

LETは「1つのセル内」での重複を排除するもの。複数セルにまたがる場合は作業列のほうが自然です。使い分けがポイント。

シナリオ③:同一セル内で同じ検索を条件分岐に何度も使う

ランク判定のように、1つの検索結果を何段階ものIFで参照するケース。これがLETの最も効果的な場面です。

❌ VLOOKUPが3回重複
=IF(VLOOKUP(A2,集計!A:B,2,FALSE)>=100,"S", IF(VLOOKUP(A2,集計!A:B,2,FALSE)>=80,"A", IF(VLOOKUP(A2,集計!A:B,2,FALSE)>=60,"B","C")))
✅ LETで1回に
=LET( 点数, VLOOKUP(A2, 集計!A:B, 2, FALSE), IF(点数>=100, "S", IF(点数>=80, "A", IF(点数>=60, "B", "C"))) )

VLOOKUP 3回 → 1回。検索回数が1/3になります。IFのネストが深くても変数名のおかげで読みやすいのもメリットです。

LET あり/なし 比較まとめ

データテーブル
観点LET なしLET あり
VLOOKUP の評価回数数式に書いた回数ぶん(3回書けば3回)変数定義の1回だけ
可読性同じ長い関数が何度も出て読めない変数名で意味が明確
修正時のリスク3箇所すべて修正が必要。1箇所忘れるとバグ定義部分の1箇所を変更すれば全体に反映
数式バーの長さ長い(スクロールしないと全体が見えない)やや長いが構造が明確
計算速度(1万行目安)VLOOKUP×3回×1万=3万回の検索VLOOKUP×1回×1万=1万回の検索

LET の注意点・落とし穴

⚠ IFの遅延評価を意識する
LET の変数定義は上から順にすべて評価されます。つまり IF の TRUE側でしか使わない重い計算も、LETの変数に入れた時点で必ず実行されます。「条件によっては計算不要」なものは LET の変数にせず、IF の中に直接書くほうが速い場合があります。
⚠ 変数名のルール
変数名にセル参照と紛らわしい名前(例:A1, R1C1)は使えません。日本語の変数名(例:売上, 税率)が使えるので、積極的に日本語で命名すると可読性が上がります。ただし関数名(SUM, IFなど)と同じ名前もNGです。
⚠ LET で作業列が不要になるわけではない
シナリオ②で見たように、複数セルから同じ値を参照するなら作業列が正解です。LETは「1つのセル内の重複」を解消するもの。万能ではないことを理解して使い分けましょう。

旧バージョンでの代替法

LETが使えない環境(Excel 2019以前、または更新チャネル・買い切り版・職場PCの管理設定などで未対応の環境)では、やはり作業列に VLOOKUP の結果を一度出力し、以降の計算はそのセルを参照する方式が最善です。1つのセル内で重複評価を防ぐ手段は LET 以外に存在しないため、作業列は「古い方法」ではなく「LETが使えないときの正攻法」です。