4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【5分でVBA学習】変数の有効範囲「スコープ」(おまけに猫とアクセス修飾子も添えて) ~Excelフィルタリングツール コード解説 #5~

Last updated at Posted at 2024-05-17

1. はじめに

ARアドバンストテクノロジ株式会社(ARI)の鈴木タクヤです。

猫って、いいですよね(唐突)。
最近帰省して実家の猫と触れ合ってきました。無理矢理だっこして引っ掻かれたりもしたけれど、私はげんきです。

さて、今回はExcelフィルタリングツールのソースコード解説第5回です。

(ツールの詳細については以下の記事を、「Excelフィルタリングツール解説シリーズ」タグの記事一覧については以下の記事下部「5. 解説記事のリンク」をご参照ください。)

解説第4回 は変数についての記事でしたが、今回のテーマはその有効範囲「スコープ」です。

2. 変数の「スコープ」とは

変数は一度宣言しておけば使いたいときに使えて便利ですが、どこでも使えるわけではありません。変数の有効範囲を スコープ と呼びます。

2-1 変数のスコープの例

以下はメッセージボックスで変数の内容を表示する例です。

例①
'Subプロシージャa1
Sub a1()
    Dim x As String                 'String型(文字列)用の変数 x を宣言
    x = "猫って、いいですよね。"     '変数 x に文字列を代入
    MsgBox x                        '変数 x の内容をメッセージボックスに表示する
End Sub

例①では Subプロシージャ1 a1の中で変数 xに値を設定し、x引数2 としてMsgBox関数を呼んでいます。このa1を実行すると・・・
image.png
↑こうなります。変数 xに文字列"猫って、いいですよね。"が代入されたことが分かります。

次は少し変えてみます。

例②
'Subプロシージャa2
Sub a2()
    Dim x As String                 'String型(文字列)用の変数 x を宣言
    x = "猫って、いいですよね。"     '変数 x に文字列を代入
    Call b2                          'プロシージャ b2 を呼ぶ
End Sub

'Subプロシージャb2
Sub b2()
    MsgBox x                        '変数 x の内容をメッセージボックスに表示する
End Sub

例②では2つのSubプロシージャが登場しますが、プロシージャa2は変数xに値を設定し、プロシージャb2を呼びます。呼ばれたb2xを引数としてMsgBox関数を呼んでいます。このa2を実行すると・・・
image.png
↑こうなります。"猫って、いいですよね。"が表示されません。

実は プロシージャ内で宣言した変数は、そのプロシージャ内でしか使用できません。 このとき 「変数のスコープは宣言されたプロシージャ内のみ」 と言えます。

例②ではb2の中で変数xを宣言・代入していないため、MsgBox関数で値を表示しようとしている変数xは、"猫って、いいですよね。"が代入されたxとは別の変数とみなされてしまいます。よってメッセージボックスは空(Empty)の表示になります。

スコープから少しでも外れると使えなくなる感じ、飼い猫が家の外で飼い主に呼ばれても知らんぷりするのと似ています(?)

あるプロシージャで宣言した変数の値を別のプロシージャに受け渡したい場合には、以下の例③のように引数として渡す必要があります。

例③
'Subプロシージャa3
Sub a3()
    Dim x As String                 'String型(文字列)用の変数 x を宣言
    x = "猫って、いいですよね!"     '変数 x に文字列を代入
    Call b3(x)                      'x を引数としてプロシージャ b3 を呼ぶ
End Sub

'Subプロシージャb3
Sub b3(ByVal y As String)           '👈引数をString型で指定
    MsgBox y                        '👈引数として渡された文字列をメッセージボックスに表示する
End Sub

(例③のb3に登場するyxに置き換え可能ですが、a3xとは別物であることを強調するためにyとしています。このy"猫って、いいですよね!"が渡されます。 ByVal については 解説第3回 をご参照ください。)

このa3を実行すると・・・
image.png
↑こうなります。(おわかりいただけただろうか…)

VBAのコードの先頭に「Option Explicit」の記載がある場合には変数の宣言が強制されるため、例②のa2を実行するとb2側で「変数xが宣言されてないよ!」とコンパイルエラー3になります。
image.png

2-2 モジュールレベル変数

上では「プロシージャ内で宣言した変数は、そのプロシージャ内でしか使用できません。」と書きましたが、最初のSubまたはFunctionより前(「宣言セクション」と呼びます)で宣言した変数は、その モジュール4 全体で使用できます。このような変数を モジュールレベル変数 と呼びます。

例④
Dim x As String    '👈String型(文字列)用の変数 x をモジュールレベル変数として宣言

'Subプロシージャa4
Sub a4()
    x = "猫って、いいですよね!!"     '変数 x に文字列を代入
    Call b4                          'プロシージャ b4 を呼ぶ
End Sub

'Subプロシージャb4
Sub b4()
    MsgBox x                        '変数 x の内容をメッセージボックスに表示する
End Sub

例④ではDim x As Stringの記述をSub a4()より前で宣言しています。このa4またはb4を実行すると・・・
image.png
↑こうなります。xa4の中で値を代入されb4の中で使用されています。つまりxのスコープはa4b4を含むモジュール全体であることが分かります。

ちなみにオス猫は複数のメス猫の縄張りを囲むようにして自分の縄張りを決めるとか。モジュールレベル変数のスコープは、オス猫の縄張りみたいなものですね(?)

Excelフィルタリングツールでも、モジュールレベル変数を使用しています。

Excelフィルタリングツール冒頭
'このツールの設定値を代入する変数の定義
Dim modeNo As Integer                   'マクロの起動モード設定用(0:表見出しのコピー, 1:フィルタリング, 2:フィルタのクリア)
Dim settingSheetName As String          'フィルタ条件等を記載する本ツールの設定用シート名
(中略)
Dim targetBook As Workbook              'フィルタ対象ブック


'■共通処理(複数のマクロから呼ばれる)
Sub exeCommonProc()                     '👈最初のSub

    '処理高速化のおまじない
    With Applicatio
(後略)

最初に登場するSubプロシージャexeCommonProcより前で宣言した変数は、複数のSub/Functionプロシージャで使用しています。(多分。)

予期せぬ変数の値の書き換えバグを防ぐためにも、変数はなるべく狭いスコープで使用 することをオススメします。そう、できれば猫の額ほどの。

3. おわりに

以上、変数のスコープについての解説でした。
悪ノリの猫まみれな記事となりましたが、猫アレルギーの方には申し訳ございません。

次回は、Ifステートメントについて解説します。

👇次回

4. おまけ;アクセス修飾子

Excelフィルタリングツールでは使用していませんが、変数のスコープに関蓮する アクセス修飾子 というものがあります。大規模開発などでは必須ですが、個人的なツールの作成などでは必要に迫られないと思うので、アクセス修飾子を2種類だけ紹介します。

アクセス修飾子は変数以外に使用することもありますが、本記事では変数に絞って紹介します。

4-1 Public

モジュールレベル変数の宣言におけるDimPublic に書き換えると、さらにスコープが広がり、他のモジュールでも使用できるようになります。

Public x As String

Sub a()
(以下略)

4-2 Private

モジュールレベル変数の宣言におけるDimPrivate に書き換えても、Dimと同様にそのモジュール内のどこでも使える変数となります。Publicとは異なり、他のモジュールでは使用できません。
ただし、Dimとは異なり Private はプロシージャ内では使用できません。
他のプログラミング言語ではDimより Private の方がよく使用されます。

Private x As String   '👈Dim x As String と同じ意味

Sub a()
   Private x As String   '👈プロシージャ内ではコンパイルエラー
End Sub

5. 参考文献

こちらはMicrosoftの公式ドキュメントです。

こちらは私がものすごくお世話になっている「エクセルの神髄」という解説サイト。より深く学習を進めたい方は是非。

猫の縄張りについて。

  1. Subプロシージャ:「Sub」と「End Sub」で挟まれた、マクロの処理内容を記述する部分のこと。解説第2回参照

  2. 引数:プログラムの中で処理を呼び出す際に渡す値のこと。解説第3回参照

  3. コンパイルエラー:人間がプログラミング言語で書いたコードを、0と1のみであらわす機械語に変換する「コンパイル」の際に発生するエラーのこと。

  4. モジュール:VBAのコードを書く場所。複雑な処理の場合には複数のモジュールのプロシージャを組み合わせてマクロの処理を実行することも可能。image.png

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?