Article

【Excel】同じセルに入力するたびに加算する方法|2解法と罠

この記事で分かること

Excelで同じセルに入力するたびに数値を加算する2つの方法 (反復計算 / VBA) と、保存時の累積罠・Undo不可・使い分けマトリクスを実機検証で整理します。

この記事では、入力用のセル(例: B1)に数字を入れるたびに、別の累計セル(例: A1)へ足し込んでいく方法を扱います。累計セル A1 そのものへ直接入力し続ける方式は Undo や履歴管理の問題が大きいため、業務用途には B1 → A1 の別セル入力構成を推奨します。

実装には反復計算をオンにする方法と Worksheet_Change マクロを使う方法の 2 つがあります。それぞれに「保存のたびに B1 値が再加算される」「Worksheet_Change の後では Ctrl+Z が期待どおりに効かない」などの落とし穴があるので、用途に合うほうを選んで罠を回避してください。Microsoft 公式仕様と Excel 2024 build 19929 での実機検証で詰めて解説します。

どちらの方法を選ぶべきか — 2 解法のフローチャート

保存しながら使うか・Ctrl+Z で戻したいか・他人に配布するか・マクロが使えるかの 4 軸で反復計算とマクロを使い分けるフローチャート
  • 1 人で使う、保存頻度低、Ctrl+Z 期待しない → 解法 A(反復計算)
  • 配布する、複数人が使う、Ctrl+Z 期待しない → 解法 B(Worksheet_Change マクロ)
  • 保存しながら使う / Ctrl+Z で戻したい → どちらも要工夫、後述の 罠 1 / 罠 4 回避策 を参照

解法 A: 反復計算をオンにしてセルフ参照式を使う

Excel のオプションで反復計算を有効にすると、自分のセルを参照する数式(セルフ参照式)が許容されます。これを利用して、A1 セルに =A1+B1 という式を書き、B1 への入力を A1 へ累積させます。

手順

  1. ファイル → オプション → 数式 → 「反復計算を行う」をオン、最大反復回数を 1 に設定
  2. A1 セルに =A1+B1 を入力
  3. B1 に数値を入力するたびに、A1 が累積していく
Excel のオプション画面の「数式」タブ。「反復計算を行う」チェックボックスと「最大反復回数」入力欄の位置を示す参考画像

※ 上の画像は設定項目の位置を示す参考画面です。実際には「反復計算を行う」にチェックを入れ、「最大反復回数」を 1 に書き換えた状態で OK を押してください。

A1 に貼り付ける数式(コピー可能):

=A1+B1
B1 に 100、50、30 を順に入力するたびに A1 の値が 100、150、180 と累積していく 3 状態を 1 枚に合成した実機画面

利点と制限

  • 利点: VBA を書く必要がない。設定一発で済む。.xlsx のまま動く
  • 制限: 反復計算の設定は Excel アプリケーション全体に適用される(後述の 罠 2 を参照)。最大反復回数を 2 以上にすると 1 回の入力で複数回累積する罠あり(後述の 罠 1 注意点)

Microsoft 公式: 数式の再計算、反復計算、または有効桁数を変更する(サポート)

最大反復回数の挙動について: 最大反復回数を 3 にすると、1 回の再計算で 3 回分(B1 の値 × 3)が足されます。さらに F9 や保存などで再計算がもう一度走ると、そのたびに同じ分だけ加算されます(実機: B1=10 入力直後 A1=30、明示再計算後 A1=60)。累積入力では最大反復回数を 1 にしておくのが安全です。

解法 B: Worksheet_Change マクロで別セルから足し込む

VBA の Worksheet_Change イベントを使うと、B1 への入力を検知して A1 に足し込み、B1 をクリアする動きが作れます。ファイルは .xlsm(マクロ有効ブック)で保存し、開いたときにマクロ有効化を許可します。

マクロの貼り付け方

  1. Excel で対象のシートを開いた状態で Alt+F11 を押し、VBE(Visual Basic Editor)を起動
  2. 左ペインのプロジェクトツリーで対象シート(例: Sheet1)をダブルクリック
  3. 右ペインのコード領域に下のマクロを貼り付け
  4. ファイルを .xlsm 形式で保存(マクロ有効ブック)
VBE の Sheet1 コードモジュールに Worksheet_Change マクロを貼り付けた画面、左にプロジェクトツリー右にコード

基本版(Macro A)— B1 単独入力に対応するフェイルセーフ設計

もっともシンプルな実装です。Target.Address$B$1 と完全に一致するときだけ A1 に足し込みます。複数セルを一度にペーストした場合は何もしないので、想定外の入力で誤動作することがありません。

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
    On Error GoTo Done
    Application.EnableEvents = False
    If Target.Address = "$B$1" Then
        If IsNumeric(Target.Value) And Len(CStr(Target.Value)) > 0 Then
            Me.Range("A1").Value = Me.Range("A1").Value + Target.Value
            Target.ClearContents
        End If
    End If
Done:
    Application.EnableEvents = True
End Sub

実機確認(Excel 2024 build 19929): B1 に 100 / 50 / 30 を順に入力すると A1 が 100 → 150 → 180 と累積し、B1 はそのつどクリアされます。B1 に文字列(例: abc)を入れた場合は IsNumeric ガードで A1 は変わらず、B1 もクリアされません。B1:B3 への一括ペーストでは $B$1 との完全一致が外れるため A1 は変わりません(フェイルセーフ)。

応用版(Macro B)— B1:B100 への複数セル同時ペーストにも対応

業務で「3 つの数字を一気に貼り付けて、3 つすべて累積したい」ような場合は、For Each cell In Target.Cells で範囲全体を回す版を使います。Intersect で B1:B100 の範囲内に限定し、範囲外のセル編集には反応しません。

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
    On Error GoTo Done
    Application.EnableEvents = False
    Dim cell As Range
    For Each cell In Target.Cells
        If Not Intersect(cell, Me.Range("B1:B100")) Is Nothing Then
            If IsNumeric(cell.Value) And Len(CStr(cell.Value)) > 0 Then
                Me.Range("A1").Value = Me.Range("A1").Value + cell.Value
                cell.ClearContents
            End If
        End If
    Next cell
Done:
    Application.EnableEvents = True
End Sub
B1 から B3 に 10、20、30 を一括ペーストすると A1 が 60 ぶん(10+20+30)一度に増え、B1 から B3 がすべてクリアされた状態

実機確認: A1=100 の状態で B1:B3=(10, 20, 30) を一括ペーストすると、A1 が 160 になり、B1〜B3 はすべてクリアされます。範囲外の D1 への入力では A1 は変化しません。

EnableEvents=False の役割: マクロが Me.Range("A1").Value = ...cell.ClearContents でセルを書き換えると、Excel はその書き換えを「変更」とみなします。すると再び Worksheet_Change が発火し、無限ループになる可能性があります。Application.EnableEvents = False はこの再発火を一時的に止め、無限ループを防ぐ仕組みです。

Microsoft 公式: Worksheet.Change イベント (Excel)

解法 A / B の使い分け

2 解法の特性を 1 枚の表にまとめます。「どちらの解法を選ぶか迷ったらこの表だけ見れば判断できる」核となる 1 枚です。

観点解法 A: 反復計算解法 B: Worksheet_Change
ファイル形式.xlsx(マクロ不要).xlsm 必須(マクロ警告あり)
受け取り側で必要な操作「他のブックも反復計算オンになる」承知が必要マクロ有効化を許可
Ctrl+Z(Undo)で累計値を戻す累計値は戻らない(B1 入力だけ取り消され、A1 はそのまま)戻らない(バックアップセル方式が必要)
既存ブックへの影響Excel 全体に影響する(Application 単位)なし(このブックのみ)
保存時の挙動保存のたびに B1 値が再加算される致命的罠(後述)保存しても A1 は変わらない
同じ値の再入力累積する(B1=100 を続けて 2 回入れると A1+=200)累積する(同じ値でも Worksheet_Change が再発火)
複数セル同時ペーストA1 は B1 値しか拾わない(B2/B3 は =A1+B1 の参照外)For Each ループで全セル合算可(応用版)
入力場所A1(累計セル自身を =A1+B1 で書く)B1(別セル、A1 が累計先)
メンテナンスExcel オプションで切替VBA コードを保守
対象人数1 人(本人のみ)複数人配布も可(マクロ警告対応必要)
推奨ケース1 人で短期間、保存頻度低業務で繰り返し使う、配布前提、Undo 不要
非推奨ケース保存しながら使う運用(致命的)スピル数式と並行運用、Undo 必須

8 つの落とし穴(実機検証 + Microsoft 公式)

2 解法それぞれに、知らずに使うと致命的な罠があります。独自に発見した 6 つ + 2 解法に共通する 2 つを順に整理します。

罠 1(解法 A、最重要): 保存のたびに B1 値が再加算される

解法 A で A1=100、B1=100 の状態のまま保存操作(上書き保存・名前を付けて保存)を実行すると、A1 が 200 に増えます。もう一度保存すると 300 に。実機検証で確認した、本記事の最重大の罠です。

保存前は A1=100 だったのが、保存操作を実行した瞬間に A1=200 に増えるビフォー・アフター画面、+100 の矢印付き

原因: 反復計算オンの状態で保存すると、Excel の「保存前に再計算する」仕様により =A1+B1 がもう 1 回評価され、A1 += B1 が走ります。Microsoft Learn「Excel の再計算」の再計算トリガー一覧にも「保存前に再計算」が明記されています。

回避策(実機確認済の 2 つ):

  1. 保存する直前に B1 を空にする — B1 が空なら =A1+B1 の再計算で A1 は変わりません
  2. 保存する直前に反復計算を一時オフにする — オフの状態で保存すれば再計算しても A1 は不変です

Excel オプションの「保存前に再計算」をオフにする方法(CalculateBeforeSave=False)は、保存トリガーや計算方法によって挙動が変わるため信頼できる回避策ではありません。実機検証では、自動計算 + COM の ExecuteMso("FileSave") 経由では CalculateBeforeSave=False にしても保存時加算が起きました(A1: 360 → 370)。一方で、計算方法 = 手動 + 通常の保存では加算が止まります(A1: 200 のまま)。条件依存で読みにくいため、本記事ではこのプロパティ操作による回避は推奨せず、上記の回避策 1(B1 をクリアしてから保存)または回避策 2(反復計算を一時オフにしてから保存)を使ってください。

罠 2(解法 A): 反復計算は Excel 全体に影響する

反復計算はブック単位ではなく Excel アプリケーション全体の設定です。あなたが反復計算をオンにしたブックを開いている間、同じ Excel で別のブックを開くと、その別のブックでも反復計算が有効になります。反復計算オンのブックを閉じても、別のブックがまだ開いている限り、設定はオンのまま維持されます。

Microsoft 公式(サポートページ)にも「これらのオプションを変更すると、開いているすべてのブックに影響します」と明記されています。

回避策: 累積入力の作業が終わったら、ファイル → オプション → 数式 → 「反復計算を行う」のチェックを手動で外すことを忘れずに。

罠 3(解法 A): 既存の循環参照警告が消える副作用

反復計算をオンにすると、既存ブックに含まれていた循環参照のセルも警告なしで計算されてしまいます。意図せず別のシートで計算が進んでいるケースに気づきにくくなります。詳細は 【Excel】循環参照の警告が消えない――原因セルの探し方と解除手順 で解説しています。

罠 4(解法 B): Ctrl+Z で取り消しはできない

Worksheet_Change で A1 の値を書き換えたり B1 をクリアしたりした後に Ctrl+Z を押しても、A1 の値は元に戻りません。Microsoft 公式の Application.Undo は最後のユーザー操作を取り消すためのもので、マクロの最初の行で使う必要があり、VBA コマンド自体の取り消しには使えません。今回の検証でも、Worksheet_Change 後に Application.Undo を呼ぶ経路では Err=1004 でした。

Microsoft 公式(Application.Undo method、英語)にも次のとおり明記されています:

It cannot be used to undo Visual Basic commands.
(日本語: VBA コマンドの取り消しには使えません)

つまり、Worksheet_Change による値の書き換えは Excel の Undo 履歴に乗らず、Ctrl+Z で戻すことを期待しない方が安全です。

回避策: バックアップセル付きマクロ(Macro C)

1 段だけでも戻せるようにするには、A1 に足し込む直前の値を別のセル(例: C1)に保存しておく実装にします。

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
    On Error GoTo Done
    Application.EnableEvents = False
    Dim cell As Range
    For Each cell In Target.Cells
        If Not Intersect(cell, Me.Range("B1")) Is Nothing Then
            If IsNumeric(cell.Value) And Len(CStr(cell.Value)) > 0 Then
                Me.Range("C1").Value = Me.Range("A1").Value
                Me.Range("A1").Value = Me.Range("A1").Value + cell.Value
                cell.ClearContents
            End If
        End If
    Next cell
Done:
    Application.EnableEvents = True
End Sub

使い方: 1 段戻したいときは、A1 をクリックして =C1 と手で入力します。直前の A1 値が C1 に残っているので、A1 が 1 つ前の値に戻ります。実機検証で動作確認済み(A1=180 / C1=150 の状態で A1==C1 → A1=150)。

もっと履歴を残したい場合は、別シートに「日時、入力値、A1 の累計」の 3 列で記録する実装も可能です(h2-6 のケース 4 を参照)。

罠 5(解法 B): スピル数式で値が入ったセルでは発火しない

Worksheet_Changeスピルの親セルが変更されたときには発火しますが、スピル展開先のセルでは発火しません。たとえば D1 に =SEQUENCE(3) を入力すると D1:D3 に値がスピルしますが、Worksheet_Change のイベントは D1 に対してだけ 1 回発火し、D2 / D3 の展開値については発火しません。

影響: 「スピル数式を流して B1 に値が入る」ような設計では Worksheet_Change が反応しないので、累積マクロが動きません。直接 B1 に値を入力する設計を維持してください。

罠 6(解法 A、隠れ罠): 任意のセル編集で A1 が静かに +B1 ずつ増える

解法 A で意外と気づきにくいのが、シートのどこを編集しても A1 が +B1 ずつ増えていく挙動です。

実機検証では、A1=117 の状態から次の 3 操作を順番に行いました。

  • B1=5 を入力 → A1=122(B1 は =A1+B1 の参照内なので想定どおり)
  • B2=99 を入力 → A1=127(B2 は =A1+B1 の参照外なのに +5 増えた)
  • B3=88 を入力 → A1=132(さらに +5)

原因: B2 や B3 の編集でも Excel の再計算チェーンが走り、=A1+B1 が再評価されて A1 += B1 が起きるためです。保存しなくても、シートを操作しているだけで累積する致命的罠です。

回避策: 反復計算は本当に短時間(B1 入力 → 確認 → 即オフ)だけオンにする。長時間オンのままにしない。複数の作業を 1 シートで行う場合は解法 B(マクロ)を選ぶ。

罠 7(解法 A): B1:B3 一括ペーストでも A1 は B1 値しか拾わない

「3 つの数字を一括で B1:B3 にペーストすれば A1 に 3 つとも足し込まれる」と思いがちですが、解法 A の =A1+B1 の式は B1 しか参照していません。実機: B1:B3=(10, 20, 30) を一括ペーストすると、A1 += 10 だけ起きて、B2 と B3 の値は無視されます。

解決: 複数値の合算が必要なら、式を =A1+SUM(B1:B3) に変更します(実機: A1 += 60 で全合算)。ただしこの式に変えても罠 6(任意セル編集)と罠 8(同値再入力)は引き継ぎます。複数セル合算が業務上必須なら解法 B(マクロ B)の方が安全です。

罠 8(両解法共通): 同じ値を再入力すると累積する

B1=100 を入力した後、再び B1=100 を入力すると、A1 はさらに +100 されます。Enter を 2 度押した、コピー&ペーストで同じ値を貼った、などの操作で想定外の累積が起きやすい点に注意してください。

それでもうまく動かないとき + まとめ

「保存しても A1 が増えない」ときの確認順序

  1. B1 が空ではないか — B1 が空だと =A1+B1 の再計算で A1 は変わりません
  2. 反復計算が OFF になっていないか — Application 単位設定なので、別の操作で OFF にされた可能性
  3. A1 の式が =A1+B1 のままか — 上書きで式が消えた可能性
  4. 計算方法が手動になっていないか — 手動計算では入力直後の加算が走らず A1 は変わりません。ただし CalculateBeforeSave=True(既定)のままだと保存時に再計算が走り A1 が加算されます(実機確認済み)
  5. CalculateBeforeSaveFalse にしていないか — 既定は TrueFalse にすると保存トリガーによっては加算が止まることがあります(条件依存。詳細は 罠 1 注記を参照)

その他のケース

  • 「反復計算がオンにできない」 → 保護ビュー、編集制限、共有ブック(レガシ機能)など、ブックの編集状態を確認
  • 「マクロが動かない」 → マクロの有効化と Worksheet_Change をシートのコードモジュールに貼り付けたかを確認
  • 「累積ではなく履歴を残したい」 → 履歴シート方式(別シートに「日時、入力値、A1 の累計」の 3 列で記録するマクロ)に変更

関連記事

2 解法のおすすめ早見

  • 1 人で短期間 + 保存頻度低 → 解法 A(反復計算)。使い終わったら手動で OFF
  • 配布前提 + 業務で繰り返し使う + Ctrl+Z 期待しない → 解法 B(Macro A 基本版)。複数セルペーストにも対応したいなら Macro B(応用版)
  • 1 段でも戻せるようにしたい → 解法 B(Macro C バックアップ付き)
  • 本格的な履歴管理が必要 → 履歴シート方式に切り替え

コピー用コード再掲

反復計算解法の数式:

=A1+B1

Worksheet_Change 基本版(Macro A、フェイルセーフ):

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
    On Error GoTo Done
    Application.EnableEvents = False
    If Target.Address = "$B$1" Then
        If IsNumeric(Target.Value) And Len(CStr(Target.Value)) > 0 Then
            Me.Range("A1").Value = Me.Range("A1").Value + Target.Value
            Target.ClearContents
        End If
    End If
Done:
    Application.EnableEvents = True
End Sub

Worksheet_Change 応用版(Macro B、複数セル対応):

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
    On Error GoTo Done
    Application.EnableEvents = False
    Dim cell As Range
    For Each cell In Target.Cells
        If Not Intersect(cell, Me.Range("B1:B100")) Is Nothing Then
            If IsNumeric(cell.Value) And Len(CStr(cell.Value)) > 0 Then
                Me.Range("A1").Value = Me.Range("A1").Value + cell.Value
                cell.ClearContents
            End If
        End If
    Next cell
Done:
    Application.EnableEvents = True
End Sub

Worksheet_Change バックアップ付き(Macro C、Undo 代替):

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
    On Error GoTo Done
    Application.EnableEvents = False
    Dim cell As Range
    For Each cell In Target.Cells
        If Not Intersect(cell, Me.Range("B1")) Is Nothing Then
            If IsNumeric(cell.Value) And Len(CStr(cell.Value)) > 0 Then
                Me.Range("C1").Value = Me.Range("A1").Value
                Me.Range("A1").Value = Me.Range("A1").Value + cell.Value
                cell.ClearContents
            End If
        End If
    Next cell
Done:
    Application.EnableEvents = True
End Sub

1 段戻したいときは、A1 をクリックして =C1 と手で入力すると、直前の A1 の値が復元されます。

Next Read

このあと読む記事

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

Keep Exploring

このテーマをさらに探す

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