こんにちは!現場でバリバリVBAを書いていると、「ボタンを押さなくても、ファイルを開いた瞬間に自動で処理が走ってくれたらなぁ」「セルを書き換えたら、一瞬で裏で計算を済ませてくれたらなぁ」と思う瞬間が必ずやってきますよね。
マクロの記録から一歩抜け出して、Excel VBAを「自分の手足のように動かす」ための最大の扉――それが「イベント(Event)」です。
ここをクリアすれば、あなたの作るExcelツールは、ただの「手動で動かすファイル」から、「ユーザーの動きを察知して自律的に動くシステム」へと生まれ変わります。
今日は、イベントの基本から、現場のプロが絶対に避けて通る「無限ループ地獄」の回避策まで、優しく、そして深く解説していきますね。ここをクリアすれば、Excel VBAの基本はバッチリですよ!
—
1. 「イベント」って一体なに?(マクロの記録との決別)
これまでのあなたは、きっとこんな風にマクロを使っていたはずです。
1. 開発タブを開く
2. 「マクロの実行」ボタンを押す
3. または、シートに配置した図形(ボタン)をクリックする
これは言い換えば、「人間がExcelに指示を出して動かしている状態」です。
一方、イベントとは、Excelのセカイで何らかの「事件(=イベント)」が起きたとき、Excel自身がそれを検知して、自動的に裏でプロシージャを呼び出す仕組みのことです。
- 「Excelファイルを開いた」
- 「特定のセルを書き換えた」
- 「別のシートに切り替えた」
これらがすべて、VBAにおける「トリガー(導火線)」になります。ボタンを押す手間すら省ける、これがイベントの真骨頂です。
—
2. どこに書くの?イベントプロシージャの置き場所
通常の標準モジュール(「標準モジュール1」など)に書くコードと違い、イベントを受け取る場所は決まっています。ここが最初のつまずきポイントなので、しっかり押さえましょう。
① `Workbook_Open` (ファイルを開いた瞬間に発動)
- 置き場所: `ThisWorkbook` モジュール
- 用途: 起動時の初期化処理、今日の日付の自動入力、期限切れチェックなど。
② `Worksheet_Change` (セルが書き換わった瞬間に発動)
- 置き場所: 各シートのモジュール(`Sheet1` や `Sheet2` など)
- 用途: 入力ミスのリアルタイムチェック、自動タイムスタンプの記録など。
—
3. 実践!よく使う代表的イベントの書き方
百聞は一見にしかず。実際にコードを書いてみましょう。
実践例1:ファイルを開いたときに挨拶させる(`Workbook_Open`)
1. VBAエディタ(VBE)を開く(`Alt` + `F11`)
2. 左側のプロジェクトエクスプローラーから `ThisWorkbook` をダブルクリック。
3. 以下のコードを貼り付けます。
Private Sub Workbook_Open()
‘ ファイルを開いたときに自動実行される
Dim userName As String
userName = Environ(“USERNAME”) ‘ Windowsのログインユーザー名を取得
MsgBox “お疲れ様です、” & userName & “さん!” & vbCrLf & _
“本日の業務ファイルを開きました。”, vbInformation, “起動通知”
‘ セルに今日の日付を自動セットする例
Sheets(“Sheet1”).Range(“A1”).Value = Date
Sheets(“Sheet1”).Range(“A1”).NumberFormatLocal = “yyyy年m月d日”
End Sub
これだけで、このファイルをダブルクリックして開いた瞬間、VBAが勝手に起動してメッセージボックスを出し、A1セルに今日の日付を刻み込みます。感動的ですよね!
—
4. ⚠️【超重要】現場のエンジニアが恐れる「無限ループ」の罠
さて、ここからが本題の本質です。
セルが書き換わったときに動く `Worksheet_Change` を使うとき、私たちは「ある恐ろしい怪物」に気をつけなければなりません。
それが「無限ループ(カオス・スパイラル)」です。
事故現場を再現してみよう
例えば、「Sheet1のA1セルが書き換わったら、自動でB1セルに『完了』と書き込みたい」と思ったとします。
素直に書くと、こうなりますよね。
‘ 【※これはやってはいけないダメなコード例です】
Private Sub Worksheet_Change(ByVal Target As Range)
‘ A1セルが変更されたら
If Target.Address = “$A$1” Then
‘ B1セルに文字を入れる!
Range(“B1”).Value = “完了”
End If
End Sub
一見、正しく動きそうですが、ここでExcelの身になって考えてみてください。
1. ユーザーがA1セルに何かを入力する ➔ `Worksheet_Change` が発動!
2. VBAがB1セルに「完了」と書き込む ➔ 「おっと、セルが書き換わったぞ!」と検知し、再び `Worksheet_Change` が発動!!
3. 再びB1セルに「完了」と書き込む ➔ またセルが書き換わったので発動!!!
4. 💥 永遠に終わらない無限ループの完成。Excelがフリーズし、ファンが唸り声を上げます。
救世主:`EnableEvents` プロパティ
この悲劇を防ぐために、VBAには「ちょっと待て、Excelのイベント監視機能を一時停止してくれ!」と命令するスイッチが用意されています。
それが `Application.EnableEvents` です。
安全に動く、プロの書き方はこちらです!
Private Sub Worksheet_Change(ByVal Target As Range)
‘ 対象がA1セル以外なら何もしない(無駄な処理を走らせないガード)
If Target.Address <> “$A$1” Then Exit Sub
‘ 【重要】ここから先、VBAが自分でセルを書き換えるので、イベントを一時停止!
Application.EnableEvents = False
On Error GoTo ErrorHandler ‘ エラーで止まったときにイベント停止が解除されないのを防ぐ保険
‘ B1セルに「完了」と書き込む(ここでイベントは発火しない!)
Range(“B1”).Value = “完了”
ErrorHandler:
‘ 【絶対必須】処理が終わったら、必ずイベント監視を再開する!
Application.EnableEvents = True
End Sub
プロのエンジニアからのアドバイス
`Application.EnableEvents = False` を書いたときは、必ずエラー処理(`On Error GoTo`)とセットで `True` に戻す処理を書いてください。これを忘れると、コードの途中でエラーが起きたときにExcelのイベント機能が死んだままになり、「あれ?マクロが一切反応しなくなったぞ!?」という謎の不具合に悩まされることになります(現場で本当によくある新人・中級者のミスです!)。
—
まとめ
いかがでしたでしょうか?
- イベントとは、ユーザーやExcelの動きをトリガーにして、自動でコードを実行させる強力な仕組み。
- 起動時の処理は `ThisWorkbook` の `Workbook_Open` へ書く。
- セルの変更を捉えるときは `Worksheet_Change` を使う。
- 自らセルを書き換えるときは、`Application.EnableEvents = False` で無限ループを必ずブロックする!
この基本原則さえ押さえておけば、あなたのExcel自動化スキルは一段も二段もレベルアップします。ぜひ、明日の業務ファイルで試してみてくださいね。
それでは、また次の極限知見でお会いしましょう!
