【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でデータ型を定義する方法
更新日 : 2019年10月1日

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

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

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


・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で宣言したintNumTest1のみで使える変数で、Test2で宣言したstrMessageTest2のみで使える変数です。

このように、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のメッセージ

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

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

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

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

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

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

サンプルコード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のメッセージ

Module1Publicで作ったグローバル変数intNumstrMessageModule2Test1Module3Test2でそれぞれ使えていますよね。

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

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

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

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

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

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

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

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

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

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(税率)を、Module2Mainプロシージャ内の最初で1.08(消費税8%)として設定しているにもかかわらず、誤ってModule3の合計金額を計算するTest1の先頭でも1.05(消費税率5%)として設定してしまっているため、Mainプロシージャを実行した結果が「合計金額:1050」になっています。

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

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

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

Public Const taxRate = 1.08

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

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

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

まとめ

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

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

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

LINEで送る
Pocket

SEからWebエンジニアへ転職した理由

侍エンジニア塾卒業生の小池さんは、以前は社内SEとして約5年ほど勤務していました。しかし業務内容は社内のヘルプデスク対応など、プログラムを書く仕事は全くなかったそうです。

SEながらプログラムを書けない現状に「将来仕事がなくなるんじゃないか」と不安を感じ、プログラミング学習を決意。

弊社スクールで学習し、無事ベンチャー企業のプログラマーとして転職に成功しました。そんな小池さんの学習法や転職体験談を伺いましたので、是非ご覧ください。

「プログラミングができないSEは仕事がなくなる」不安を感じたSEが未経験から転職成功するまで
更新日 : 2019年10月7日

書いた人

Sanshiro Wakizaka

Sanshiro Wakizaka

フリーランスエンジニア兼ライターのワキザカ サンシロウです。
ExcelVBAの自動化ツール開発、WEB開発をメインにエンジニア業務をこなしつつ、サムライエンジニアにてライター業務をしております。

プログラミングをこれからやってみたい方に向けて、ためになる記事を全力で書いていきますので宜しくお願い致します!

おすすめコンテンツ

あなたにぴったりなプログラミング学習プランを無料で診断!

プログラミング学習の効率を劇的に上げる学習メソッドを解説