VBA技術解説
標準モジュールとシートモジュールの違い

ExcelマクロVBAの問題点と解決策、VBAの技術的解説
公開日:2015-01-03 最終更新日:2021-06-24

標準モジュールとシートモジュールの違い


エクセルVBAを始めたばかりの人に教えるとき、
まずは標準モジュールを挿入して、そこに書きましょう、と教えます。
しかし後で見ると、時に間違ってシートモジュールに書いている場合が結構あります。


そういう時に、必ず聞かれるのが、
「何が違うんですか?」
「どこが違うんですか?」
そういう時は、
「今はその違いについて説明しても混乱するだけですから、とにかく標準モジュールに書いてください。」
このようにお伝えすることが結構あります。

とはいえ、
イベント処理等でシートモジュールを扱うようになったら、その違いは正確に理解しておかなければなりません。
以下では、標準モジュールとブックモジュールとシートモジュールの違いを列挙的に説明します。
用語的には、若干の独自補正を加えています。
なぜなら、正式用語を羅列しても理解しづらく、それで理解できる人にはそもそも説明が不要だからです。

書かれている場所と概要

標準モジュール
ブックに属しています。
ブック内に自由に挿入・削除できます。
いくつでも挿入できますし、無くても構いません。

ブックモジュール
ブックに属しています。
初期名称は「ThisWorkbook」
ブック内に一つだけです。

シートモジュール
シートに属しています。
シートと一対一の関係です。
シートを削除すれば、シートモジュールも削除されてしまいます。


シートモジュールはシートに属しています。
つまり、シートをコピーすれば、シートモジュールも一緒にコピーされます
これを逆手にとって、シートモジュールに意図的に記述することで、他のブックにマクロVBAをコピーすることもできます。

シートを省略してRangeやCellsと記述した時

VBAの書き方として、シート修飾せずに、いきなりRangeやCellsから書き始めた場合。
つまり、
Range("A1") = 1
Cells(2,1) = 2
このように書いた場合です。

標準モジュール
アクティブブックのアクティブシートのセル
ブックモジュール
アクティブブックのアクティブシートのセル
シートモジュール
シートモジュールが記述されているシートのセル

もちろん、ブック・シートで修飾していれば、それらは同じ動作になります。
そして、本来はブック・シートはしっかり指定すべきす。
ThisWorkbook.Worksheets("Sheet1").Range("A1")
つまり、基本通りにブック・シートを指定していれば、この違いはあまり気にする必要はありません。

他モジュールから使う時

Public指定の変数やプロシージャーを他のモジュールで使う時の記述の違いです。
もちろん、Privateは他のモジュールからは使用できません。

標準モジュール
全てのモジュールでそのまま使用可能
Public 変数hoge
これを他のモジュールで使用する時は、
変数hoge
とだけ記述すれば使用できます。

ブックモジュール
常にオブジェクト名で修飾する必要があります。
ThisWorkbookの、
Public 変数hoge
これを他のモジュールで使用する時は、
ThisWorkbook.変数hoge
と記述する必要があります。

シートモジュール
常にオブジェクト名で修飾する必要があります。
Sheet1の、
Public 変数hoge
これを他のモジュールで使用する時は、
Sheet1.変数hoge
と記述する必要があります。

以下も参考してください。
第108回.変数の適用範囲
・プロシージャーレベル変数 ・・・ プロシージャー内でのみ使用可能 ・モジュールレベル変数 ・・・ モジュール内でのみ使用可能 ・パブリック変数 ・・・ 全てのモジュールの全てのプロシージャーで使用可能 ・変数の適用範囲について簡単にまとめてると ・定数(Const)の適用範囲について ・変数の重複について ・変数は、極力狭いスコープで使う事が望ましいとされます。


デバッグ時の違い

ここは、実際のエラーメッセージを見てください。

標準ジュール
マクロ VBA シートモジュール ブックモジュール

このようなダイアログが表示され、「デバッグ」押下で、
VBAの当該行が黄色反転表示されます。

ブックモジュール
シートモジュール
マクロ VBA シートモジュール ブックモジュール

「デバッグ」がなく、当該VBA行が不明です。

上記の動作違いの原因
このような動作違いは、ツールのオプションの設定に依存して起きています。

マクロ VBA シートモジュール ブックモジュール

このエラートラップの指定に依存しています。
初期値の
「エラー処理対象外のエラーで中断」
この状態の時に、上で書いたような違いが発生します。
「クラスモジュールで中断」または「エラー発生時に中断」にしてあれば、
上のエラー時のメッセージでの「デバッグ」押下はどちらも同じになります。

ブック/シートモジュールを使う場合は、「クラスモジュールで中断」にしておいたほうが良いでしょう。

標準モジュールとシートモジュールの使い分け方

標準モジュールは名前の通りですと、標準的に使うモジュールということになりますが、
そもそも標準と言う言葉があまりにも曖昧に感じられて混乱しやすいのだと思います。

シートやブックはオブジェクトと呼ばれます。
そのオブジェクトに付帯しているモジュールなので、オブジェクトモジュールという言い方もします。

オブジェクトモジュール(ブックモジュール/シートモジュール)
・オブジェクトと切り離すことのできない処理
・一緒にしておいた方が良い処理
オブジェクトモジュールには、これらの処理を記述します。
代表的なものが、イベントプロシージャーになります。
イベントプロシージャーは、当該オブジェクトのモジュールに書かなければならず、オブジェクトと切り離すことのできない処理になります。

単にシートに「依存する処理」という考え方をしてしまうと、
多くの処理がシートに依存していることになり、やたらとシートモジュールに書くことになってしまいます。
そもそも、ほとんどはブックに依存しているので、全てブックモジュールに書くことになってしまいますよね。
つまり、
オブジェクトと一体としてそこに無ければならない処理なのかが判断基準になってくるでしょう。
簡単に考えるなら、シートをコピーした時を想定してみると良いでしょう。
シートをコピーすれば、シートモジュールもコピーされます。
例えば、イベント処理として、

Sheet1
Private Sub Worksheet_Change(ByVal Target As Range)
  '・・・
  'いろいろな処理
  '・・・
End Sub

このSheet1をコピーしてSheet2を作成した時、このシートモジュールも全てコピーされます。
上記のイベント処理も当然コピーされますが、それはむしろ都合が良いでしょう。
しかし、
「いろいろな処理」この記述も含めてそれぞれのシートに存在することになります。
この「いろいろな処理」が数十行のVBAで書かれていたとしたらどうでしょうか。
いったんは問題ないでしょうが、何かの変更が発生したら、、、
ではどうしたら良いか。
「いろいろな処理」の部分は標準モジュールに記載して、
イベントプロシージャーからはCallするような作りにしておくことを考えるべくでしょう。
(当然Tagetを直接または加工して引数として渡すことになります。)

イベント処理以外でもシートモジュールを使用することはあるでしょう。
この時にも、シートのコピーは常に念頭に置いて考えるべきです。
もちろん、
シートをコピーすることが無いといった場合や、
それぞれのシートにVBAが存在している事の是非については、
個別の判断が必要になることは言うまでもありません。

標準モジュール
・オブジェクトとは切り離しておいた方が良い処理
・複数オブジェクトから汎用的に使用される処理
上記以外でも、オブジェクトモジュールに記載する処理以外は全てここに書きます。


ここは見解がいろいろありそうですが、
イベント処理を覚えるまでは、まずは標準モジュールだけ使う事をお勧めしておきます。

シートモジュールの便利な活用方法はありますが、
それらは、イベント処理くらいまで習得した後に考えれば良いと思います。



同じテーマ「マクロVBA技術解説」の記事

Rangeオブジェクト.Valueの省略について
シート保護でユーザー操作を制限する
シートに数式を設定する時のセル参照の指定方法
標準モジュールとシートモジュールの違い
オートフィルタ(AutoFilter)の使い方まとめ
複雑な条件(複数除外等)のオートフィルター(AutoFilter)
クリップボードを使わないセルのCopy
Rangeの使い方:最終行まで選択を例に
フルパスをディレクトリ、ファイル名、拡張子に分ける
Colorプロパティの設定値一覧(カラー定数、XlRgbColor列挙)
VBAを定型文で覚えよう


新着記事NEW ・・・新着記事一覧を見る

ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
累計を求める数式あれこれ|エクセル関数応用(2024-01-22)
複数の文字列を検索して置換するSUBSTITUTE|エクセル入門(2024-01-03)
いくつかの数式の計算中にリソース不足になりました。|エクセル雑感(2023-12-28)
VBAでクリップボードへ文字列を送信・取得する3つの方法|VBA技術解説(2023-12-07)
難しい数式とは何か?|エクセル雑感(2023-12-07)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.変数宣言のDimとデータ型|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.並べ替え(Sort)|VBA入門
8.条件分岐(IF)|VBA入門
9.セルのクリア(Clear,ClearContents)|VBA入門
10.マクロとは?VBAとは?VBAでできること|VBA入門




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ