Article

【Excel】数式の「@」が勝手につく3つの原因と外し方

この記事で分かること

Excelの数式バーで「@」が突然出てきて困ったことはありませんか。実機検証から「@」が勝手につく3つの原因を切り分け、Range.Formula2を使った外し方を解説します。

Excel の数式バーで突然見かける「@」(アットマーク)。VBA で書いた式に勝手に付いていたり、関数名の前に出ていたり、テーブル内で見ると違う形だったりして混乱しがちです。多くの解説は「暗黙的交差です」で終わりますが、それだけでは「自分のケースではどう外すのか」「そもそもなぜ自分の数式に付いたのか」が分かりません。本記事では Excel 2024 で実機検証した結果から、「@」を 3 種類に分け、「Range.Formula」と「Range.Formula2」の違いを軸に根本原因と外し方を解説します。

Excel 数式バーに =VLOOKUP(@A2:A6,A2:C6,2,FALSE) が表示され @ が赤丸で強調されたアイキャッチ

結論——typed では「@」は基本付かない、付くのはほぼこの 3 ケース

結論からいうと、Excel 2024 の数式バーで直接タイプ(typed)した式には、暗黙的交差演算子の @ は基本的に自動で付きません。=B2:B6=VLOOKUP(A2:A6,...) をそのまま入れれば、通常はスピルして複数セルに値が並びます。

「@」が勝手に付いて見えるのは、ほぼ次の 3 ケースに限られます。

  1. VBA で Range.Formula = "..." を使ったとき(レガシーなプロパティ経由で式を書き戻したとき)
  2. 既存マクロや記録された VBA の中で Range.FormulaR1C1 を使ったとき(挙動は実機で同じ系列)
  3. Excel 2019 以前のファイル(または .xls 形式で保存し直したファイル)を Excel 2024 で開いたとき

この記事ではこれらの違いを実機の数式バー画像で並べ、外し方と「外したときに何が起きるか」までセットで解説します。VBA は触らないという方は 3 種類の @ を整理@ がつかないケースだけ読めば十分理解できる構成にしています。

数式バーに =VLOOKUP(A2:A6,A2:C6,2,FALSE) と @ なしで表示され、E1:E5 に 100 80 300 200 150 がスピル
数式バーで直接入力した VLOOKUP は @ なしで E1:E5 にスピルする
数式バーに =VLOOKUP(@A2:A6,A2:C6,2,FALSE) と @ 付きで表示され、F1 が #VALUE! になっている
VBA で .Formula 経由に書くと数式バーに @ が補われる

そもそも「@」の意味——暗黙的交差演算子とは

「@」の正式名称は暗黙的交差演算子(implicit intersection operator)です。役割は単純で、「ここはスピルさせず、現在行に対応する 1 つの値で評価する」というマーカーです。

この演算子が必要になった背景は、Excel 2019 以前と Excel 2021/2024 の数式評価ルールの違いにあります。Excel 2019 までは「複数セル範囲が単一値を期待する関数に渡されたとき、数式と同じ行(または列)のセルを暗黙的に取り出す」暗黙的積集合 (IIE: Implicit Intersection Evaluation) が既定でした。Excel 2021 以降は「複数セル範囲を関数に渡すと、各セルで関数を呼び出し、結果を配列として返す」配列評価 (AE: Array Evaluation) が既定になっています。

Excel 2024 で IIE 風の動作を残したいときに「ここは単一値モード」と示すマーカーが @ です。Microsoft Learn の Range.Formula vs Formula2 でも、AE と IIE の差が「@」によって表記される旨が説明されています。

混同しやすい 3 種類の「@」を整理する

Excel で「@」を見かける場面は、表面上は似ていても背景が違います。本記事では次の 3 種類に分けて整理します。

表記名称意味主に出会う場面
=@A2:A6暗黙的交差演算子配列を行整列で 1 セルに縮約VBA、旧ファイル、手動入力
=Tbl1[@売上]構造化参照の @テーブル内で「現在行の値」を取るショートハンドテーブル内の計算列
_xlfn.SINGLE(...)レガシー互換マーカー暗黙的交差の XML 上の実体旧 Excel で開いたとき (#NAME? 表示の原因にもなる)
テーブル内の D2 セルが選択され、数式バーに =[@単価]*[@数量] が表示されている
テーブル内の構造化参照 [@単価] は「現在行の値」を意味する
通常セル G1 に =@B2:B6 を入れたところ #VALUE! になっている
通常セルに =@B2:B6 を typed すると行が範囲外で #VALUE! になる

このうち A の通常セルの @ と B の構造化参照の @ は表記と保存形式が違います。Excel 2024 のファイル(.xlsx)を解凍して内部 XML を確認すると、A は _xlfn.SINGLE(...) または <f> ノードに格納されています。B は Tbl[[#This Row],[列名]] という別の構文で格納されます。

一方で、どちらも「複数候補のなかから現在行に対応する 1 つの値を取る」という考え方は近いものです。Microsoft Support の implicit intersection 解説でも、テーブル参照と通常セルの両方が同じ implicit intersection の概念として扱われています。本記事では「同じ系列だが、見た目と使う場面で区別すると整理しやすい」というスタンスで進めます。

判別フローチャート

  • セルがテーブル内 → 構造化参照の [@col](現在行のショートハンド)
  • セルが普通のシートで関数の頭に @ → 通常セルの暗黙的交差演算子(typed では基本付かないので、VBA 経由を疑う)
  • 関数名の前に _xlfn.SINGLE(...) → 旧 Excel で開いた時の互換表記。Excel 2021 以降で開き直して再保存すれば @ 形式に変わる

本当に「勝手につく」3 つのシナリオ

シナリオ 1:VBA で Range.Formula = "..." を使ったとき(最頻)

もっとも頻繁に起きるのがこのケースです。例えば次のような VBA を実行すると、数式バーには @ 付きで表示されます。

Sub BadExample()
    ' これがダメな書き方
    Sheet1.Range("E1").Formula = "=VLOOKUP(A2:A6,A2:C6,2,FALSE)"
End Sub
VBE で Module_Demo の Demo_AtInjection サブが表示され、.Formula 経由と .Formula2 経由の両方の代入が並んで見える
VBE で .Formula と .Formula2 の対比を VBA コードで表現
Range.Formula = の VBA を実行した後の H1 セル、数式バーが =VLOOKUP(@A2:A6,A2:C6,2,FALSE) と表示される
Range.Formula 経由で書いた直後の数式バー

結果は次のようになります。

  • 数式バーの表示:=VLOOKUP(@A2:A6,A2:C6,2,FALSE)(@ が補われる)
  • セルの値:#VALUE!(行 1 は A2:A6 と交差しないため)
  • スピル:しない

原因は、Range.Formula プロパティが暗黙的積集合(IIE)モードで式を評価する仕様だからです。Microsoft Learn の表現を借りれば「Range.Formula を使用して数式を設定すると、暗黙的な積集合がトリガーされ、スピルすることはありません」。配列を返す式を渡された Excel は、数式バー表示用の Range.Formula2 上では @ を補って単一値モードを示します。

正しい書き方は Range.Formula2 を使うことです。

Sub GoodExample()
    ' これが正解
    Sheet1.Range("E1").Formula2 = "=VLOOKUP(A2:A6,A2:C6,2,FALSE)"
End Sub
Range.Formula2 = の VBA を実行した後の I1 セル、数式バーは =VLOOKUP(A2:A6,A2:C6,2,FALSE) で I1:I5 にスピル
Range.Formula2 で書き直すと @ なしでスピルする

これで数式バーには =VLOOKUP(A2:A6,A2:C6,2,FALSE) がそのまま表示され、E1:E5 にスピルします。

シナリオ 2:既存マクロや記録された VBA で FormulaR1C1 を使ったとき

過去に書かれた VBA でよく見られる Range.FormulaR1C1、あるいはマクロ記録の生成コードに .FormulaR1C1 が含まれている場合も注意が必要です。実機検証では Range.Formula と同じく暗黙的交差を補う挙動になりました。

たとえば Range("E1").FormulaR1C1 = "=R2C2:R6C2" を実行すると、数式バー上の表示は =@$B$2:$B$6 になります。=FILTER(R2C2:R6C2,R2C2:R6C2>100) なら =@FILTER($B$2:$B$6,$B$2:$B$6>100) という形で @ が補われます。同じ式を Range.Formula2R1C1 で書けば @ は付かず、複数セルにスピルします。

' 既存マクロや記録結果(@ が混入)
Range("E1").FormulaR1C1 = "=VLOOKUP(R[1]C[-4]:R[5]C[-4],R[1]C[-4]:R[5]C[-2],2,FALSE)"

' 動的配列対応に書き換え(@ なし、スピル)
Range("E1").Formula2R1C1 = "=VLOOKUP(R[1]C[-4]:R[5]C[-4],R[1]C[-4]:R[5]C[-2],2,FALSE)"

シナリオ 3:Excel 2019 以前のファイル(または .xls 形式)を Excel 2024 で開いたとき

Excel 2019 以前で書かれた式のうち、暗黙的積集合(IIE)で評価される単一セルの式は、Excel 2024 で開くと数式バー上で @ が補われた表示になります。たとえば 1 つのセルに =B2:B6 と入っていた場合、Excel 2024 では =@B2:B6 として表示されます。なお、Excel 2019 で Ctrl+Shift+Enter を使って明示的に作られた配列数式 (CSE 配列) はそのまま配列数式として保持され、@ の付与とは別の経路で扱われます。

本記事の検証では、Excel 2024 で =@B2:B6 を含むブックを .xls 形式で保存し、開き直したところ、数式バーは =@B2:B6、セルの値は 100(行 2 の B 値)で保持されることを確認しました。.xls をハブにすると暗黙的交差の @ はそのまま残ります。

形式=B2:B6 の数式バー表示値(行 2 の場合)スピル
.xlsx (新規 typed)=B2:B6100あり (E1:E5)
.xlsx (.Formula 経由保存)=@B2:B6#VALUE! (行 1)なし
.xls (旧形式 → 再オープン)=@B2:B6100なし
.xls 旧形式で保存して再オープンした E1 セル、数式バーは =@B2:B6 のまま値は 100
.xls 経由で再オープンしても @ は保持される

補足:関数名の前に _xlfn.SINGLE(...) が見えるときは、Excel 2019 以前で同じファイルを開いた時の互換表記です。これは @ の XML 上の実体で、Excel 2021 以降で開き直して再保存すれば、数式バーでは @ 形式に変わります。

「@」がつかないケース——よくある誤解

古い記事や Q&A では「VLOOKUP に配列を渡すと @ が自動で付く」「テーブル集計行で @ が付く」といった説明が見られますが、Excel 2024 の実機検証ではいずれも 付きませんでした。次のケースで @ が付かないことを確認しています。

  • 単一セルに =A2:A6 を typed → スピル(@ 不要)
  • VLOOKUP に配列引数 =VLOOKUP(A2:A6,A2:C6,2,FALSE) を typed → スピル
  • テーブルの集計行で「合計」を選択 → =SUBTOTAL(109,[単価])(@ なし)
  • 条件付き書式の数式 =B2:B6>100 → 配列評価で @ なし
  • データ検証(入力規則)の =$B$2:$B$6 → 配列評価で @ なし

Excel 2021 以降は、VLOOKUP に配列引数を typed するだけでスピルします。「VLOOKUP の配列展開を抑止するには @ を付けろ」という記述は Excel 2019 以前の挙動を前提としたもので、現代的な typed の標準動作はスピルです。一方で、配列を返す式を意図的に 1 セルに縮約したいときは、今でも @ で暗黙的交差を働かせる用途は有効です。

「@」を外したらどうなるか

「@」を見つけたら数式バーで該当の @ を削除して再確定します。例えば =@B2:B6 から @ を取れば =B2:B6 になり、複数セルにスピルが走ります。

@ なしの =B2:B6 を入れた J1 セル、J1:J5 に 100 80 300 200 150 がスピル
@ なしで書けば配列はスピルする

外す前に注意したいポイントは次のとおりです。

  • スピル先に既存値があると #SPILL!:外すと配列が展開しようとするため、隣接セルが空でないとエラーになります
  • 1 行ずつ独立計算していた中間セルが影響を受ける:「行ごとに同じ式をコピー」という旧来のパターンが、スピルで全行展開する 1 セルに置き換わります
  • コピー貼り付けの追従:本記事の検証では、=@B2:B6 を I2 に入れて I3:I5 にコピーすると、それぞれ =@B3:B7=@B4:B8=@B5:B9@ ごと相対参照で追従しました

VBA 開発者向け:Range.FormulaRange.Formula2 の違い

VBA で @ 問題を回避する根本対策は、Range.Formula2 プロパティを使うことです。Microsoft Learn の公式ドキュメントは両者を次のように整理しています。

  • Range.Formula:暗黙的積集合 (IIE) で評価。Excel 2019 以前の数式バーが報告する内容に相当
  • Range.Formula2:配列評価 (AE) で評価。動的配列対応の Excel が数式バーで報告する内容に相当

関数の挙動マトリクス(実機検証の抜粋)

同じ式を .Formula 経由と .Formula2 経由で書き、数式バー表示にどう差が出るかを検証した結果が次のマトリクスです。本文には主要な関数の抜粋を載せ、配布サンプル .xlsm の「関数別マトリクス」シートに完全版を収録しています。

Range.Formula 経由と Range.Formula2 経由で 18 関数の数式バー表示を比較したマトリクス図、@ 注入される行は赤い背景で示される
Range.Formula と Range.Formula2 の挙動マトリクス(Excel 2024 実機検証)
入力した式.Formula で書くと数式バーは.Formula2 で書くと数式バーは
=B2:B6=@B2:B6=B2:B6 (スピル)
=SUM(B2:B6)=SUM(B2:B6)=SUM(B2:B6)
=FILTER(B2:B6,B2:B6>100)=@FILTER(B2:B6,B2:B6>100)=FILTER(B2:B6,B2:B6>100) (スピル)
=UNIQUE(B2:B6)=@UNIQUE(B2:B6)=UNIQUE(B2:B6) (スピル)
=SORT(B2:B6)=@SORT(B2:B6)=SORT(B2:B6) (スピル)
=SEQUENCE(5)=@SEQUENCE(5)=SEQUENCE(5) (スピル)
=VLOOKUP(A2,A2:C6,2,FALSE)=VLOOKUP(A2,A2:C6,2,FALSE)=VLOOKUP(A2,A2:C6,2,FALSE)
=VLOOKUP(A2:A6,A2:C6,2,FALSE)=VLOOKUP(@A2:A6,A2:C6,2,FALSE)=VLOOKUP(A2:A6,A2:C6,2,FALSE) (スピル)
=INDEX(B2:B6,A2:A6)=@INDEX(B2:B6,@A2:A6) (@ が 2 個)=INDEX(B2:B6,A2:A6) (スピル)
=IF(B2:B6>100,"高","低")=IF(@B2:B6>100,"高","低")=IF(B2:B6>100,"高","低") (スピル)
=LET(x,B2:B6,x*2)=LET(x,B2:B6,@x*2)=LET(x,B2:B6,x*2) (スピル)
=E1# (スピル参照)=@E1#=E1#
=ROW(A2:A6)=@ROW(A2:A6)=ROW(A2:A6) (スピル)
=TEXT(B2:B6,"#,##0")=TEXT(@B2:B6,"#,##0")=TEXT(B2:B6,"#,##0") (スピル)

パターンとしては 「結果が配列(複数値)になる式」を .Formula で書くと @ が補われる元から単一値しか返さない関数(SUMSUMIF、スカラ引数の VLOOKUP など)では差が出ないという挙動になります。

逆方向の変換と SavedAsArray

逆方向、つまり Range.Formula2=SQRT(@A1:A4) と書いて Range.Formula 経由で読み戻すと、@ の落ちた =SQRT(A1:A4) という形で返ってきます。Excel は IIE と AE で結果が同じなら、ファイル保存時に互換性の高い IIE 形式で書き出して、旧バージョン Excel での見た目を改善しています。配列形式で保存されるかどうかは Range.SavedAsArray プロパティで判定できます。

OfficeJS と Excel for the web(調査観点)

Microsoft Learn によると、OfficeJS(Office アドイン用 JavaScript API)には Range.Formula2 に相当するプロパティが含まれていません。そのため Web 版 Excel のアドインや、OfficeJS をベースにしたツール経由で式を書く場合、VBA の .Formula2 と同じ挙動になるとは限りません。@ が混入する不具合に出会ったときは、どの API・どのツール経由で式を書いたかを切り分けの第一歩にすると効率的です。

ベストプラクティス

  • 動的配列対応版(Excel 2021 以降)だけが対象 → .Formula2 または .Formula2R1C1 を使う
  • Excel 2019 以前も対象 → .Formula を使う(@ が出ても許容する設計)
  • 両方対応したい → .Formula2 がサポートされているかを判定して分岐させる

構造化参照の [@col] は通常セルの「@」と表記・保存形式が違う

テーブル内の計算列で書く =[@単価]*[@数量]@ は、テーブル内の「現在行の値」を取るためのショートハンドです。XML 上は Tbl1[[#This Row],[単価]]*Tbl1[[#This Row],[数量]] として保存され、通常セルの暗黙的交差(_xlfn.SINGLE(...) 系)とは別構文で記録されます。

テーブル内の =[@単価]*[@数量] と通常セルの =@B2:B6 を同じシートに並べて表示
構造化参照の @ と通常セルの暗黙的交差の比較

一方で、どちらも「複数候補から現在行に対応する 1 つの値を取る」という考え方は近いものです。Microsoft Support の implicit intersection 解説でも、テーブル参照と通常セルが同じ implicit intersection の概念として整理されています。実用上は、テーブル内なら [@col]、テーブル外で関数の頭に @ なら通常セルの暗黙的交差と判別すれば混乱しません。

まとめ

Excel 2024 の数式バーで「@」が見えるのは、暗黙的交差(implicit intersection)を示す互換マーカーで、typed では基本付きません。「勝手につく」と感じるのは、ほとんどが VBA の Range.Formula / Range.FormulaR1C1 経由か、Excel 2019 以前のファイル(あるいは .xls)の経路です。VBA で配列を返す式を扱うときは Range.Formula2 を選ぶ、典型的なケースで「@」が出たら Range.Formula2 系に書き換える——これがもっともシンプルな処方箋になります。

配布サンプル

本記事で実演した挙動を実機で試せる .xlsm サンプルを配布します。VBA の Demo_AtInjection マクロを実行すると、シート「VBA_at_注入実演」で .Formula 経由(D 列)と .Formula2 経由(G 列)の差が並列で確認できます。

サンプルファイル xlsm ・ 約 23 KB

本記事で実演した「@」の挙動を試せるブックです。VBA の Demo_AtInjection マクロを実行すると、シート「VBA_at_注入実演」で .Formula 経由(D 列)と .Formula2 経由(G 列)の差を並列で確認できます。

ダウンロード

関連記事

Next Read

このあと読む記事

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

Keep Exploring

このテーマをさらに探す

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

コメント