「モジュール」はVBAコードを入れる“フォルダ”だと思ってみる
まずイメージからいきます。
Excelブックの中に、VBAのコードを入れておく“箱”がいくつか用意されています。
その箱の種類のことを「モジュール」と呼びます。
一つのブックの中に、
標準モジュール
シートモジュール(Sheet1 など)
ThisWorkbook モジュール
クラスモジュール
といった“種類の違う箱”が並んでいて、それぞれ役割が少しずつ違います。
超初心者の段階では、
「標準モジュール」と「シートモジュール」と「ThisWorkbook」
この三つのイメージがつかめれば十分です。
そこを丁寧にかみ砕いていきます。
標準モジュール:ふつうのマクロを入れる“作業場”
標準モジュールってどこにある?
VBE(Alt+F11)を開くと、左側に「VBAProject(ブック名)」というツリーがあります。
その中に「標準モジュール」というカテゴリがあり、Module1、Module2…のような名前で並びます。
「挿入 → 標準モジュール」を選ぶと、新しい Module が一つ増えます。
ここに書くのが、いわゆる「普通のマクロ」です。
標準モジュールに書くコードのイメージ
標準モジュールは、
「どのシートからでも使える、汎用的な処理」
「ボタンから呼び出すメインのマクロ」
などを入れておく場所です。
例として、Module1 にこんなコードを書いてみます。
Option Explicit
Sub HelloWorld()
MsgBox "こんにちは、標準モジュールのマクロです"
End Sub
Sub WriteToA1()
Range("A1").Value = "Module1 から書き込み"
End Sub
VBHelloWorld も WriteToA1 も、「開発タブ → マクロ」から実行できます。
どのシートがアクティブでも動きます(Range(“A1”) は“今アクティブなシート”の A1)。
「とりあえずマクロを書きたい」ときは、基本的に標準モジュールに書く、と思っておけばOKです。
シートモジュール:そのシート専用の“イベント置き場”
シートモジュールってどこにある?
同じく左側のツリーに、
Sheet1(Sheet1)
Sheet2(Sheet2)
…
のように、シートごとの項目があります。
これをダブルクリックすると、そのシート専用のコードウィンドウが開きます。
ここが「シートモジュール」です。
シートモジュールの役割
シートモジュールは、
「そのシートで起きた出来事(イベント)に反応するコード」
を書く場所です。
例えば、
セルを変更したとき
シートをアクティブにしたとき
ダブルクリックしたとき
などの“イベント”に対して、自動で動くマクロをここに書きます。
例:セルが変わったらメッセージを出す
Sheet1 のシートモジュールに、次のように書いてみます。
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
MsgBox "Sheet1 でセルが変更されました"
End Sub
VBこれは「Sheet1 のどこかのセルが変更されたときに自動で呼ばれるイベントプロシージャ」です。
標準モジュールに書いても動きません。
「Sheet1 のシートモジュールにあるからこそ、“Sheet1 の変化”に反応する」のがポイントです。
ここで大事なのは、
標準モジュール:自分で実行するマクロを置く場所
シートモジュール:そのシートのイベントに反応するマクロを置く場所
という役割の違いです。
ThisWorkbook モジュール:ブック全体の“イベント置き場”
ThisWorkbook はどこにある?
ツリーの中に「ThisWorkbook」という項目があります。
これをダブルクリックすると、そのブック全体に関するコードを書く場所が開きます。
ここが「ThisWorkbook モジュール」です。
ThisWorkbook の役割
ThisWorkbook には、
「ブックが開かれたとき」
「ブックが保存されるとき」
「ブックが閉じられるとき」
といった、“ブック全体のイベント”に反応するコードを書きます。
例:ブックを開いたときにあいさつする
ThisWorkbook に、次のように書いてみます。
Option Explicit
Private Sub Workbook_Open()
MsgBox "このブックを開いてくれてありがとう!"
End Sub
VBこのブックを開いた瞬間に、自動でこのメッセージが表示されます。
標準モジュールではなく ThisWorkbook に書くからこそ、「ブックを開く」というイベントに紐づきます。
ここまでで、
標準モジュール:普通のマクロ
シートモジュール:シートのイベント
ThisWorkbook:ブックのイベント
という三つの“役割の違う箱”が見えてきたと思います。
モジュール構成をどう考えるか(超初心者向けの整理)
なんでも Module1 に詰め込むのはアリだけど…
最初のうちは、全部 Module1 に書いても動きます。
ただ、マクロが増えてくると、
どのマクロが何をしているのか分かりにくい
イベント用のコードと普通のマクロが混ざってカオス
同じような処理があちこちにコピペされる
みたいな状態になりがちです。
そこで、「モジュールごとに役割を分ける」という発想が効いてきます。
役割ごとにモジュールを分けるイメージ
例えば、こんな分け方が典型です。
Module_Main
メイン処理(ユーザーが実行する入口)をまとめる
Module_Utility
共通で使う小さな関数や Sub(文字列処理、日付処理など)をまとめる
Sheet1(シートモジュール)
Sheet1 のイベント(セル変更、ダブルクリックなど)
ThisWorkbook
ブックのイベント(開く、閉じる、保存など)
名前は自由ですが、
「このモジュールには、こういう種類のコードだけを置く」
と決めておくと、後から見たときに迷子になりにくくなります。
小さな例で「モジュール構成」を体感する
例:メイン処理+共通関数+イベント、を分けてみる
標準モジュール Module_Main:
Option Explicit
Public Sub RunReport()
Dim total As Long
total = GetTotal(10, 20)
Range("A1").Value = "合計は " & total & " です"
End Sub
VB標準モジュール Module_Utility:
Option Explicit
Public Function GetTotal(a As Long, b As Long) As Long
GetTotal = a + b
End Function
VBSheet1 のシートモジュール:
Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Range("B1").Value = "最後に選択したセルは " & Target.Address
End Sub
VBThisWorkbook:
Option Explicit
Private Sub Workbook_Open()
MsgBox "レポートブックを開きました"
End Sub
VBこの構成だと、
ユーザーが実行する入口(RunReport)は Module_Main
計算ロジック(GetTotal)は Module_Utility
シートの動きに反応するコードは Sheet1
ブックの動きに反応するコードは ThisWorkbook
というふうに、役割ごとに“置き場所”が分かれています。
「この動きはどこに書いてあったっけ?」と思ったときに、
イベントならシート or ThisWorkbook
普通のマクロなら標準モジュール
と、すぐ当たりがつけられるようになります。
超初心者向け「モジュール構成」の実践ルール
最後に、今の段階で意識しておくと楽になる考え方をまとめます。
普通のマクロ(ボタンから実行する処理など)は、標準モジュールに書く。
シートで何かが起きたときに自動で動いてほしい処理は、そのシートのシートモジュールに書く。
ブックを開いたとき・閉じたときなどの処理は、ThisWorkbook に書く。
標準モジュールは、できれば「メイン用」「共通処理用」くらいにざっくり分けておくと、後で見やすい。
モジュール構成は、「正解が一つ」ではありません。
大事なのは、
「自分と未来の自分が、どこに何があるかすぐ分かるようにしておくこと」です。
