こんにちは、SkillStack Lab運営者のスタックです。
※本記事には広告・アフィリエイトリンクが含まれています。
Excelでセルへ入力したときに、「別のセルへ同じ値を表示したい」「自動で計算したい」「別シートへ履歴として追加したい」と考えていませんか。
結論から言うと、単純に値を表示・計算するだけなら数式、入力をきっかけに転記や履歴保存まで行うならVBAマクロを使うのが基本です。
VBAで自動反映する場合は、セルが変更されたときに動くWorksheet_Changeイベントを使用します。
ただし、コードをコピーするだけでは、無限ループ、二重転記、イベントが無効のまま戻らない、複数セルを貼り付けたらエラーになるといった問題が起こることがあります。
この記事では、別セルへの反映、同じ行での自動計算、別シートへの履歴追加という3つのコードと、安全に運用するための注意点を順番に解説します。

- 関数とVBAのどちらを使うべきか
- 入力した値を別のセルへ自動反映するコード
- 入力内容を別シートへ履歴として追加するコード
- Worksheet_Changeを貼り付ける場所
- 無限ループや二重転記を防ぐ方法
- マクロが動かない場合の確認項目
この記事の3つのコード例は、それぞれ単独で使うサンプルです。
同じシートモジュールへ複数のPrivate Sub Worksheet_Changeをそのまま貼り付けることはできません。複数の処理を同じシートで使う場合は、1つのWorksheet_Change内へ処理をまとめてください。
最初に確認|関数とマクロのどちらを使うか
別のセルへ反映するだけなら、必ずしもVBAは必要ありません。
作りたい処理に応じて、必要な機能を満たす中で最も簡単な方法を選びましょう。
| やりたいこと | 第一候補 | 設定例 |
|---|---|---|
| A2の内容をD2にも表示する | 数式 | =A2 |
| 入力シートのA2を別シートに表示する | 数式 | ='入力'!A2 |
| 単価と数量から金額を計算する | 数式 | =B2*C2 |
| 入力した瞬間に値を固定する | VBA | Worksheet_Change |
| 入力内容を別シートの最終行へ追加する | VBA | 最終行取得+転記 |
| 入力後にフォームを空欄へ戻す | VBA | ClearContents |
| 複数ファイルを毎月結合する | Power Query | フォルダーから取得 |
表示結果が元セルと連動して変わってよいなら数式、入力時点の値を固定したり履歴として残したりするならVBAと考えると判断しやすくなります。
関数で解決できる処理へ無理にマクロを導入すると、修正できる人が限られ、ファイル管理も複雑になります。
すぐ使える自動反映マクロ3種類
ここからは、よく使われる3つの処理を紹介します。
それぞれ独立したサンプルなので、まず自分が実現したい処理に近いものを1つ選び、後述する対象シートのシートモジュールへ貼り付けてください。
1.入力したら同じ行で自動計算する

次のコードは、B列の単価またはC列の数量を変更すると、同じ行のD列へ金額を表示します。
2行目から1000行目までを対象にし、B列・C列へ複数行をまとめて貼り付けた場合にも処理できる構成です。
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim changedRange As Range
Dim changedCell As Range
Dim rowNumber As Long
Set changedRange = Intersect(Target, Me.Range("B2:C1000"))
If changedRange Is Nothing Then Exit Sub
On Error GoTo SafeExit
Application.EnableEvents = False
For Each changedCell In changedRange.Cells
rowNumber = changedCell.Row
If Len(Me.Cells(rowNumber, "B").Value) = 0 _
Or Len(Me.Cells(rowNumber, "C").Value) = 0 Then
Me.Cells(rowNumber, "D").ClearContents
ElseIf IsNumeric(Me.Cells(rowNumber, "B").Value) _
And IsNumeric(Me.Cells(rowNumber, "C").Value) Then
Me.Cells(rowNumber, "D").Value = _
CDbl(Me.Cells(rowNumber, "B").Value) * _
CDbl(Me.Cells(rowNumber, "C").Value)
Else
Me.Cells(rowNumber, "D").ClearContents
End If
Next changedCell
SafeExit:
Application.EnableEvents = True
End Sub
単純な掛け算だけなら、D2へ=B2*C2と入力して下までコピーする方が簡単です。
計算結果を値として固定したい場合や、入力後にほかの処理も続けたい場合にVBAを選びましょう。
ここからVBAをもう少し体系的に学び、転記・集計・複数ファイル処理まで自分で組めるようになりたい方は、UdemyでVBAを学ぶおすすめ講座と選び方も参考にしてください。
2.入力値を別のセルへ反映する
次のコードは、A2に入力した内容を同じシートのD2へ値としてコピーします。
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Me.Range("A2")) Is Nothing Then Exit Sub
On Error GoTo SafeExit
Application.EnableEvents = False
Me.Range("D2").Value = Me.Range("A2").Value
SafeExit:
Application.EnableEvents = True
End Sub
反映先を別シートにする場合は、転記部分を次のように変更します。
ThisWorkbook.Worksheets("集計").Range("D2").Value = Me.Range("A2").Value
集計は実際のシート名、D2は反映先のセル番地へ置き換えてください。
同じ値を常に表示したいだけならVBAは不要です。
D2へ=A2と入力すれば、A2の変更に合わせてD2も自動更新されます。VBAは「入力時点の値を固定したい」「転記後に別の処理を行いたい」ときに使いましょう。
数式で変化したセルはWorksheet_Changeの対象外
Worksheet_Changeは、ユーザーがセルへ入力した場合など、ワークシートのセルそのものが変更されたときに発生します。
数式の再計算によって表示結果だけが変わった場合は発生しません。
そのため、監視対象には基本的にユーザーが直接入力するセルを指定してください。再計算をきっかけに処理したい場合は、Worksheet_Calculateなど別のイベントを検討します。
3.入力内容を別シートへ履歴として追加する

次は、入力フォームのA2からC2を、別シートの最終行へ履歴として追加するコードです。
A2を日付、B2を商品名、C2を数量とし、C2を最後に入力するセルとして使用します。
転記先の「データベース」シートは、1行目を見出し、2行目以降をデータ行として使う前提です。
A2・B2・C2がすべて入力された状態でC2を変更すると、「データベース」シートへ1行追加し、転記後は入力欄を空欄へ戻します。
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Const DATABASE_SHEET As String = "データベース"
Dim wsData As Worksheet
Dim nextRow As Long
Dim errorNumber As Long
Dim errorDescription As String
If Intersect(Target, Me.Range("C2")) Is Nothing Then Exit Sub
If Len(Me.Range("A2").Value) = 0 Then Exit Sub
If Len(Me.Range("B2").Value) = 0 Then Exit Sub
If Len(Me.Range("C2").Value) = 0 Then Exit Sub
On Error GoTo ErrorHandler
Application.EnableEvents = False
Set wsData = ThisWorkbook.Worksheets(DATABASE_SHEET)
nextRow = wsData.Cells(wsData.Rows.Count, "A").End(xlUp).Row + 1
wsData.Cells(nextRow, "A").Resize(1, 3).Value = _
Me.Range("A2:C2").Value
wsData.Cells(nextRow, "D").Value = Now
Me.Range("A2:C2").ClearContents
SafeExit:
Application.EnableEvents = True
If errorNumber <> 0 Then
MsgBox "転記中にエラーが発生しました。" & vbCrLf & _
errorDescription, vbExclamation
End If
Exit Sub
ErrorHandler:
errorNumber = Err.Number
errorDescription = Err.Description
Resume SafeExit
End Sub
このコードでは、「データベース」シートのA列で最後に使用している行を調べ、その1行下へ新しいデータを追加します。そのため、1行目には「日付」「商品名」「数量」「登録日時」などの見出しを入れておいてください。
また、処理途中にエラーが起きた場合でも、最後にApplication.EnableEvents = Trueへ戻る構成にしています。
転記後にA2:C2を空欄へ戻す処理も、イベントを一時停止している間に実行するため、ClearContentsによって同じイベントが再び動くことを防げます。
C2は最後に入力してください。
C2を入力した後でA2やB2を変更しても、このコードでは自動転記されません。「最後に入力するセル」を明確にできない業務では、登録ボタンを押して転記する方法の方が安全です。
二重転記を防ぐポイント
A2からC2のどのセルを変更しても転記する設定にすると、3項目を入力する間に複数回記録される可能性があります。
そのため、最後に入力するセル、ステータス欄、登録済みフラグ、登録ボタンなど、処理を確定させるきっかけを1つ決めることが重要です。
Worksheet_Changeを複数使いたい場合の注意点
ここまで紹介した3つのコードには、それぞれ次のような記述があります。
Private Sub Worksheet_Change(ByVal Target As Range)
同じシートモジュールへ、このイベントを3つ並べて貼り付けることはできません。
例えば「A2をD2へ反映する処理」と「C列を変更したら日付を記録する処理」の両方を同じシートで使いたい場合は、1つのWorksheet_Changeの中でそれぞれの監視範囲を判定します。
最初はこの記事のサンプルを1つだけ使って動作を確認してください。複数処理を組み合わせる段階になったら、同じイベントへ条件を追加していく方がトラブルを切り分けやすくなります。
マクロを貼り付ける場所と設定手順
Worksheet_Changeは、一般的なマクロを記述する標準モジュールではなく、入力を監視するシートのシートモジュールへ記述します。

- 念のため、元のExcelファイルを複製する
- Excelで対象ファイルを開く
- Alt+F11を押してVisual Basic Editorを開く
- 左側のプロジェクト一覧から対象ブックを探す
- 入力を監視する「Sheet1」などをダブルクリックする
- 表示されたコード画面へ使用するサンプルを貼り付ける
- セル番地とシート名を自分のファイルに合わせて変更する
- Excelマクロ有効ブック形式で保存する
- コピーしたテスト用ファイルで動作を確認する
すでに対象シートにPrivate Sub Worksheet_Changeが存在する場合は、新しいイベントを追加せず、既存イベントの処理内容を確認してください。
マクロ有効ブックで保存する

VBAコードを残すには、ファイルをExcelマクロ有効ブック(.xlsm)として保存します。
通常のExcelブック(.xlsx)として保存すると、VBAコードを保持できません。
Microsoft公式「マクロの保存」でも、マクロを含むブックはExcelマクロ有効ブック(.xlsm)として保存する手順が案内されています。
Worksheet_Changeの仕組み
コードを安全に修正するために、最低限理解しておきたい4つの要素を確認しましょう。

Targetは変更されたセルを表す
Targetには、今回変更されたセルまたはセル範囲が渡されます。
A2を変更した場合はA2、A2からC2をまとめて貼り付けた場合はA2:C2がTargetになります。
そのため、コードを1セル入力だけで設計すると、複数セルのコピー&ペーストで想定外の動作をする場合があります。
Intersectで監視範囲を限定する
Intersectは、変更されたセルと監視対象のセルが重なっているかを確認するときに使います。
If Intersect(Target, Me.Range("A2:A10")) Is Nothing Then Exit Sub
このコードでは、A2からA10以外が変更された場合、すぐに処理を終了します。
監視範囲を限定することで、関係のないセル編集によってマクロが動くことを防げます。
Meで対象シートを明確にする
シートモジュール内のMeは、そのコードが記述されているワークシートを表します。
Range("A2")だけで記述するより、Me.Range("A2")とした方が、どのシートを操作しているのか分かりやすくなります。
ThisWorkbookでコード側のブックを指定する
ThisWorkbookは、実行中のVBAコードが保存されているブックを表します。
作業中に別のブックが前面へ表示されても、転記先が意図せず別のブックになることを防ぎやすくなります。
関数とVBAの違い

| 比較項目 | Excel関数 | VBAマクロ |
|---|---|---|
| 別セルへの表示 | 簡単 | 可能だが過剰になりやすい |
| 再計算 | 元データに合わせて変化 | 処理時点の値を固定できる |
| 履歴の追加 | 不向き | 最終行へ追加できる |
| 入力欄の初期化 | できない | 処理後に消去できる |
| 帳票・PDF・ファイル操作 | 不向き | 対応しやすい |
| 保守 | セル上で確認しやすい | VBAを読める担当者が必要 |
| セキュリティ | 通常の数式として動作 | マクロの実行可否を管理する必要がある |
VBAが常に関数より優れているわけではありません。
「入力した瞬間の値を固定したい」「履歴を下へ追加したい」「入力後に別の操作を続けたい」という場合に、VBAの利点が出ます。
日付や入力履歴を自動で残す方法

ステータスを「完了」に変更したとき、右隣のセルへ完了日を記録する例です。
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.CountLarge > 1 Then Exit Sub
If Intersect(Target, Me.Range("C2:C100")) Is Nothing Then Exit Sub
On Error GoTo SafeExit
Application.EnableEvents = False
If Target.Value = "完了" Then
Target.Offset(0, 1).Value = Date
Else
Target.Offset(0, 1).ClearContents
End If
SafeExit:
Application.EnableEvents = True
End Sub
Dateは日付、Nowは日付と時刻を記録します。
ただし、Excel上の日付やパソコンのユーザー名だけでは、改ざん防止まで含めた正式な監査ログにはなりません。
給与、請求、勤怠、個人情報などの重要業務で変更履歴が必要な場合は、権限管理や操作ログを備えたシステムも比較してください。
無限ループを防ぐ方法

Worksheet_Changeの処理内で別のセルを書き換えると、その変更によってイベントが再び動く場合があります。
これを防ぐために使うのがApplication.EnableEventsです。
On Error GoTo SafeExit
Application.EnableEvents = False
' セルを書き換える処理
SafeExit:
Application.EnableEvents = True
重要なのは、イベントを停止することだけではありません。
エラーが発生した場合にも、必ずTrueへ戻る経路を作ることが重要です。
Falseのまま処理が終了すると、その後のWorksheet_Changeなどのイベントが発生しなくなります。
Microsoft Learn「Application.EnableEventsプロパティ」
マクロが動かない場合の確認項目

- シートモジュールへ貼り付けているか:標準モジュールではWorksheet_Changeイベントとして動きません
- 監視するセルが合っているか:A2とA3など、セル番地の間違いを確認します
- シート名が完全に一致しているか:空白や全角・半角も含めて確認します
- .xlsmで保存しているか:.xlsxではVBAコードを保持できません
- マクロが許可されているか:提供元と内容を確認してから実行します
- EnableEventsがFalseになっていないか:途中のエラー後にイベントが停止している可能性があります
- 数式結果の変化を監視していないか:再計算だけではWorksheet_Changeは発生しません
- 同じイベントが重複していないか:同じシートに同名のWorksheet_Changeを複数記述できません
- 複数セルを貼り付けていないか:コードが1セル入力だけを前提にしていないか確認します
- 結合セルを使っていないか:Targetの範囲が想定と異なる場合があります
イベントが無効になっている場合は、VBEのイミディエイトウィンドウへ次のコードを入力し、Enterキーを押すとイベントを再度有効にできます。
Application.EnableEvents = True
Microsoft Learn「Worksheet.Changeイベント」
Excel for the webではVBAを実行できない
今回紹介しているVBAコードは、デスクトップ版Excelでの利用を前提としています。
Excel for the webでは、VBAマクロを含むブックを開いて編集することはできますが、VBAマクロを作成・実行・編集することはできません。
ブラウザ中心でExcel業務を自動化したい場合は、Office ScriptsやPower Automateなども比較してください。
Microsoft公式「Excel for the webでVBAマクロを操作する」
実務で使用する前の注意点
コードが一度動いたことと、会社の業務で安全に使えることは同じではありません。
- 元ファイルを残してテスト用コピーで動かす
- 空欄、文字列、0、負数などでも確認する
- 複数セルの貼り付けを試す
- シート名や列を変更した場合の動作を確認する
- 転記先が存在しない場合のエラーを確認する
- 同じデータが二重登録されないか確認する
- 処理後に件数や合計を照合する
- コードの目的と変更箇所を記録する
- 作成者以外でも実行・復旧できるようにする
- 信頼できないファイルのマクロを安易に有効化しない
Microsoftも、マクロの動作が分からない場合や、提供元を信頼できない場合は、安易にマクロを有効化しないよう案内しています。
Microsoft公式「Microsoft 365ファイルでマクロを有効または無効にする」
複数人で同時に更新する業務や、停止すると給与・請求・顧客対応へ影響する業務では、Excelマクロだけで作り込まない判断も必要です。
業務別にVBA、Power Query、Power Automate、Python、SaaSを比較したい方は、Excel自動化の方法を用途別に比較した記事を確認してください。
VBA以外の方法が向いているケース
今回のような小規模な入力反映はVBAが得意です。
一方、処理の内容によっては、別の方法を選んだ方が作成と保守の負担を減らせます。
| 業務の状態 | 候補 | 理由 |
|---|---|---|
| 別セルへ値を表示するだけ | 関数 | コードが不要 |
| 毎月同じ形式のファイルを結合する | Power Query | 取得と整形の手順を再利用しやすい |
| Excel内の細かなセル操作を行う | VBA | デスクトップ版Excelの操作に向く |
| 大量のCSVや外部データを処理する | Python | Excel外のデータも扱いやすい |
| Microsoft 365上で処理を共有する | Office Scripts・Power Automate | クラウド上の処理や連携を設計しやすい |
| 勤怠・会計・問い合わせを管理する | SaaS | 権限・履歴・同時利用を標準化しやすい |
スタック自分や少人数だけが使う小さな作業なら、今回のようなVBAは今でも有効です。ただし、利用者や処理件数が増え、止まったときの影響が大きくなったら、VBAを継ぎ足す前に別の方法も比較した方が保守しやすくなります。
Pythonへ変更しただけで属人化がなくなるわけでもありません。どの手段でも、コメント、テスト、バックアップ、権限管理、引き継ぎが必要です。
VBAを続けるべき業務と別の手段へ移行すべき業務は、VBAを残すかやめるかを業務別に判断する記事で詳しく解説しています。
ほかの実務向けマクロも試したい方は、Excel便利マクロ8選も参考にしてください。
コードをコピーするだけでなく、変数・条件分岐・繰り返し・エラー処理まで基礎から理解したい方は、UdemyでVBAを学ぶ方法と講座選びで初心者向けの選び方を整理しています。
勤怠、会計、問い合わせ管理などをExcelで作り込んでいる場合は、バックオフィス向け脱Excelツールの比較から、自作を続ける場合との違いを確認できます。
入力したら自動反映するマクロのよくある質問
まとめ|小さな反映はVBAで安全に自動化する
Excelで入力した内容を別のセルや別シートへ反映する方法は、処理の目的によって異なります。
- 単純な表示や計算なら関数を使う
- 入力した瞬間に処理するならWorksheet_Changeを使う
- 3つのコード例は単独サンプルとして使う
- 複数処理を使う場合は1つのWorksheet_Changeへまとめる
- 監視範囲はIntersectで限定する
- セルを書き換える間はEnableEventsを停止する
- エラー時にも必ずEnableEventsをTrueへ戻す
- 履歴転記は処理を確定させるセルを1つ決める
- 本番利用前にコピーとダミーデータで確認する
- 複数人で使う重要業務は別の手段も比較する
最初から大きな仕組みを作らず、1つの入力と1つの反映からテストすることが、トラブルを減らす近道です。
今回のようなコードを自分の業務に合わせて修正できるようになりたい場合は、コピー&ペーストだけで終わらせず、変数、条件分岐、繰り返し、イベント、エラー処理の基礎を一度体系的に学ぶと応用しやすくなります。
\ VBAを基礎から理解したい人向け /








