【VBA】モジュール間の呼び出し|Public / Private の違いと正しい呼び方を解説

VBAでは、処理を整理して「標準モジュール」「クラスモジュール」「シートモジュール」など複数のモジュールへ分割することが一般的です。
しかしモジュールを増やすと、別のモジュールにあるプロシージャをどう呼び出すのか? という問題に直面します。

本記事では、初心者でも理解しやすいように VBAでモジュール間のプロシージャを呼び出す基本から注意点まで詳しく解説 します。


スポンサーリンク

1. モジュール間の呼び出しの基本

異なるモジュールにあるプロシージャを呼ぶ場合でも、呼び出し方は非常にシンプルです。

● Public プロシージャならどこからでも呼べる

標準モジュールに定義したプロシージャを他のモジュールから呼び出す場合は、次のように Public がついている必要があります。

'標準モジュール ModuleA に記述
Public Sub HelloWorld()
    MsgBox "こんにちは"
End Sub

別のモジュール(例:ModuleB)から呼ぶ:

Sub Exec()
    HelloWorld   'モジュール名の指定は不要
End Sub

スポンサーリンク

2. モジュール名を指定して呼び出す方法

名前が重複するときや、どのモジュールのプロシージャか明確にしたい場合は、モジュール名.プロシージャ名 の形式で呼び出します。

ModuleA.HelloWorld

これは「モジュール名を名前空間のように使う」イメージです。


スポンサーリンク

3. Private プロシージャは呼び出せない

Private をつけたプロシージャは、そのモジュール内でしか使えません。

'ModuleA
Private Sub LocalProc()
    MsgBox "これはこのモジュール内専用"
End Sub

ModuleB から呼ぶとエラーになります。

公開したい場合は必ず Public にすること。


スポンサーリンク

4. シートモジュールやThisWorkbookからの呼び出し

シートモジュールや ThisWorkbook にあるプロシージャは、通常モジュールとは扱いが異なります。

● Call 例:シートモジュール(Sheet1)

'Sheet1 モジュール
Public Sub ShowMsg()
    MsgBox "Sheet1からのメッセージ"
End Sub

別モジュールから呼ぶ:

Sub Exec()
    Sheet1.ShowMsg
End Sub

シート名ではなく、シートのコードネームで呼ぶ点がポイントです。


スポンサーリンク

5. 関数をモジュール間で呼び出す

関数も同様に呼び出せます。

'ModuleA
Public Function Add(a As Long, b As Long) As Long
    Add = a + b
End Function
'ModuleB
Sub Exec()
    MsgBox Add(3, 5)
End Sub

クラスモジュールと異なり、標準モジュールの Public 関数はそのまま呼べるのが特徴です。


スポンサーリンク

6. モジュール間呼び出しのよくあるトラブルと対策

●(1)Public にしたつもりが Private のまま

「呼び出せない!」の原因の多くはアクセス修飾子の付け忘れ。

対策:デフォルト Private と考える。必要なものだけ Public にする。


●(2)モジュール名とプロシージャ名の重複

以下のようなケースでは必ずフル指定を行いましょう。

  • 同名プロシージャが複数のモジュールにある
  • モジュール名とプロシージャ名が同じになる(避けるべき)

例:

ModuleA.Test
ModuleB.Test

必ず「どちらを呼ぶか」明確にする必要があります。


●(3)引数の数が合わずコンパイルエラー

関数・プロシージャの引数が合わないと呼び出し時にエラーとなります。

「プロシージャの分割」でモジュールを整理する際に発生しやすいので注意してください。


スポンサーリンク

7. まとめ

モジュール間の呼び出しは VBA コードの構造化と分割のキモです。

要点説明
Public を付ける他モジュールから呼べる
Private はそのモジュール内限定外部からは呼び出し不可
モジュール名を付けて呼べる曖昧さを防ぎ、トラブル回避
シートモジュールはコードネームで呼ぶシート名ではない点に注意

この知識を押さえることで、プロジェクトの規模が大きくなっても整理されたコードを保つことができます。

コメント

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