【VBA基礎③】変数の種類
皆さんはVBAの変数を使用していますか?VBAの変数は、マクロ内でデータを一時的に保存するための箱のようなものです。変数には、数値や文字列などの様々なデータ型を定義することができます。今回は配列やユーザー定義型など様々な変数をまとめたので、この記事を読めば、VBAの変数について理解することができます!
この記事はVBAの基礎シリーズです。他の記事は以下のリンクからご覧いただけます!
>>>【VBA基礎④】イベント
変数とは?
1回目の記事で少し解説しましたが、VBAにおける変数とはデータを入れる箱のようなものです。箱にはデータを自由に出し入れして使用することが出来ます。変数には入れるデータの性質によって変数の型を宣言しなければなりません。これを「変数宣言」といいます。変数宣言は以下のように行います。
Dim x As Double , y As String
「Double」は実数を取り扱う変数の型、「String」は文字列を取り扱う変数の型です。これにより、xに実数を、yには文字列を自由に代入して使用できるようになります。

「Dim~」はひとつのプロシージャ内で使用できる変数を宣言するものです。変数宣言や変数の型については第1回の記事でまとめています。
変数には単一の値のみを格納するものだけでなく、複数の値を格納できる「配列」や使用者が独自に型をつくることができる「ユーザー定義型」があります。
配列について
配列とは?
一般的な変数は、変数1つにつき1つの値しか格納することができません。例えば以下のマクロを実行するとMsgBoxの表示結果は「2」となり、最初に代入された「1」は上書きされたことが分かります。
Sub test1()
Dim i As Integer
i = 1
i = 2
MsgBox i
End Sub


VBAに限らす、特別な指示をしない限りプログラミング言語は上から下へ順に実行されていきます。なので、変数も一度代入した後に再度違う値を代入すれば、それに入れ替わります。
以上のように基本的に変数にはひとつの値のみ代入できますが、複数の値を同時に代入できる変数もあります。このような変数を「配列」といいます。変数は箱のようなものと言いましたが、配列は箱をいくつも組み合わせるイメージです。
配列を使用する時は、変数宣言の際にいくつの箱を用意するかを指定する必要があります。配列の箱の数を配列の「要素」といいます。以下のように変数を宣言する際に後ろの()内に要素数を指定します。
Dim 配列名(要素の最小値 To 要素の最大値) As 変数の型
要素の最小値は省略することができます。要素の最小値を省略すると、自動的に最小値は「0」となります。以下に最小値を指定せずに配列「number」を宣言し、各要素に値を入れてみます。
Sub test2()
Dim number(3) As Integer
number(0) = 1
number(1) = 2
number(2) = 3
number(3) = 4
MsgBox number(0) + number(1) + number(2) + number(3)
End Sub

これを実行すると「10」が表示されます。1つの変数「number」に複数の値が代入され、その合計値が示されたことが分かります。また、要素の最小値を省略したので、最小値には「0」が入り、「0~3」まで4つの要素が作成されています。このように、配列は複数の要素に別々の情報を同時に代入できます。配列の要素は番号で識別されています。この番号を「インデックス」といいます。
動的配列
先ほど、配列の宣言時に要素数を指定すると言いましたが、宣言時にいくつの要素が必要になるのか分からない場合があると思います。そのような時は要素数を指定せずに配列を宣言することができます。これを「動的配列」といいます。
動的配列を宣言した場合、配列に値を代入するときに改めて要素数を指定する必要があります。この時の命令文には「ReDim」を使用します。以下のマクロは動的配列で宣言後に要素数を指定しています。
Sub test3()
Dim number() As Integer
ReDim number(1)
number(0) = 1
number(1) = 2
ReDim number(3)
number(2) = 3
number(3) = 4
MsgBox number(0) + number(1) + number(2) + number(3)
End Sub

インデックス(0)と(1)にもそれぞれ値を入れたので、結果は「10」になりそうですが、実はこれを実行すると「7」が表示されます。これは配列の要素に値を代入した後にさらに「ReDim」で要素数を指定し直したからです。「ReDim」で要素数を指定し直すと以前に代入した値はリセットされてしまいます。

宣言時に要素数を指定した配列は「ReDim」で要素数を指定し直すことはできません。
既存の要素に入れた値をリセットせずに、要素数を指定し直すには「ReDim」の後に「Preserve」を記載します。
Sub test3()
Dim number() As Integer
ReDim number(1)
number(0) = 1
number(1) = 2
ReDim Preserve number(3)
number(2) = 3
number(3) = 4
MsgBox number(0) + number(1) + number(2) + number(3)
End Sub

これを実行するとインデックス(0)と(1)の値はリセットされず、表示結果は「10」となります。
静的変数
プロシージャ内で変数を宣言し、マクロを実行してプロシージャが終了すると、その変数に代入した値は消えてしまいます。以下のマクロを実行すると、表示結果は何度やっても「1」になります。
Sub test5()
Dim num As Integer
num = num + 1
MsgBox num
End Sub
一般の変数はプロシージャが終了するごとに変数に代入した値はリセットされてしまいますが、前回の計算結果を残しておきたい場合は「静的変数」による宣言を行います。
静的変数を宣言する時は以下のように「Dim」の部分を「Static」という命令に変えます。これを実行すると1回目の結果は「1」ですが、2回目の結果は「2」、3回目は「3」・・・・とプラス1ずつされていきます。これは前回変数に代入した結果が保存されているからです。
Sub test5()
Static num As Integer
num = num + 1
MsgBox num
End Sub


静的変数はモジュールやパブリックレベルで宣言することはできません。
プロシージャレベルでのみ使用できる変数です。
オブジェクト変数
今までの変数には「数値」や「文字列」などのデータを格納してきましたが、セルやワークシート、ワークブックなどの「オブジェクト」そのものを格納することができる変数もあります。このような変数を「オブジェクト変数」といいます。
オブジェクト変数の宣言
Dim 変数名 AS Range セルを扱う型
Dim 変数名 AS Worksheet ワークシートを扱う型
Dim 変数名 AS Workbook ワークブックを扱う型
Dim 変数名 AS Object すべてのオブジェクト型を扱う型

ちなみにVariant型はすべての型を格納できる変数型なので、オブジェクトも格納することができます。
オブジェクト変数にオブジェクトを格納するときは、以下のように「Set」という命令を使用します。
Set 変数名 = オブジェクト
実際にオブジェクト変数を用いてコードを書いてみます。以下のマクロを実行すると、シート「Sheet1」のセルA1の値をコピーし、シート「Sheet2」のセルA1にペーストします。様々なオブジェクトを使用するマクロを作成する際は最初に変数を定義しておけば、コードが綺麗にまとまりますね。
Sub test7()
Dim w1 As Worksheet, w2 As Worksheet
Set w1 = Worksheets("Sheet1")
Set w2 = Worksheets("Sheet2")
w1.Cells(1, 1).Copy w2.Cells(1, 1)
End Sub
ちなみにオブジェクト変数の格納したオブジェクトをリセットするにはオブジェクト変数に「Nothing」という値を代入します。
Set 変数名 = Nothing
ユーザー定義型
変数も配列も一度変数宣言を行うと、異なる変数型の値を代入することは出来なくなります。String型には文字列のみ、Integer型には整数しか代入できません。
変数に異なる型を格納するためには、ユーザー定義型を使用します。ユーザー定義型は複数の異なる変数型をセットにして、1つの変数をつくります。ユーザー定義型は以下のように宣言します。
Type ユーザー定義型の名前
変数の要素名 As 変数の型
変数の要素名 As 変数の型
・
・
・
End Type

ユーザー定義型はプロシージャの冒頭で宣言しなければなりません。プロシージャとプロシージャの中間に記載するとエラーになります。
実際にユーザー定義型を宣言してみます。Dataというユーザー定義型を作成し、変数の要素に実数型と文字列型の2つを指定します。Subプロシージャを作成し、変数宣言で、変数の型を先ほど作成したユーザー定義型にします。宣言した変数memberに数字を入れるときはmemberの後ろに「.id」、文字列を入れるときは「.name」をつけます。これはユーザー定義型で設定した変数の要素名です。こうすることで、1つの変数memberに複数の変数型の値を格納できます。このマクロの表示結果は「2024001 田中太郎」になります。
Option Explicit
Type Data
id As Long
name As String
End Type
---------------------------------------
Sub test8()
Dim member As Data
member.id = 2024001
member.name = "田中太郎"
MsgBox member.id & " " & member.name
End Sub

MsgBoxの「&」は文字と文字をつなげる命令です。
まとめ
いかがでしたでしょうか?今回はVBAの変数についてまとめました。この記事はVBAの基礎シリーズとして今後も発信していきますので、良ければ他の記事も読んでいただければ嬉しいです。それで最後までお読みいただき、ありがとうございました。