どんな場面で使う?
- データ入力のたびに更新日時を自動記録したい(手動でタイムスタンプを打つ手間をなくす)
- ステータスを変更したら即座に行の色が変わるようにしたい
- 特定のセルに値が入力されたらバリデーションチェックを自動で走らせたい
- 在庫数や売上額を入力した瞬間に基準値超えの警告を出したい
—
完成イメージ(Before / After)
Before(実行前)

A列にデータを入力しても、B列は空のまま。タイムスタンプは手動で入力する必要がある。
| A(データ) | B(更新日時) | |
|---|---|---|
| 1 | データ | 更新日時 |
| 2 | りんご | |
| 3 | みかん | |
| 4 | バナナ |
After(実行後)

A列にデータを入力・変更すると、B列に自動で日時が記録される。手動入力は不要。
| A(データ) | B(更新日時) | |
|---|---|---|
| 1 | データ | 更新日時 |
| 2 | りんご | 2026/02/19 10:30:15 |
| 3 | みかん | 2026/02/19 10:30:22 |
| 4 | バナナ | 2026/02/19 10:31:05 |
—
実行前の準備
バックアップを取る
既存のデータが入っているExcelファイルで試す場合は、先にファイルをコピーしてバックアップを取ること。
Excelをマクロ有効ブック(.xlsm)で保存する
- Excelを開く(新規でも既存でもOK)
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を 「Excel マクロ有効ブック (*.xlsm)」 に変更して保存
.xlsx のままだとマクロが保存されない。必ず .xlsm にすること。
シート(A列・B列)を準備する
| A | B | |
|---|---|---|
| 1 | データ | 更新日時 |
| 2 | (ここに入力する) | (自動で入る) |
A1に「データ」、B1に「更新日時」とヘッダーを入力しておく。
—
手順(コピペ → 動作確認まで約5分)
VBE(コードを書く画面)を開く
Alt + F11 キーを押すとVBE(Visual Basic Editor)が開く。
一般的にはAlt + F11で開けるが、企業のセキュリティ設定でVBAが無効化されている場合は、IT部門に確認すること。
★ シートモジュールを開く(標準モジュールではない)
ここが最大のポイント。 通常のマクロは「標準モジュール」に書くが、Worksheet_Change はシートモジュールに書く。
- VBE の左側に「プロジェクトエクスプローラー」が表示されている
- 対象のシート名(例:Sheet1 (Sheet1))をダブルクリックする
- 右側にコードウィンドウが開く → ここにコードを貼り付ける
間違いやすいポイント:
- 「挿入」→「標準モジュール」は使わない
- 左のツリーで「Sheet1」をダブルクリックする
- シート名を変更している場合は、VBE上で「Sheet1 (売上管理)」のように表示名が変わっている
コードを貼り付ける
下の「コード(最小版)」をコピーして、シートモジュールのコードウィンドウに貼り付ける。
動作を確認する
- VBEからExcelの画面に戻る(Alt + F11 または タスクバーでExcelをクリック)
- A2セルに何か入力してEnterを押す
- B2セルに現在日時が自動で表示されれば成功
—
コード(最小版)– A列変更でB列にタイムスタンプ自動記録
まずはこれだけで動く。A列のセルが変わったら、同じ行のB列に現在日時を自動で記録する。
★ 貼り付け先はシートモジュール(標準モジュールではない)
Private Sub Worksheet_Change(ByVal Target As Range)
' A列(1列目)以外の変更は無視
If Target.Column <> 1 Then Exit Sub
' ヘッダー行(1行目)は無視
If Target.Row < 2 Then Exit Sub
' 複数セルの同時変更(貼り付け等)は無視
If Target.Count > 1 Then Exit Sub
' --- イベントを一時停止(無限ループ防止) ---
Application.EnableEvents = False
On Error GoTo ErrHandler
' B列(同じ行)に現在日時を記録
Target.Offset(0, 1).Value = Now
' A列が空欄になったらB列もクリア
If Target.Value = "" Then
Target.Offset(0, 1).ClearContents
End If
CleanUp:
' --- イベントを再開 ---
Application.EnableEvents = True
Exit Sub
ErrHandler:
Application.EnableEvents = True
End Sub
重要:EnableEvents について
Application.EnableEvents = False は、イベントの発火を一時的に止める命令。これがないと、B列に値を書き込んだ瞬間に再びWorksheet_Changeが発火し、無限ループになる。処理が終わったら必ず True に戻すこと。
コードの動作:
- A列のセルが変更される → Worksheet_Change が自動で実行される
- A列以外、ヘッダー行、複数セル同時変更の場合は何もしない
- EnableEvents を False にして無限ループを防止
- B列に現在日時を記録
- A列が空欄にされた場合はB列もクリア
- EnableEvents を True に戻して終了
—
コード(実務版)– 入力値チェック+色変更+タイムスタンプ
業務で使うなら、値に応じた色分けとステータス自動記入があると便利。A列の数値に応じて行の色を変え、B列にタイムスタンプ、C列にステータスを記録する。
シートのレイアウト(実務版):
| A | B | C | |
|---|---|---|---|
| 1 | 数値 | 更新日時 | ステータス |
| 2 | 120 | 2026/02/19 10:30 | 要確認 |
| 3 | 75 | 2026/02/19 10:31 | 注意 |
| 4 | 30 | 2026/02/19 10:32 | 正常 |
★ 貼り付け先はシートモジュール(標準モジュールではない)
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Range
Dim cell As Range
Dim val As Variant
' A列(1列目)以外の変更は無視
If Target.Column <> 1 Then Exit Sub
' ヘッダー行(1行目)は無視
If Target.Row < 2 Then Exit Sub
' --- イベントを一時停止(無限ループ防止) ---
Application.EnableEvents = False
On Error GoTo ErrHandler
' --- 変更されたセルが複数の場合にも対応 ---
Set rng = Intersect(Target, Me.Range("A2:A" & Me.Rows.Count))
If rng Is Nothing Then GoTo CleanUp
For Each cell In rng
val = cell.Value
' --- B列にタイムスタンプ記録 ---
cell.Offset(0, 1).Value = Now
' --- 値が空欄の場合:色とステータスをクリア ---
If val = "" Then
cell.EntireRow.Interior.ColorIndex = xlNone
cell.Offset(0, 1).ClearContents
cell.Offset(0, 2).ClearContents
GoTo NextCell
End If
' --- 値が数値でない場合:色とステータスをクリア ---
If Not IsNumeric(val) Then
cell.EntireRow.Interior.ColorIndex = xlNone
cell.Offset(0, 2).Value = "(数値以外)"
GoTo NextCell
End If
' --- 数値に応じて色分け+ステータス ---
Select Case CDbl(val)
Case Is >= 100
' 100以上 → 薄い赤 + 要確認
cell.EntireRow.Interior.Color = RGB(255, 200, 200)
cell.Offset(0, 2).Value = "要確認"
Case Is >= 50
' 50〜99 → 薄い黄色 + 注意
cell.EntireRow.Interior.Color = RGB(255, 255, 200)
cell.Offset(0, 2).Value = "注意"
Case Else
' 50未満 → 色なし + 正常
cell.EntireRow.Interior.ColorIndex = xlNone
cell.Offset(0, 2).Value = "正常"
End Select
NextCell:
Next cell
CleanUp:
' --- イベントを再開 ---
Application.EnableEvents = True
Exit Sub
ErrHandler:
Application.EnableEvents = True
Resume NextCell
End Sub
自分はこの実務版を在庫管理表に入れたところ、数値を入力した瞬間に行が色分けされるので、基準値を超えた項目にすぐ気づけるようになった。翌日のチェックで発覚していたミスが、入力時点で分かるのは想像以上にありがたい。
追加ポイント:
- 複数セルの貼り付け操作にも対応(
For Each cell In rngでループ処理) - 数値の大きさに応じて行全体を色分け(100以上:赤、50〜99:黄、50未満:色なし)
- C列にステータス(「要確認」「注意」「正常」)を自動記入
- 値が空欄 or 数値以外の場合は色とステータスをクリア
- エラー発生時はその行をスキップして次のセルに進む
色の閾値を変更したい場合: Case Is >= 100 の数値を業務に合った基準に書き換える。
処理が重いと感じたら: 対象行が多い場合やシートのデータ量が大きい場合は、画面更新・再計算を止めてマクロを高速化する方法の Application.ScreenUpdating = False を組み合わせると体感速度が改善する。
—
もし無限ループに入ったら(対処法)
EnableEvents を書き忘れた、またはエラーでTrue に戻らなかった場合、Excelがフリーズすることがある。
対処手順:
- Ctrl + Break を押す(多くのキーボードで中断できる)
- Ctrl + Break が効かない場合(ノートPCでBreakキーがない等)→ Ctrl + Alt + Delete →「タスク マネージャー」→ Excel を選択 →「タスクの終了」
- Excelを再起動し、ファイルを開き直す
- VBE(Alt+F11)を開き、「表示」→「イミディエイト ウィンドウ」(Ctrl+G)で以下を入力して Enter:
Application.EnableEvents = True
これでイベントが復旧する。
—
よくある落とし穴5選
自分が初めてWorksheet_Changeを書いたとき、Application.EnableEvents = False を入れ忘れた。B列にタイムスタンプを書き込んだ瞬間にまたイベントが発火して、Excelが完全にフリーズした。電源ボタンで強制終了するしかなく、保存前のデータが飛んだ。以来、Worksheet_Changeを書くときは最初にEnableEvents = Falseを入れるのを絶対のルールにしている。
| # | 症状 | 原因 | 対策 |
|---|---|---|---|
| 1 | コードを貼り付けたのに何も起きない | 標準モジュールに貼り付けている。Worksheet_Change はシートモジュール専用 | VBE の左ツリーで対象シート(例:Sheet1)をダブルクリックして、そこに貼り付ける |
| 2 | Excelがフリーズする(無限ループ) | EnableEvents = False を書いていない、またはエラーで True に戻っていない | コードの先頭に Application.EnableEvents = False、末尾と ErrHandler の両方に True を必ず書く。フリーズしたら Ctrl+Break で中断(上の「もし無限ループに入ったら」参照) |
| 3 | 複数セルを貼り付けるとエラーになる | 最小版は Target.Count > 1 で複数セルを除外しているが、実務版に差し替え忘れた |
複数セル対応が必要な場合は実務版コードを使う |
| 4 | 他のマクロのイベントも動かなくなった | EnableEvents = False のまま処理が中断(エラー等)し、True に戻っていない | VBE の「イミディエイト ウィンドウ」(Ctrl+G)で Application.EnableEvents = True と入力して Enter |
| 5 | 数式の結果が変わっても反応しない | Worksheet_Change は値の直接入力にのみ反応する。数式の再計算は対象外 | 数式の結果に反応させたい場合は Worksheet_Calculate イベントを使う(別の仕組み) |
VBAのWorksheet_Changeが反応しないときの対処法
「コードを貼り付けたのにセルを変更しても何も起きない」という場合、原因は標準モジュールに貼り付けていることが多い。Worksheet_Changeはシートモジュール専用のイベントで、標準モジュールでは動作しない。VBEの左ツリーで対象シート(例:Sheet1)をダブルクリックして、そのコードウィンドウに貼り付け直せば解決する。
VBAのWorksheet_Changeで無限ループになったときの対処法
「Excelがフリーズして操作できなくなった」という場合、原因は Application.EnableEvents = False を書き忘れていることだ。B列に値を書き込んだ瞬間に再びイベントが発火して無限ループになる。Ctrl+Breakで中断し、イミディエイトウィンドウで Application.EnableEvents = True を実行すれば復旧する。
—
FAQ
Q1: 特定の列だけに反応させたい場合は?
If Target.Column <> 1 Then Exit Sub の 1 を変更する。B列なら 2、C列なら 3。複数列に反応させたい場合は If Target.Column <> 1 And Target.Column <> 3 Then Exit Sub(A列とC列の場合)。
Q2: 特定の値が入力されたときだけ反応させたい場合は?
If Target.Value = "完了" Then のように条件分岐を追加する。例えば、A列に「完了」と入力されたらB列に日時を記録し、それ以外の値では何もしない、という使い方ができる。特定の文字列を検索してハイライトしたい場合は 【VBA】特定の文字を含むセルを検索してハイライトする方法 も参考になる。
Q3: イベントが突然動かなくなった
EnableEvents が False のまま残っている可能性が高い。VBE を開き、「表示」→「イミディエイト ウィンドウ」(または Ctrl+G)で Application.EnableEvents = True と入力して Enter。これで復旧する。
Q4: セルを Delete キーで消したときも反応する?
する。Delete キーでセルの値をクリアした場合も Worksheet_Change は発火する。最小版のコードでは、A列が空欄になったらB列もクリアする処理が入っているので、意図通りの動作になる。
Q5: 複数のシートで同じ処理をしたい場合は?
—
まとめ
この記事で、セルの値が変わったら自動で処理(タイムスタンプ記録・色変更)が実行されるようになった。
- 最小版:A列変更 → B列にタイムスタンプ自動記録
- 実務版:A列の数値に応じて行を色分け+C列にステータス+B列にタイムスタンプ
重要なのは以下の2点:
- 貼り付け先がシートモジュールであること(標準モジュールではない)
Application.EnableEvents = Falseで無限ループを防止すること
関連記事
- 【VBA】セルの値に応じて行を自動色分けする方法 — マクロ実行ボタンで一括色分けする方法。本記事はセル変更の都度リアルタイムに色分けする方法
- 【VBA】ブックを開いたとき・保存時に自動実行するイベント処理の方法 — Worksheet_Changeの兄弟イベント。ブックを開く・保存するタイミングで自動実行
- 【VBA】セルの変更履歴を自動記録して差分管理する方法 — 本記事のWorksheet_Changeを応用し、変更前後の値を履歴シートに蓄積
- 【VBA】ボタンを押してマクロを実行する方法 — イベントではなくボタンクリックでマクロを実行したい場合
- 【VBA】画面更新・再計算を止めてマクロを高速化する方法 — イベント処理が多いときに併用すると体感速度が改善
次にやりたくなること
- 【VBA】セルの値に応じて行を自動色分けする方法 — 変更をトリガーに行の色分けも自動化したい場合はこちら
- 【VBA】ボタンを押してマクロを実行する方法 — シート上にボタンを置いてワンクリックで実行したい場合はこちら
- 【VBA】セルの変更履歴を自動記録して差分管理する方法 — 変更を検知するだけでなく、誰が何をいつ変えたか記録したい場合はこちら
- 【VBA】ブックを開いたとき・保存時に自動実行するイベント処理の方法 — セル変更だけでなく、ブックを開いた瞬間にも自動実行したい場合はこちら
- 【VBA】画面更新・再計算を止めてマクロを高速化する方法 — イベント処理が増えて動作が重くなったら高速化テクニックを併用
—


コメント