【VBA】セルの値が変わったら自動実行!Worksheet_Changeの使い方(コピペOK)

VBA

この記事でできること

セルの値を変えるたびに手動でタイムスタンプを入力したり、色を変えたりしていませんか? VBAの Worksheet_Change イベントを使えば、セルの値が変わった瞬間に自動で処理が実行される。コードをシートモジュールに貼り付けるだけ。マクロの実行ボタンも不要

  • 対象:セルを変更するたびに手動で別の作業をしている人、VBAが初めての人
  • 所要時間:コピペ → 動作確認まで約5分(目安)

完成イメージ(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)で保存する

  1. Excelを開く(新規でも既存でもOK)
  2. 「ファイル」→「名前を付けて保存」
  3. ファイルの種類を 「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 はシートモジュールに書く。

  1. VBE の左側に「プロジェクトエクスプローラー」が表示されている
  2. 対象のシート名(例:Sheet1 (Sheet1))をダブルクリックする
  3. 右側にコードウィンドウが開く → ここにコードを貼り付ける

間違いやすいポイント:

  • 「挿入」→「標準モジュール」は使わない
  • 左のツリーで「Sheet1」をダブルクリックする
  • シート名を変更している場合は、VBE上で「Sheet1 (売上管理)」のように表示名が変わっている

コードを貼り付ける

下の「コード(最小版)」をコピーして、シートモジュールのコードウィンドウに貼り付ける。

動作を確認する

  1. VBEからExcelの画面に戻る(Alt + F11 または タスクバーでExcelをクリック)
  2. A2セルに何か入力してEnterを押す
  3. 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 に戻すこと。

コードの動作:

  1. A列のセルが変更される → Worksheet_Change が自動で実行される
  2. A列以外、ヘッダー行、複数セル同時変更の場合は何もしない
  3. EnableEvents を False にして無限ループを防止
  4. B列に現在日時を記録
  5. A列が空欄にされた場合はB列もクリア
  6. 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 の数値を業務に合った基準に書き換える。


もし無限ループに入ったら(対処法)

EnableEvents を書き忘れた、またはエラーでTrue に戻らなかった場合、Excelがフリーズすることがある。

対処手順:

  1. Ctrl + Break を押す(多くのキーボードで中断できる)
  2. Ctrl + Break が効かない場合(ノートPCでBreakキーがない等)→ Ctrl + Alt + Delete →「タスク マネージャー」→ Excel を選択 →「タスクの終了」
  3. Excelを再起動し、ファイルを開き直す
  4. VBE(Alt+F11)を開き、「表示」→「イミディエイト ウィンドウ」(Ctrl+G)で以下を入力して Enter:

Application.EnableEvents = True

これでイベントが復旧する。


よくある落とし穴5選

# 症状 原因 対策
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 イベントを使う(別の仕組み)

FAQ

Q1: 特定の列だけに反応させたい場合は?

If Target.Column <> 1 Then Exit Sub1 を変更する。B列なら 2、C列なら 3。複数列に反応させたい場合は If Target.Column <> 1 And Target.Column <> 3 Then Exit Sub(A列とC列の場合)。

Q2: 特定の値が入力されたときだけ反応させたい場合は?

If Target.Value = "完了" Then のように条件分岐を追加する。例えば、A列に「完了」と入力されたらB列に日時を記録し、それ以外の値では何もしない、という使い方ができる。

Q3: イベントが突然動かなくなった

EnableEvents が False のまま残っている可能性が高い。VBE を開き、「表示」→「イミディエイト ウィンドウ」(または Ctrl+G)で Application.EnableEvents = True と入力して Enter。これで復旧する。

Q4: セルを Delete キーで消したときも反応する?

する。Delete キーでセルの値をクリアした場合も Worksheet_Change は発火する。最小版のコードでは、A列が空欄になったらB列もクリアする処理が入っているので、意図通りの動作になる。

Q5: 複数のシートで同じ処理をしたい場合は?

シートモジュールはシートごとに書く必要がある。Sheet1 に書いたコードを Sheet2 のシートモジュールにもコピペすればよい。ブック内の全シートで同じ処理をしたい場合は、ThisWorkbook モジュールの Workbook_SheetChange イベントを使う方法もあるが、処理が複雑になるためココナラで相談を推奨。


まとめ

この記事で、セルの値が変わったら自動で処理(タイムスタンプ記録・色変更)が実行されるようになった。

  • 最小版:A列変更 → B列にタイムスタンプ自動記録
  • 実務版:A列の数値に応じて行を色分け+C列にステータス+B列にタイムスタンプ

重要なのは以下の2点:

  1. 貼り付け先がシートモジュールであること(標準モジュールではない)
  2. Application.EnableEvents = False で無限ループを防止すること

関連記事


もっとカスタマイズしたい場合

「複数シートに一括で設定したい」「入力規則と組み合わせたい」「変更履歴を別シートに残したい」など、業務に合わせたカスタマイズが必要な場合は、ココナラで相談できます。

相談時に以下の情報があるとスムーズです:

  • Excel のバージョン / OS
  • 対象のシート数とレイアウト
  • どのセルが変わったら何を実行したいか
  • 行の色分け基準(あれば)

あわせて読みたい

コメント

タイトルとURLをコピーしました