Article

ExcelでFILTER関数の#CALC!エラーが出る原因と対処法

この記事で分かること

ExcelでFILTERやLAMBDAの数式が #CALC! になる原因を4パターンに整理し、空配列の連鎖や兄弟エラーとの切り分けを実機検証で解説します。

Excel の FILTER 関数で #CALC! が出たら、まず第3引数 [if_empty] を入れてください。最も多い原因は、条件に一致するデータが 1 件もなく、抽出結果が空になっていることです。空白を返したいなら ""、0 件だと分かる表示にしたいなら "該当なし" を指定します。

ただし #CALC!FILTER の 0 件だけでなく、LAMBDA の書き方や BYCOLBYROWMAP の戻り値、空配列を別の関数で包んだときにも出ます。この記事では、原因を 4 つに整理し、どこを直せばいいかを早見表でまず示します。実機検証は Excel 16.0 Build 19929(Microsoft Office 2024)で行いました。

30秒で分かる #CALC! の 4 原因 早見表

急ぎなら、まずこの表の「最初に直す場所」を見て、自分の式と照らしてください。詳しい説明はそれぞれの原因セクションへ。

原因出る数式の例最初に直す場所詳細
1: FILTER の結果が 0 件=FILTER(範囲, 条件)第3引数 [if_empty] を入れる原因1へ
2: LAMBDA 裸書き=LAMBDA(x, x*2)末尾に (値) を足して即時呼び出しにする原因2へ
3: ネスト配列=BYCOL(...,LAMBDA(c, c))戻り値を SUMMAX 等で単一値にまとめる原因3へ
4: 空配列の連鎖=VSTACK(FILTER(0件), ...)内側の FILTER に第3引数 [if_empty] を入れる原因4へ

4 原因のいずれでもない場合、#CALC! ではなく別のエラー(#REF!#SPILL!#VALUE!#NUM!)が出ている可能性があります。記事末尾の 兄弟エラーとの切り分け表 で見分けられます。

原因1:FILTER 関数で 0 件のとき(最頻)

FILTER 関数は、一致したデータを配列で返します。しかし現在の Excel は、空の配列をそのまま返せません。そのため、条件に一致する行が 1 件もないのに第3引数 [if_empty] を省略すると #CALC! になります。

つまり、このエラーが出たときに最初に疑うべきなのは「式の構文ミス」ではなく、「実は一致 0 件になっていないか」です。特に検索条件を厳しくしすぎたときや、数値・日付の比較がずれているときに起こりやすいです。

結論:第3引数を入れるのが最短解

まずは次の形に直してください。

=FILTER(A2:C6, C2:C6<1000, "該当なし")

見た目を空白のままにしたい場合は、"該当なし" の代わりに "" を使います。

=FILTER(A2:C6, C2:C6<1000, "")
返したい内容第3引数の例
0 件だと分かる表示"該当なし"
空白のまま表示""
数値で返したい0

第3引数で受け取るか、IFERROR で囲むかの2択

IFNA でも空配列を受け取れるのでは?」と思うかもしれませんが、Excel 2024 実機では IFNA#CALC! を捕捉しません。

=IFNA(FILTER(A2:C6, C2:C6<1000), "該当なし")

この式の結果は #CALC! のままです(IFNA#N/A 専用のため、#CALC! は素通りします)。捕捉できるのは、FILTER 自身の第3引数か、IFERROR で囲むかのどちらかです。

=IFERROR(FILTER(A2:C6, C2:C6<1000), "該当なし")

こちらは「該当なし」を返します。

ただし IFERROR#CALC! 以外のエラー(#VALUE!#REF! も)まで一緒に呑み込んでしまうので、検索条件のミスを気付けなくします。第3引数を入れるほうが意図が明確で、エラーの切り分けもしやすいので、こちらを優先してください。

実例:一致 0 件で #CALC! になるケース

次の表を例にします。

書籍番号書名金額
1ケーススタディ民法1400
2交通六法2700
3法人税法の基礎2700
4会社法2800
5民法総則2700

この表から「金額が 1000 円未満」のデータを取り出そうとすると、条件に一致する行が 1 件もないため #CALC! になります。

=FILTER(A2:C6, C2:C6<1000)
FILTER関数で第3引数を省略すると条件0件で #CALC! が出る画面
図1: FILTER で 0 件のとき、第3引数を省略すると #CALC! になる

この場合は式の書き方が壊れているのではなく、単に抽出結果が 0 件です。第3引数を追加すれば、エラーではなく任意の値を返せます。

=FILTER(A2:C6, C2:C6<1000, "該当なし")
FILTER関数の第3引数に「該当なし」を入れた直し方の画面
図2: 第3引数に「該当なし」を指定すると #CALC! が解消される

一致 0 件になりやすい確認ポイント

FILTER 関数で #CALC! が出たときは、次の点を順に確認すると切り分けしやすいです。

  • 条件が厳しすぎて、本当に一致する行がない
  • 数値に見える値が文字列で保存されている
  • 日付や時刻の比較条件がずれている
  • 複数条件を掛け合わせた結果、すべて FALSE になっている

原因を確かめたいときは、いきなり FILTER 全体を見るのではなく、条件部分だけを確認すると早いです。

=C2:C6<1000

このように条件式だけを見ると、「本当に一致 0 件なのか」「比較条件そのものがずれているのか」を見分けやすくなります。

空白や 0 を除外したデータを左詰め・上詰めで整えたい場合は、ExcelでFILTER関数を使って空白や0を除外する方法の方が目的に合います。

原因2:LAMBDA で有効な戻り値がないとき

LAMBDA 関数を「定義しただけ」の状態でセルに直接書くと、Excel は呼び出し方が分からないため #CALC! を返します。

=LAMBDA(x, x*2)

このまま入力すると #CALC! になります(裸書きで呼び出していないため)。解決方法は 2 つあります。

解1:式の末尾に (値) を足して即時呼び出しにする

=LAMBDA(x, x*2)(10)

結果は 20 で正常に計算されます。LAMBDA の本体(x*2)の後ろに、引数を渡す (10) を追加するだけです。これは「定義してすぐ実行する」書き方で、テストや単発処理に向きます。

LAMBDA を裸で書くと #CALC!、即時呼び出しなら 20 が返る画面
図3: LAMBDA は裸書きで #CALC!、末尾に (10) を足して即時呼び出しすると 20 が返る

解2:[名前の定義] に登録して再利用する

同じ計算を何度も使うなら、数式タブ → [名前の定義] で名前を付けます。たとえば「Double」という名前で =LAMBDA(x, x*2) を登録すれば、シート上では次のように書けます。

=Double(10)

結果は 20 です。何度でも呼び出せます。

注意:LAMBDA を返す式も #CALC! になる

LET の最後で LAMBDA を返す」ような書き方は、見た目は計算式ですが結果が LAMBDA オブジェクトのままなので #CALC! になります。

=LET(x, 10, LAMBDA(y, y))

この式の結果は #CALC! です(最終戻り値が LAMBDA のまま)。

LAMBDA はあくまで「呼び出した結果」をセルに置くための関数で、定義そのものはセル上に出せない、と覚えると分かりやすいです。

原因3:BYCOL・BYROW・MAP のラムダがネスト配列を返すとき

BYCOLBYROWMAP は、配列の各列・各行・各要素に対してラムダ式を 1 回ずつ適用し、結果を 1 つの配列にまとめる関数です。このとき、ラムダ式の戻り値は「単一値(スカラー)」でなければなりません。 配列を返すと、配列の中に配列が入る「ネスト配列」になり #CALC! が出ます。

=BYCOL({1,2,3;4,5,6}, LAMBDA(c, c))

結果は #CALC! です(c が列ごとに 2 セル分の配列を返しているため)。BYROW も同じ理由で #CALC! になります。

=BYROW({1,2,3;4,5,6}, LAMBDA(r, r))

こちらも結果は #CALC! で、r が行ごとに 3 セル分の配列を返しています。MAP でも、IF の真の側で範囲を返すと同じく #CALC! です。

=MAP(M1:O2, LAMBDA(v, IF(v>0, M1:N1, 0)))

結果は #CALC! で、IF の真の側 M1:N1 が範囲を返してしまうのが原因です。

解:戻り値を SUM・MAX 等で単一値にまとめる

たとえば、各行の合計を出したいなら、r をそのまま返すのではなく SUM(r) で集約します。

=BYROW(A2:B4, LAMBDA(r, SUM(r)))

各行の合計が縦にスピルし、エラーは出ません。

BYCOL でネスト配列を返すと #CALC!、BYROW で SUM 集約すると正常にスピルする画面
図4: BYCOL に列を返すと #CALC!(上段)、BYROW で SUM 集約すれば正常にスピル(下段)

各列の最大値を取るなら次の形です。

=BYCOL(A2:B4, LAMBDA(c, MAX(c)))

各列の最大値が横にスピルします。MAP でも、IF で範囲を返さず、計算結果のスカラーを返すように書き換えれば動きます。

=MAP(M1:O2, LAMBDA(v, IF(v>0, v*2, 0)))

各要素を 2 倍にした 2 行 3 列の配列がスピルします。

原因4:空配列が他の関数に伝播するとき

FILTER の結果が 0 件になると、その式単体では #CALC! ですが、FILTER(...0件...) を別の関数で包んだ式」は、外側の関数に #CALC! がそのまま伝播します。

Excel 2024 実機で確認した範囲では、次の関数で FILTER の 0 件結果を包むと、すべて #CALC! になります。

包む関数結果
VSTACK=VSTACK(FILTER(0件), {"x","y","z"})#CALC!
HSTACK=HSTACK(FILTER(0件), A2:C6)#CALC!
DROP=DROP(FILTER(0件), 1)#CALC!
TAKE=TAKE(FILTER(0件), 1)#CALC!
TOROW=TOROW(FILTER(0件))#CALC!
TOCOL=TOCOL(FILTER(0件))#CALC!
SUM=SUM(FILTER(C2:C6, C2:C6>99999))#CALC!
ROWS=ROWS(FILTER(0件))#CALC!
VSTACK の引数に空配列の FILTER が混ざると #CALC! が伝播する画面
図5: VSTACK の中で FILTER が 0 件を返すと、外側に #CALC! が伝播する

解:内側の FILTER に第3引数 [if_empty] を入れる

解決の基本は、外側ではなく 内側の FILTER 自体に第3引数を入れることです。空配列が出ないなら、外側に伝播するものもありません。

VSTACKHSTACK で包む場合は、第3引数の値が外側の関数と幅・高さが揃うようにするのが大事です。たとえば {"x","y","z"}(3列)と縦に積むなら、第3引数も 3 列分用意します。

=VSTACK(FILTER(A2:C6, C2:C6>99999, {"-","-","-"}), {"x","y","z"})

結果は ["-","-"]{"x","y"} が縦に並び、2 列 × 2 行できれいにスピルします。幅を合わせず =VSTACK(FILTER(..., ""), {"x","y"}) のように単一値を渡すと、#CALC! は回避できますが VSTACK 側の幅合わせで #N/A が補完されてしまいます。

FILTER の戻り値を SUM で集計するパターンは、第3引数 0 を入れるだけで #CALC! を回避できます。SUM はスカラーを返すので幅の心配はいりません。

=SUM(FILTER(C2:C6, C2:C6>99999, 0))

結果は 0 です(合計対象が 0 件なら 0 を返す)。

FILTER から TAKE / DROP へつなぐとき、第 3 引数で空配列を防御してもスカラに対する DROP(_, 1)#CALC! が二段伝播する罠があります。詳しくは DROP 関数 完全リファレンス と、対策の使い分けは 【Excel】DROP 関数と TAKE 関数の違い|#CALC! 対策 を参照してください。

検証メモ:COUNTA は例外的に伝播しない

少しややこしい話ですが、Excel 2024 実機では COUNTA(FILTER(...0件...)) だけは例外で、#CALC! にならず数値 1 を返します。

=COUNTA(FILTER(A2:C6, C2:C6>99999))

この式の結果は 1 です(#CALC! にはならない)。

これは「件数が 0 のはずなのに 1 が返る」ので、件数 0 の判定にこの式を使うのは推奨しません。0 件チェックは、FILTER の第3引数や IFERROR で空配列自体を出さないようにするのが安全です。

兄弟エラーとの切り分け表

#CALC! だと思っていたら別のエラーだった」というケースもあります。配列・スピル・LAMBDA まわりで出る代表的なエラーを ERROR.TYPE 値とあわせて整理します(Excel 2024 実機)。

エラーERROR.TYPE代表的な数式主な原因詳細
#CALC!14=FILTER(範囲, 条件) 0 件 / =LAMBDA(x, x*2) 裸書き / ネスト配列空配列・無効な配列・配列の配列本記事
#REF!4=OFFSET(A1, -1, 0) シート外参照参照先がシートの範囲外エラー値一覧
#SPILL! (#スピル!)9=TAKE(A2:A4, 100) 行数超過 / スピル先がふさがっているスピル先の妨害・範囲超過要求エラー値「#スピル!」の発生原因
#VALUE!3=FILTER(VSTACK(A2:B6, D2:E5), A2:A6="x") 高さ不一致引数の型・サイズが合わない#VALUE!を表示させない方法
#NUM!6=Fact(1000) 深再帰 / 循環 LAMBDA計算回数や数値範囲の超過エラー値一覧
#NAME?5=_xlfn.LAMBDA(...)関数名を Excel が認識できない「_xlfn.」が付いて #NAME?

以前の記事で「OFFSET が範囲外で #CALC!」「LAMBDA(x)(範囲)#VALUE!」と説明されているのを見かけることがありますが、Excel 2024 実機ではどちらも違う結果になります(OFFSET 範囲外は #REF!LAMBDA に範囲を渡すと #SPILL!)。古い情報を鵜呑みにしないでください。

OFFSET シート外参照で #REF!、TAKE がスピル先妨害で #スピル! になる画面
図6: 上が =OFFSET(A1, -1, 0) で #REF!、下が =TAKE(A2:A6, 5) でスピル先妨害により #スピル!(どちらも #CALC! ではない)

関連エラーの切り分け先記事

本文中で触れた個別のエラー・現象をさらに掘り下げる記事を、テーマ別にまとめます。

まとめ

#CALC! が出たときは、まず原因 1〜4 のどれに当たるかを早見表で確認してください。

  1. FILTER の 0 件 → 第3引数 [if_empty] が最短解
  2. LAMBDA 裸書き → 末尾に (値) を足すか、[名前の定義] に登録
  3. BYCOLBYROWMAP のネスト配列 → 戻り値を SUM 等で単一値化
  4. 空配列の連鎖 → 内側の FILTER に第3引数を入れて、空配列自体を出さない

4 原因のいずれでもないなら、兄弟エラーとの切り分け表ERROR.TYPE から実際のエラー種別を見分けてください。

VBA や旧バージョンでの注意

VBA から #CALC! セルを読むと、Range.Text"#CALC!" の文字列、Range.Value2 は HRESULT 値 -2146826238 を返します。xls 形式で保存すると LETTEXTSPLIT などの新しい関数のスピル結果は失われます。なお「LibreOffice Calc」は名前は似ていますが Microsoft Excel とは別ソフトで、本記事の挙動とは関係ありません。

参考情報

マイクロソフト公式の #CALC! 解説は 「#CALC! を修正する方法」(Microsoft サポート) にあります。本記事は実務でつまずきやすい 4 原因に絞っているので、公式が挙げる「Nested Array」「Array of ranges」「Empty Array」「Cell contains a lambda」「Cell formula result is a function」の 5 類型と合わせて読むと、より広いケースに対応できます。

Next Read

このあと読む記事

今の内容に近い記事から、次の1本と補助記事を続けて見つけられるようにしています。

Keep Exploring

このテーマをさらに探す

同じテーマの入口記事と更新記事を、一覧の形でまとめています。

コメント