【ExcelVBA入門】変数の適用範囲(Dim・Public)について徹底解説!

こんにちは、フリーランスエンジニア兼ライターのワキザカ サンシロウです。

皆さんは、VBAで変数の適用範囲(スコープ)を意識したことがありますか?

スコープを意識すると、変数を便利に使うことができるので覚えておくととても便利です。

そこで今回は、

・変数とは

・変数のスコープとは

といった基礎的なことから、

・変数のスコープの使い分け方法

・グローバル変数のおすすめの使い方

といった応用的な方法まで、徹底的に解説します!

目次

変数とは

変数とは、値を保存しておくことができる箱のようなものです。

値を入れたり、使ったりすることができます。

次のように書くことで、変数を使うことができます。

Dim 変数名 as 型名
変数名 = 値

型名で整数、小数、文字列など何を入れる箱なのか宣言してから、値を入れて使います。

例えば、次のようなイメージです。

変数サンプルコード:

Sub Test()
  Dim intData1 As Integer   '整数
  Dim dblData2 As Double    '小数
  Dim strData3 As String    '文字列
  
  '変数に値を入れる
  intData1 = 10
  dblData2 = 3.14
  strData3 = "こんにちわ"
  
  '変数の値をメッセージで確認
  MsgBox "intData1:" & intData1 & vbCrLf & _
         "dblData2:" & dblData2 & vbCrLf & _
         "strData3:" & strData3

End Sub

実行結果:

このように、「Dimで変数の名前と型を決める → 変数に値を入れる → 使いたい場所で変数名を使う」の流れで簡単に変数を使うことができます。

変数の使い方については以下で詳しく解説しているので、気になる方は見てみてくださいね!

【VBA入門】変数をDimで宣言し、 Asでデータ型を定義する方法
更新日:2023年10月10日

変数の適用範囲(スコープ)とは

次に、変数の適用範囲(スコープ)について解説します。

変数は、書く場所・書き方によって使える範囲が変わります。


・Dimでプロシージャ内:プロシージャのみ使える
・Dimでプロシージャ外:モジュール内で使える
・Publicでプロシージャ外:プロジェクト全体でどこからでも使える

言葉だけだとわかりづらいので、それぞれサンプルを交えて解説しますね。

プロシージャ内でのみ使う方法

まずは、プロシージャ内でのみ使う方法です。

VBAは次のような構成でデータができています。

プロジェクトの下に複数のモジュールがあり、モジュールの下に複数のプロシージャがあるイメージですね。

プロシージャ内でのみ使える変数を宣言することができます。

変数を学んだ時に最初に書くのがSubプロシージャの中なので、この方法を使っている人は多いと思います。

サンプルコード:

Sub Test1()
    Dim intNum as Integer
    intNum = 123
End Sub

Sub Test2()
    Dim strMessage as String
    strMessage = "こんにちは"
End Sub

Test1で宣言したintNumはTest1のみで使える変数で、Test2で宣言したstrMessageはTest2のみで使える変数です。

このように、Sub内でDimで宣言した変数は、同じプロシージャ内でのみ使える変数になります。

モジュール内でのみ使う方法

次は、同じモジュール内で使う方法です。

先ほどの図でいうと、次のように赤枠で囲った部分がモジュール内で使える変数となります。

モジュール内には複数のプロシージャを作れるので、複数のプロシージャをまたいで使うことができる変数を作ることができます。

サンプルコード:

Dim intNum As Integer
Dim strMessage As String

Sub Test1()
  
  intNum = 1
  strMessage = "Test1のメッセージ"

  Debug.Print "intNum:" & intNum & vbCrLf & _
              "strMessage :" & strMessage

End Sub

Sub Test2()
  
  intNum = 2
  strMessage = "Test2のメッセージ"

  Debug.Print "intNum:" & intNum & vbCrLf & _
              "strMessage :" & strMessage

End Sub

Test1実行結果:

 1
Test1のメッセージ

Test1実行結果:

 2
Test2のメッセージ

モジュールの先頭にintNumとstrMessageを宣言し、Test1、Test2どちらでも変数を使えていますよね。

このように、プロシージャの外に変数を宣言することで、モジュール内であればどこでも使える変数として使うことができます。

プロジェクト全体で使う方法

つぎに、プロジェクト全体で使う方法について解説します。

先ほどの図でいうと、次の赤枠で囲った部分が範囲になります。

モジュールをまたいでどこからでも使える変数で、グローバル変数とも呼ばれています。

サンプルコードModule1:

Public intNum As Integer
Public strMessage As String

サンプルコードModule2:

Sub Test1()
  
  intNum = 1
  strMessage = "Module2.Test1のメッセージ"

  Debug.Print "intNum:" & intNum & vbCrLf & _
              "strMessage :" & strMessage
End Sub

サンプルコードModule3:

Sub Test2()
  
  intNum = 2
  strMessage = "Module3.Test2のメッセージ"

  Debug.Print "intNum:" & intNum & vbCrLf & _
              "strMessage :" & strMessage
End Sub

Test1実行結果:

intNum:1
strMessage :Module2.Test1のメッセージ

Test2実行結果:

intNum:2
strMessage :Module3.Test2のメッセージ

Module1にPublicで作ったグローバル変数intNum、strMessageがModule2のTest1、Module3のTest2でそれぞれ使えていますよね。

このように、モジュールをまたいでどこからでも使うことができます。

ちなみに、グローバル変数については以下で詳しく解説しているので、気になる方は見てみてくださいね!

【ExcelVBA】グローバル変数を使って開発効率を上げる方法とは
更新日:2024年3月1日

合わせて覚えると便利なグローバル変数の使い方

ここまでの説明を聞いて、

「どこからでも使える変数の方が便利だし、全部グローバル変数でいいのでは・・・?」

と思った方もいるのではないでしょうか。

確かに使いやすくなるので便利なのですが、その分データが書き換えられやすくなるデメリットがあります。

例えば、次のようなケースです。

Module1:

Public taxRate As Integer  '税率

Module2:

'メイン処理
Sub Main()
  
  '税率を設定
  taxRate = 1.08
     
  '合計金額を表示
  Call Module3.Test1(1000, 1)

End Sub

Module3:

'合計金額を表示するプロシージャ
Sub Test1(cost As Long, num As Long)
  
  '税率を設定
  taxRate = 1.05
     
  '合計金額を計算
  Dim totalCost As Long
  totalCost = cost * num * taxRate
  
  '合計金額を出力
  Debug.Print "合計金額:" & totalCost

End Sub

Module2のMain実行結果:

合計金額:1050

Module1のグローバル変数taxCost(税率)を、Module2のMainプロシージャ内の最初で1.08(消費税8%)として設定しているにもかかわらず、誤ってModule3の合計金額を計算するTest1の先頭でも1.05(消費税率5%)として設定してしまっているため、Mainプロシージャを実行した結果が「合計金額:1050」になっています。

このように、どこからでも値が書き換えられてしまうため、グローバル変数を使うときは注意が必要です。

そのため、グローバル変数は値が途中で書き換えられない定数として使うのがおすすめです!

グローバル変数を定数で置き換えたサンプル:

Public Const taxRate = 1.08

定数は値を書き換えることができないため、他のモジュールで書き換えるリスクをなくして使うことができます。

詳しい使い方については以下で解説しているので、気になる方は見てみてくださいね!

【ExcelVBA】グローバル変数を使って開発効率を上げる方法とは
更新日:2024年3月1日

まとめ

今回は、変数の適用範囲について解説しました。

スコープの違いが判ると、用途に応じて便利に変数を使うことができます。

プロシージャ内・モジュール内・プロジェクト全体で使う方法を覚えておけば応用がきくので、ぜひ使ってみてくださいね!

この記事を書いた人

北海道出身の30歳で、フリーランスエンジニア兼テックライターとして活動中。新卒入社したメーカー系のIT企業で、システムエンジニアとして約5年勤務。

Webアプリ、業務アプリ開発において、要件定義 ~ 運用保守まで様々な経験あり。また3歳の娘がいる1児のパパで、日々娘との時間を確保するために仕事を頑張っています!
侍エンジニアでは、【誰でもわかるレベルのわかりやすさ】を意識して、記事を執筆中。

目次