EB000014_VBAエキスパート(ExcelVBAベーシック)合格講座/第十四回:変数

VBAエキスパート(ExcelVBAベーシック)合格講座/第十四回:変数 ExcelVBA Basic
  1. このページの内容について
  2. 変数
    1. 変数とは
      1. サンプルコード(クリックでコピー)
      2. 処理時間の違いを体感しましょう
    2. 変数の型
    3. 変数の宣言
      1. 変数を宣言する理由
      2. 変数宣言の書式
      3. 宣言を省略しても同じ結果になります
      4. 変数を宣言しないと起きること
      5. 変数の宣言を強制する
        1. VBEのオプションを開く
        2. 編集タブから「変数の宣言を強制する」を選択
        3. 新しいモジュールを作成すると変数の宣言を強制する文言が自動追加されます
        4. 変数を宣言せずに使用すると起きるエラー
      6. 宣言の省略記法
        1. サンプルコード(クリックでコピー)
        2. 誤った省略の仕方
    4. 変数の初期値
      1. サンプルコード(クリックでコピー)
      2. 変数の状態はローカルウィンドウから確認しましょう
    5. 変数への代入
      1. 値の代入
      2. オブジェクトの代入
    6. 変数の適用範囲(スコープ)
      1. スコープとは
      2. ローカル変数(局所変数)
        1. ローカル変数とは
        2. サンプルコード(クリックでコピー)
        3. 変数の宣言を強制しているかによって結果が異なります
      3. モジュールレベル変数
        1. モジュールレベル変数とは
        2. サンプルコード(クリックでコピー)
        3. 別のプロシージャ間で変数を共有することができました
      4. パブリック変数(グローバル変数)
    7. 変数の有効期間(寿命)
      1. 宣言方法による変数の有効期間の違い
        1. サンプルコード(クリックでコピー)
        2. 実行結果
      2. 変数の初期化の重要性
        1. サンプルコード(クリックでコピー)
        2. 実行結果
  3. 【PR】VBAエキスパート試験対策記事

このページの内容について

このページは、VBAエキスパート(ExcelVBAベーシック)試験合格講座の第十四回記事です。第公式テキスト第5章「変数と定数」の内容について解説します。1時間の講義でお話する程度の分量です。講座受講者の復習での利用を想定しています。

変数

変数とは

データを一時的に格納しておく記憶域のことです。Excelのセル1つのようなものです。通常、セルへデータを書き出すよりも変数にデータを格納する方が処理速度が速いです。特に何万行ものデータを扱うと体感速度が大きく異なります。

サンプルコード(クリックでコピー)

Private Sub LoopRange50000()

Dim target_rng As Range
Dim i As Long

Set target_rng = ThisWorkbook.Worksheets(1).Range("A1")
Debug.Print Now

For i = 1 To 50000 Step 1
target_rng.Value = i
Next i

Debug.Print Now

End Sub
Private Sub LoopVariableMillion()

Dim x As Long
Dim i As Long

Debug.Print Now

For i = 1 To 1000000 Step 1
x = i
Next i

Debug.Print Now

End Sub

処理時間の違いを体感しましょう

サンプル上段のコードを実行すると、マクロを実行中のブックの左から1番目のシートのセルA1に5万回データ入力をします。入力前と後の時間がイミディエイトウィンドウに表示さます。下段のコードを実行すると変数に100万回データの格納を実施します。

私のPC環境
 サンプル上 ・・・ 12秒
 サンプル下 ・・・ 1秒未満

という結果になります。
大した差に見えないかもしれませんが、マクロ実行中に12秒も待たされると不安になるものです。自身の環境でも試してみてください。PCの性能によってはさらに時間がかかると思いますので、繰り返す数値は調整しましょう。

変数の型

変数には型を設定することができ、下記のようなものがあります。Excelのセルの書式のようなものです。

表記型名格納できるデータ
Booleanブール型True/False
Byteバイト型整数(0~255)
Integer整数型整数(-32,768~32,767)
Long長整数型整数(-2,147,483,648~2,147,483,647)
Currency通貨型小数点第四位までの数(-92,233,720,385,477.5808~922,337,203,685,477.5807)
Single単精度浮動小数点数型負の値の場合は -3.4028235E+38 から -1.401298E-45 まで、
正の値の場合は 1.401298E-45 から 3.4028235E+38 まで
Double倍精度浮動小数点数型負の値の場合は-1.79769313486231570 E + 308 から -4.94065645841246544 E-324まで
正の値の場合は1.79769313486231570 E + 308まで
Date日付型日付:100年1月1日~9999年12月31日
時刻:0:00:00~23:59:59
String文字列型最大20億文字
Objectオブジェクト型オブジェクト
Variantバリアント型変数に格納できるすべてのデータ

昔はメモリ節約のため、大きな値を格納しないことが事前にわかっている場合は、それに見合った小さな型を使用することが推奨されていました。しかし、いまはPC性能が向上しておりメモリを節約しても人間が体感できるほど実行速度に影響がでないため「大は小を兼ねる」型を選択しましょう。整数型は「Long」・小数点数型は「Double」がよく使用されます。

変数の宣言

変数を宣言する理由

変数は宣言することができます。宣言をすることで型が一目でわかるため、コードの可読性が向上します。宣言を省略して変数を使用する場合、すべて「Variant」型とみなされます。

変数宣言の書式

Dim 変数名 As 型

宣言を省略しても同じ結果になります

Private Sub Test_Decleare()
Dim cnt As Long
cnt = cnt + 1
Debug.Print cnt
End Sub
Private Sub Test_UnDecleare()
cnt = cnt + 1
Debug.Print cnt
End Sub

上記2つのサンプルをそれぞれ実行しても結果は同じです。

変数を宣言しないと起きること

変数の宣言は省略することができますが、宣言をしない場合、どんな変数も有効となってしまい開発者の意図しないエラーが発生することがあります。下記サンプルの実行結果はイミディエイトウィンドウに200が出力されるはずですが、そうなりません。どうすれば200が表示されるでしょうか?修正点を一目で判断できるでしょうか。

Private Sub Test_0O0O()
Dim No_01 As Long
Dim No_02 As Long

No_01 = 100
No_02 = 100

Debug.Print No_01 + No_O2
End Sub

変数の宣言を強制する

変数の宣言はExcelの設定で「強制」することができます。

VBEのオプションを開く

VBEを起動(「Alt」+「F11」)し、リボンの「ツール」⇒「オプション」を開く。

編集タブから「変数の宣言を強制する」を選択

「編集」タブ⇒「変数の宣言を強制する(R)」にチェックを入れて「OK」を押下する

新しいモジュールを作成すると変数の宣言を強制する文言が自動追加されます

設定が完了すると、新しく作成するモジュールの冒頭に「Option Explicit」という文言が自動で追加されるようになります。この文言はこのモジュール内で変数の宣言を強制し、宣言されていない変数がある場合、プロシージャの実行前にコンパイルエラーを発生させるというものです。設定によって変数の宣言が強制されているわけではなく、設定によって変数の宣言を強制する文言が自動追加されるようになったということです。そのため、変数の宣言を強制する設定をしていても手動で文言を削除すれば変数を宣言なしで使用できます。

変数を宣言せずに使用すると起きるエラー

前述のサンプルコードを変数の宣言を強制した状態で実行すると以下のようになり「No_02」と入力されるべき箇所に「No_O2」と入力されていたことがわかります。

宣言の省略記法

マクロが複雑になるほど使用する変数も多くなります。そんな時、複数の宣言を「,(カンマ)」で区切って1行にまとめて書くとコードの行数を抑えることができます。

サンプルコード(クリックでコピー)
Private Sub Test_Decleares()
Dim i As Long, j As Long, k As Long
Dim x, y, z As Long
Stop
End Sub
誤った省略の仕方

上記サンプルを実行すると「Stop」で動作を停止します。そこでローカルウィンドウを開き変数の中身を確認してみましょう。「x」と「y」がLong型ではなく、Variant型になってしまっていることがわかります。「,」で区切る場合でも「As 型」まで記述しないと意図した型になりません。

変数の初期値

変数には型に応じてそれぞれ初期値が設定されています。

サンプルコード(クリックでコピー)

Private Sub InitialValue()
Dim bool As Boolean
Dim by As Byte
Dim i As Integer
Dim lng As Long
Dim cur As Currency
Dim sin As Single
Dim dbl As Double
Dim day As Date
Dim str As String
Dim obj As Object
Dim val As Variant
Stop
End Sub

変数の状態はローカルウィンドウから確認しましょう

上記サンプルを実行すると「Stop」で動作を停止します。そこでローカルウィンドウを開き変数の中身を確認してみましょう。

変数への代入

値の代入

代入演算子「=」を使用します。

Private Sub Test_SubstituteValue()

Dim hello As String
Dim today As String

hello = "こんにちは"
today = "2024/11/24"

Call MsgBox(hello & today & "です。")

End Sub

オブジェクトの代入

「Set」と代入演算子「=」を使用します。

Private Sub Test_SubstituteObject()

Dim wb As Workbook
Dim ws As Worksheet

Set wb = ThisWorkbook
Set ws = wb.Worksheets(1)

Debug.Print ws.Name

End Sub

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

スコープとは

変数は宣言方法や宣言する場所によって使用できる範囲が異なります。この変数を使用できる範囲のことを「変数のスコープ」や「変数の可視範囲」と呼びます。

ローカル変数(局所変数)

ローカル変数とは

ローカル変数とはプロシージャ内で宣言された変数のことです。プロシージャ内で宣言された変数はそのプロシージャ内でしか使用することができません。下記サンプルコードで確認してみ下さい。「Test_Scope」はプロシージャ内で「msg」という変数を宣言し、msgに文字列を代入しています。その後「Test_ScopeSub」を呼び出していますがTest_ScopeSub内でmsgを使おうとしています。

サンプルコード(クリックでコピー)
Private Sub Test_Scope()

Dim msg As String
msg = "これはローカル変数です"

Call Test_ScopeSub

End Sub

Private Sub Test_ScopeSub()

Call MsgBox(msg, vbInformation)

End Sub
変数の宣言を強制しているかによって結果が異なります

上記サンプルコードで「Test_Scope」を実行すると、変数の宣言を強制している場合は「Test_ScopeSub」が呼び出されるときに「変数が定義されていません。」というエラーが発生します。変数の宣言を強制していない場合は、このエラーを回避できますが、「Test_ScopeSub」のmsgは「Test_Scope」のmsgとは別物とみなされるため、空白のメッセージが表示されます。

モジュールレベル変数

モジュールレベル変数とは

変数の宣言はプロシージャの外でも実行することができます。プロシージャの外で宣言された変数は、モジュール内であればどのプロシージャからも使用することができます。下記サンプルでは前述のようなエラーは発生しません。

モジュールレベル変数の宣言はどのプロシージャよりも上に記述する必要があります。

サンプルコード(クリックでコピー)
Dim msg As String

Private Sub Test_ScopeModule()

msg = "これはモジュールレベル変数です"

Call Test_ScopeModuleSub

End Sub

Private Sub Test_ScopeModuleSub()

Call MsgBox(msg, vbInformation)

End Sub
別のプロシージャ間で変数を共有することができました

上記のサンプルコードで「Test_ScopeModule」を実行するとモジュールレベル変数である「msg」に文字列を代入し「Test_ScopeModuleSub」を呼び出します。呼び出し先ではmsgをメッセージ表示します。モジュール内で変数の共有ができているためエラーが発生せず、また意図した通りのメッセージが表示されます。

モジュールレベル変数を定義する場合「Dim」は「Private」と置き換えて宣言することができます。この場合でも変数のスコープは同じです。

パブリック変数(グローバル変数)

モジュールレベル変数の「Dim」や「Private」を「Public」に置き換えて宣言すると別のモジュールからも使用可能な変数となります。サンプルコードでは表現しきれませんので、自身で試してみてください。

変数の有効期間(寿命)

宣言方法による変数の有効期間の違い

プロシージャ内で宣言された変数は、プロシージャの動作が終了すると中身は消えてしまいます。そのため2回目、3回目を実行しても結果は同じです。しかしモジュールレベル変数とパブリック変数はプロシージャ終了後も値が残るため、マクロの内容によっては1回目と2回目で実行結果が変わってしまいます。

サンプルコード(クリックでコピー)
Dim cnt As Long

Private Sub Test_Life()

cnt = cnt + 1
Debug.Print cnt

End Sub
実行結果

上記サンプルを実行すると実行の都度、イミディエイトウィンドウに表示される数値が増えていくことが確認できます。このように、モジュールレベル変数とパブリック変数はプロシージャの動作終了後も値を保持します。

変数の初期化の重要性

上記のように実行の都度結果が変わってしまうマクロは管理上好ましくありません。ユーザーの意図しない結果となってしまうことがあります。意図して実行結果を変えたい場合を除き、原則は変数を初期化して、何度実行しても同じ結果になるマクロを作成しましょう。

サンプルコード(クリックでコピー)
Dim cnt As Long

Private Sub Test_Initialize()

cnt = 0
cnt = cnt + 1
Debug.Print cnt

End Sub
実行結果

上記サンプルを実行すると、何度実行しても結果同じイミディエイトウィンドウに「1」が出力されます。

上記のように、変数に最初に入れておく値を代入することを「変数を初期化する」と表現します。

【PR】VBAエキスパート試験対策記事

当サイトでは、オデッセイコミュニケーションズ社が運営する試験であるVBAエキスパートExcel VBA ベーシックExcel VBA スタンダード)の出題範囲をベースに用語や各種関数の解説などを行っています。試験合格に向けて必須と言われる公式テキストに沿って解説をしています。受験をするか悩んでいる方、テキストとは別視点の解説を見てみたい方、受験はしないがExcelVBA(マクロ)に興味がある方へ向けた記事です。

Comment