VBAの Worksheet_Change イベントを使うと、セルにデータを入力した瞬間に自動で並び替えが実行されるシートを作れます。売上記録・顧客一覧・日報など、追記のたびに手動で並び替えていた作業を完全に自動化できます。
この記事では、次の内容を順番に解説します。
- 入力と同時に自動で並び替える基本コード
- 複数列を条件にした並び替えパターン
- 降順・日付順など並び替え条件のバリエーション
- 特定の列だけを対象にして無駄な実行を防ぐ方法
- EnableEventsで無限ループを防ぐ理由
入力後に自動で並び替えを実行するには?
Worksheet_Change はシートのセルが変更されるたびに自動で実行されるイベントプロシージャです。このイベントの中に並び替え処理を書くことで、入力と同時に並び替えが走ります。
記述場所:対象シートのコードウィンドウ(VBEでシート名をダブルクリックして開く)に記述します。標準モジュールではなく、シートモジュールに書く必要があります。
'シートモジュール(Sheet1など)に記述する
Private Sub Worksheet_Change(ByVal Target As Range)
'D列への入力を検知
If Not Intersect(Target, Range("D:D")) Is Nothing Then
Application.EnableEvents = False '無限ループを防ぐ
'A列を基準に昇順で並び替え
Range("A1").CurrentRegion.Sort _
Key1:=Range("A1"), _
Order1:=xlAscending, _
Header:=xlYes
Application.EnableEvents = True
End If
End Sub
このコードは「D列が変更されたとき」だけ反応します。Intersect で変更された範囲がD列と重なるかチェックし、重なる場合だけ並び替えを実行します。
| コードの要素 | 役割 |
|---|---|
Worksheet_Change | セルの変更を検知して自動実行されるイベント |
Intersect(Target, Range("D:D")) | 変更がD列に対するものかチェックする |
Application.EnableEvents = False | 並び替え実行中に再度イベントが発生しないようにする |
CurrentRegion.Sort | A1セルを起点にした連続データ範囲を並び替える |
Header:=xlYes | 1行目を見出しとして並び替え対象から外す |
複数列を条件にして並び替えるには?
「まずB列で昇順、同じ値があればC列で昇順」のように複数キーで並び替えるには、Key2 を追加します。
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("B:C")) Is Nothing Then
Application.EnableEvents = False
With Range("A1").CurrentRegion
.Sort _
Key1:=.Columns(2), Order1:=xlAscending, _
Key2:=.Columns(3), Order2:=xlAscending, _
Header:=xlYes
End With
Application.EnableEvents = True
End If
End Sub
降順・日付順など並び替え条件を変えるには?
並び替えの方向や条件は Order1 の値を変えるだけで対応できます。
| 並び替えの種類 | 設定値 | 使用例 |
|---|---|---|
| 昇順(小→大、あ→ん) | xlAscending | 日付の古い順、名前のあいうえお順 |
| 降順(大→小、ん→あ) | xlDescending | 売上の高い順、日付の新しい順 |
日付列(例:A列)を新しい順に並べる例です。
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A:D")) Is Nothing Then
Application.EnableEvents = False
'A列(日付)を降順で並び替え
Range("A1").CurrentRegion.Sort _
Key1:=Range("A1"), _
Order1:=xlDescending, _
Header:=xlYes
Application.EnableEvents = True
End If
End Sub
EnableEventsで無限ループを防ぐ理由を理解するには?
Sort を実行するとセルの並び順が変わり、その変更がまた Worksheet_Change を呼び出してしまいます。これが繰り返されると無限ループになりExcelがフリーズします。Application.EnableEvents = False でイベントの発生を一時的に止めることでこれを防ぎます。
'必ずセットで使う
Application.EnableEvents = False
'並び替え処理(この間はイベントが発生しない)
Range("A1").CurrentRegion.Sort ...
Application.EnableEvents = True '必ず元に戻す
重要:EnableEvents = False にしたまま処理が中断すると、以後すべてのイベントが発生しなくなります。エラーが起きても必ず True に戻るよう、On Error GoTo と組み合わせた安全な書き方がおすすめです。
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("D:D")) Is Nothing Then
On Error GoTo ErrorHandler
Application.EnableEvents = False
Range("A1").CurrentRegion.Sort _
Key1:=Range("A1"), _
Order1:=xlAscending, _
Header:=xlYes
ErrorHandler:
Application.EnableEvents = True
End If
End Sub
まとめ
Worksheet_Changeイベントをシートモジュールに記述すると、セル変更のたびに自動処理を実行できるIntersectで対象列を絞ることで、関係ない列への入力では並び替えが走らないようにできる- 複数列を条件にするときは
Key2・Order2を追加する Application.EnableEvents = Falseを入れないと並び替えが無限ループになるため必須- エラー時に
EnableEventsがFalseのまま残らないよう、On Error GoToと組み合わせると安全
よくある質問
コードをどこに書けばいいですか?
シートモジュールに記述します。VBEを開いて(Alt+F11)、左のプロジェクトウィンドウから対象シート名(「Sheet1」など)をダブルクリックすると、そのシートのコードウィンドウが開きます。標準モジュールに書いても動きません。
並び替えると入力したセルの選択が外れてしまいます
並び替えによってセルの位置が変わるため、入力後のカーソル位置がずれることがあります。気になる場合は、並び替え後に Application.Goto Target で元のセルに戻るコードを追加すると、カーソルの移動を抑えられます。
見出し行も一緒に並び替えられてしまいます
Header:=xlYes を設定すると1行目が見出しとして扱われ、並び替え対象から外されます。もし1行目に見出しがない場合は Header:=xlNo に変更してください。
並び替えの対象範囲を固定したいです
CurrentRegion は空白行・列で囲まれた連続データ範囲を自動取得します。範囲を固定したい場合は Range("A1:D100") のように直接指定できます。データ量が変動する場合は、最終行を取得して動的に範囲を設定するのがおすすめです。
並び替えを一時的に止めたいです
コードの Intersect 条件の前に、セルへのフラグ(例:特定セルが「一時停止」という値のとき)を確認する処理を追加すると、条件付きで並び替えを止めることができます。もしくはVBEで Worksheet_Change の先頭に Exit Sub を一時的に追加してもシンプルに止められます。
動画で学びたい方へ
「記事を読んでも、実際に自分で書けるか不安…」という方には、動画で基礎からじっくり学べる講座がおすすめです。
VBAが初めての方を前提に、つまずきやすいポイントを先回りして解説しています。サンプル動画は無料でご覧いただけます。



