VBAは変数を宣言することを強くお勧めします。そのための準備となる「変数の宣言を強制する」オプションの設定方法を解説します。また、サンプルコードを使いながら、 実際に変数を宣言してみます。
目次
変数の宣言を強制する
2, 3行程度の短いVBAコードで足りる集計業務でない限り、次にお話する理由から、VBAコードを書く際は必ず変数を宣言するようにします。
「変数の宣言を強制する」メリット
変数の宣言をすることは、少し面倒に思われるかもしれませんが、次に述べる理由により、「変数の宣言を強制する」設定をすることをおすすめします。
その理由ですが、例えばVBAコードを組んでいる途中段階(コードを組む、実行する、集計結果チェック、コード修正を繰り返している段階)では、実行時にエラーが生じなくても、集計結果に違いが出ることが良くあります。
この原因は、コードが間違っているからではなく、アルゴリズム(集計方法)が間違っていることがほとんどで、アルゴリズムが正しくなれば、きちんとした集計結果になります。
ところが、変数の宣言をしないコードで、同じようなことをしようとしても、集計結果が合わない原因が、アルゴリズムだけではなく、コードが間違えている可能性も否定できなくなり、結果的にエラーの原因調査に多大な時間を要することもあります。
こうなると、初めから変数の宣言をしておいた方が、あとで合わない集計結果に頭を抱えるという事態に陥らなくて済みます。設定方法もとても簡単にできますので、ここはぜひ常に設定するものだと覚えて頂いてよいかもしれません。
「変数の宣言を強制する」設定方法
では、まずVBE画面を表示してから、下図のようにツール(①)→オプション(②)を選択してください。
Tips
ショートカットからVBE画面を開く
開発タブを使ってVBE画面を開く
下のようなオプション画面が表示されますので、「変数の宣言を強制する」の左横に✔を入れた状態で「OK」ボタンをクリックしてくださいね。設定作業はたったこれだけです。
それでは、きちんと設定されたかを確認してみましょう。VBE画面から別の標準モジュールを新規に挿入してみましょう。
Tips
標準モジュールの挿入の仕方
新しいモジュール(上図のModule2)が追加され、今度は「Option Explicit」という文字が自動的に入りました。この文字が明記されることにより、このモジュールでは、以後変数を宣言しないとエラーになります。
変数の宣言セクション
次に変数の宣言方法についてお話ししたいと思います。先ほどの新規の標準モジュールに、次のコードを追加で書いてみてください。
1 2 3 4 5 6 7 8 9 10 11 | Option Explicit '変数の宣言 Dim strTest As String Sub Sample007_1() '文字列を文字列型の変数「strTest」へ代入 strTest = "Hello! World!" 'Msgbox関数の実行 MsgBox strTest End Sub |

VBAでは、図の赤枠で示した場所、すなわちモジュールの最上部にある「Option Explicit」の次の行から、プロシージャ記述開始の「Sub~」手前の行までの間で変数を宣言します。
この変数を宣言する場所を、「宣言セクション」といいます。
では続きのコードについてお話ししますね。
7行目: strTest = "Hello! World!"
宣言セクションで定義した文字列型変数「strTest」に、文字列"Hello! World!"を代入しています。
10行目: MsgBox strTest
Excelシート上にメッセージを表示させるMsgBox関数です。以前にもMsgBox関数を使って文字列「Hello World!」を表示させましたよね。
それでは、お待たせしました。今回のコードを実行してみてください。
どうでしたか?上手くいけばMsgbox関数によって、「Hello! World!」という文字が、小さなウィンドウ上に表示されたかと思います。
では、つぎに下図のように、変数の宣言セクションに書かれた3行目「Dim strTest As String」の先頭に「'」(シングルクォーテーション)をつけて、コメントアウト(コメント文にすること)してみてから実行してください。
1 2 3 4 5 6 7 8 9 10 11 | Option Explicit '変数の宣言 'Dim strTest As String Sub Sample007_1() '文字列を文字列型の変数「strTest」へ代入 strTest = "Hello! World!" 'Msgbox関数の実行 MsgBox strTest End Sub |
どうでしたか?下図のようなエラー表示が出ませんでしたか。
ここで「OK」ボタンを押すと下図のようにエラーインジケーター(黄色ライン)と呼ばれるサインが表示されます。このエラーインジケータは、エラーの発生した場所を教えてくれる目印(マーク)になります。
気になるこのエラーの原因ですが、「Option Explicit」で変数の宣言を強制しているのに、変数を宣言していない(3行目の変数定義の行をコメント文にして実行されないようにしたため)ことによるものです。
このことから、「変数の宣言を強制する」をすることにより、変数を宣言しないとプログラムはエラーを返してきます。少し面倒な感じがしますが、先ほど変数の宣言を強制するメリットの中で述べた通り、変数を宣言せずに組み立てたコードは、あとあとエラーの処置により多くの時間を要します。
このことから、「変数の宣言を強制する」ことは、コーディングの初期の段階に、変数の宣言忘れを教えてくれるとても良い機能だと考えるとよいかもしれませんね。
VBAもう1つの変数宣言場所
じつはVBAの変数を宣言する場所は、宣言セクション内で宣言する以外に、もう1つだけあります。その場所は、プロシージャ内に記述する方法です。つぎは、このプロシージャ内に変数を宣言する方法について解説します。
さらに、前述の宣言セクション内で変数を宣言する場合との違いについても解説します。
では、これまでと同じモジュールに続けて、下記コードをさらに追加してください。
1 2 3 4 5 6 7 8 9 10 11 | '今回追加するプロシージャ Sub Sample007_2() 'プロシージャ内に変数を定義 Dim strTest2 As String '文字列を文字列型変数「strTest2」に代入 strTest2 = "Good Morning!" 'Msgbox関数の実行 MsgBox strTest2 End Sub |
今書いていただいたVBAコードですが、変数の宣言文がプロシージャ内に書かれているのに気づかれたのではと思います。VBAコードの行番号で4行目ですね。
このように、VBAではもう1つの変数を宣言する場所として「プロシージャ内」に変数を宣言できます。
この例では、変数名「strTest2」を文字列型として4行目で定義しています。
つづいて、7行目ではその変数に文字列データである"Good Morning!"を代入していますね。
では、このプロシージャ「Sample007_2」を実行してみましょう。
無事、変数「strTest2」の内容が表示されましたよね。
「じゃあ変数の宣言方法(場所)は、宣言セクション内と今回のプロシージャ内のどちらにすればいいの?」と疑問に思われるかもしれません。
では、その説明に入る前に、また少し手を動かしてみてください。
下図のように、今度はSample007_1の10, 11行目とSample007_2の23, 24行目を同じ内容にしてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | Option Explicit '変数の宣言 Dim strTest As String Sub Sample007_1() '文字列を文字列型の変数「strTest」へ代入 strTest = "Hello! World!" 'Msgbox関数の実行 MsgBox strTest MsgBox strTest2 End Sub '今回追加するプロシージャ Sub Sample007_2() 'プロシージャ内に変数を定義 Dim strTest2 As String '文字列を文字列型変数「strTest2」に代入 strTest2 = "Good Morning!" 'Msgbox関数の実行 MsgBox strTest MsgBox strTest2 End Sub |
その上で、Sample007_1を実行してみると、次のように、「strTest2」は変数として定義されていない旨のエラーが生じてしまいます。
この理由ですが、変数「strTest2」はプロシージャ「Sample007_2」に定義されているからです。つまり、プロシージャ内で定義された変数は、そのプロシージャ内でしか有効にならないということです。
つづいて、Sample007_2を実行してみてください。
今度はエラーが起きずに、コードは実行されます。ただし、Sample007_2内では変数strTestに代入する式は記述されていませんから、下図のように文字列型変数の初期値 ""(長さ0文字の文字列)が出力されます。
OKを押すと、次のMsgbox関数の実行結果(24行目)がウィンドウに出力されます(下図)
では今回エラーが起きなかった理由についてです。
まず、最初にSample007_1でエラーを起こした変数「strTest2」については、実行しているSample007_2内で定義されてますから、今回はエラーにはなりません。
ところが、変数「strTest」については、Sample007_2内では定義されていませんよね。なのにSample007_1のようなエラーが生じませんでした。
この理由は、変数「strTest」が宣言セクションで定義されているからです。
つまり、宣言セクションで定義されている変数は、そのモジュール内に書かれたプロシージャであれば、どのプロシージャで呼び出されても常に有効であるということです。
今回の例で言い換えますと、モジュール内に書かれたプロシージャは、「Sample007_01」と「Sample007_02」ですので、宣言セクションで宣言された変数「strTest」は、これら2つのプロシージャで有効になります。
このことから、宣言セクションで宣言された変数をモジュール変数といいます。
さらに繰り返しになりますが、「Sample007_02」プロシージャ内で定義された変数「strTest2」は、「Sample007_02」でのみ有効で、「Sample007_01」で呼び出しても認識されません。
「宣言セクション」か「プロシージャ内」のどちらで変数を宣言するか
「宣言セクション」か、もしくは「プロシージャ内」のどちらで変数を宣言するかについてですが、まず、1つのプロシージャ内でしか使われない変数については、「プロシージャ内」で宣言します。また、複数のプロシージャに共通して使われる変数については、「宣言セクション」でモジュール変数として宣言します。
あまりお勧めできないのは、あるプロシージャだけに使われる変数もモジュール変数として宣言することです。理由の1つは、変数の数が多くなると、それだけ多くの変数が宣言セクションに記述されますので、VBAコードの可読性が悪くなるからです。
2つ目の理由ですが、例えばすべての変数をモジュール変数として宣言したとします。そして開発を続ける途中、もしくは開発が終わった段階で、不要になったプロシージャがいくつかあったとします。
この場合、不要になったプロシージャ自身は削除か、コメントアウトをすれば良いのですが、この不要になったプロシージャだけで使われている変数も本来なら削除したいですよね。
ところが、すべての変数を宣言セクションに記述してしまっていると、不要なプロシージャだけに使われている変数も、宣言セクション内の多くの変数の中に埋もれて記述されていますので、その中から探して削除するのが面倒になります。
また、誤って宣言セクション内の他の変数を削除してしまうこともありますので、ある1つのプロシージャ内だけに使われている変数であれば、そのプロシージャ内に定義することをおすすめします。
そうすれば、もしそのプロシージャが不要になったときも、プロシージャごと削除すれば、変数も一緒に削除できますから。
まとめ
「変数の宣言を強制する」の設定方法と、設定するメリットについて解説しました。さらに、VBAの変数を宣言する場所は「宣言セクション」と「プロシージャ内」の2か所があり、それぞれでVBAコードへの影響が異なることをお伝えしました。
また、これら2つの変数宣言の場所の使い分けについても、理由と共にお伝えしました。