Excel VBAで、あるマクロで作った変数の値を、別のマクロや別のモジュールで使いたいことがあります。
変数をどこから使えるかは、「どこに」「何と」宣言するかで決まります。
| 宣言する場所 | 書き方 | 使える範囲 |
|---|---|---|
| プロシージャ(Sub〜End Sub)の中 | Dim | そのプロシージャの中だけ |
| モジュールの一番上(宣言セクション) | Dim または Private | 同じモジュールのすべてのプロシージャ |
| 標準モジュールの一番上(宣言セクション) | Public | すべてのモジュールのすべてのプロシージャ |
変数を共有する代わりに、「引数」で値を渡す方法もあります。この記事では、それぞれの書き方と使い分けを、そのまま動くコードで紹介します。
初心者の頃は一つのモジュールやマクロに長々とコードを書きがちでしたが、マクロが大きくなってくると、これらを分けたくなります。
そんな時、モジュールやマクロ間で変数を共有するのに便利です。
同じモジュールの他のプロシージャで使う(モジュールレベル変数)
モジュールの一番上、最初のプロシージャより前(宣言セクション)で変数を宣言すると、そのモジュールの中のすべてのプロシージャで使えます。
Option Explicit
Dim msg As String
Sub モジュールレベル変数1()
msg = "変数"
MsgBox "モジュールレベル変数1:" & msg
Call モジュールレベル変数2
End Sub
Sub モジュールレベル変数2()
MsgBox "モジュールレベル変数2:" & msg
End Sub「モジュールレベル変数1」で入れた値を、「モジュールレベル変数2」でも表示できます。

Excel VBA モジュールの宣言セクションでDimを使って変数を宣言したVBEの画面
宣言セクションのDimは、Privateと書いても同じ意味です。「このモジュールの中だけで使う」ことをはっきりさせたいときは、Privateと書くと分かりやすくなります。
別のモジュールでも使う(Public変数=グローバル変数)
別のモジュールからも使いたいときは、標準モジュールの宣言セクションで「Public 変数名 As 型」と宣言します。
このような変数は「パブリック変数」や「グローバル変数」と呼ばれます。
Module1に次のコードを書きます。
Option Explicit
Public num As Long
Sub パブリック変数1()
num = 777
MsgBox "パブリック変数1:" & num
Call パブリック変数2
End SubModule2に次のコードを書きます。
Option Explicit
Sub パブリック変数2()
MsgBox "パブリック変数2:" & num
End SubModule1の「パブリック変数1」を実行すると、Module2の「パブリック変数2」でも「777」が表示されます。Module2ではnumを宣言していませんが、Module1のPublic宣言をそのまま使えています。

Excel VBA Module1の「パブリック変数1」を実行すると、Module2の「パブリック変数2」でも「777」が表示
モジュールを役割ごとに分けている場合は、Public変数を「mod_Common」のような共通用のモジュールにまとめて書くと、どこで宣言したか迷いません。
モジュール名の変え方はこちらです。
が表示された画面-160x90.png)
引数で値を渡す(プロシージャ間の受け渡し)
変数を共有しなくても、呼び出すときに「引数」として値を渡すことができます。別のモジュールのプロシージャにも渡せます。
Sub 引数で渡す()
Dim userName As String
userName = "山田"
Call 挨拶を表示(userName)
End Sub
Sub 挨拶を表示(ByVal targetName As String)
MsgBox targetName & "さん、こんにちは"
End Sub「挨拶を表示」のカッコの中のtargetNameが引数です。呼び出し側で渡した userName の値が、targetName に入ります。
計算した結果を返してほしいときは、SubではなくFunctionを使います。
Sub 結果を受け取る()
Dim total As Long
total = 合計を計算(100, 250)
MsgBox total
End Sub
Function 合計を計算(ByVal a As Long, ByVal b As Long) As Long
合計を計算 = a + b
End FunctionByValは「値だけを渡す」という意味で、受け取った側で値を変えても呼び出し側の変数は変わりません。
何も書かないとByRef(変数そのものを渡す)になり、受け取った側で値を変えると呼び出し側の変数も変わります。
意図せず値が変わるのを防ぐため、迷ったらByValを付けておきましょう。
定数を共有する(Public Const)
シート名や税率のように、途中で変わらない値を複数のモジュールで使いたいときは、標準モジュールの宣言セクションで定数にします。
Option Explicit
Public Const DATA_SHEET As String = "データ"
Public Const TAX_RATE As Double = 0.1別のモジュールから Worksheets(DATA_SHEET) のように使えます。
シート名が変わったときも、この1行を直すだけで済みます。
定数は値が消える心配もないので、変わらない値はPublic変数より定数にするのがおすすめです。
Public変数の値が消えるタイミング
モジュールレベル変数やPublic変数は、マクロが終わった後も値を覚えています。ただし、次のようなときには値がリセットされます。
- エラーで止まり、「終了」を押したとき
- VBEの「リセット」(■)ボタンを押したとき
- コードの中でEndステートメントを実行したとき
- ブックを閉じたとき
ブックを閉じた後も値を残したい場合は、変数ではなくシートのセルに書いておき、次に使うときに読み込みましょう。
設定用のシートを作って非表示にしておく方法もよく使われます。
プロシージャの中で値を覚えておく(Static)
プロシージャの中でDimの代わりにStaticと書くと、そのプロシージャが終わっても値を覚えていて、次に実行したときに続きから使えます。
Sub 実行回数を数える()
Static count As Long
count = count + 1
MsgBox count & "回目の実行です"
End Sub実行するたびに「1回目」「2回目」…と数が増えます。
他のプロシージャからは使えないので、「そのプロシージャの中だけで値を持ち越したい」ときに向いています。
どの方法を使えばいい?
| やりたいこと | おすすめ |
|---|---|
| あるマクロから別のマクロへ値を渡したい | 引数(ByVal) |
| 計算結果を返してほしい | Function |
| シート名や税率など変わらない値を共有したい | Public Const |
| 同じモジュールの中で値を共有したい | モジュールレベル変数(Private) |
| ブック全体で値を共有したい | Public変数 |
| ブックを閉じても値を残したい | セルに保存 |
Public変数は便利ですが、どこからでも値を変えられるので、数が増えると「どこで値が変わったのか」が分からなくなります。
まずは引数で渡せないかを考え、本当に必要なものだけPublicにするのがおすすめです。
生成AIにコードを頼むときも、「Public変数は使わず、引数で渡して」と一言添えると、後から直しやすいコードになりやすいです。
まとめ
- 同じモジュールの中で共有:宣言セクションでDimまたはPrivate
- 別のモジュールとも共有:標準モジュールの宣言セクションでPublic
- 変わらない値はPublic Const、マクロ間の受け渡しは引数がおすすめ
- Public変数はエラーでの終了やブックを閉じると値が消える。残したい値はセルに保存


