目標
VBAのバリアント型を理解してい利用できる。
VBAのバリアント型の概要と利用方法
バリアント型の概要
バリアント型は、ほとんどの型のデータを格納できる特殊な型です。
※ 固定長文字列データ(Stringに対してアスタリスクを利用して文字の個数を指定する型)やユーザー定義型は扱えません。
変数宣言で型を指定しない場合は、このバリアント型として変数が準備されます。バリアント型は、数値だと最大16バイト分、文字列であれば22バイト+超過文字列分の大きなサイズを使用できます。
対応できる型の格納であれば「Integer」→「String」→「Long」のように値の変更が可能です。
バリアント型の利用方法
バリアント型の変数は次のように宣言します。
Dim varSample1 As Variant
または次のように宣言します。
Dim varSample1
※ 型を指定しなければ、その変数はバリアント型になります。
サンプルプロシージャ1
バリアント型の変数に色々な値を設定するプログラムを作成して動きを確認します。
Option Explicit
Sub varSample_Part1()
Worksheets("Sheet1").Activate
Dim varSample0
Dim varSample1 As Variant
Dim varSample2 As Variant
Dim varSample3 As Variant
Dim varSample4 As Variant
Dim varSample5 As Variant
varSample1 = 12345
varSample2 = 123.456
varSample3 = "文字列"
varSample4 = True
varSample5 = Date
MsgBox _
"varSample0:" & Chr(9) & varSample0 & Chr(9) & Chr(9) & VarType(varSample0) & Chr(9) & Len(varSample0) & Chr(10) & _
"varSample1:" & Chr(9) & varSample1 & Chr(9) & Chr(9) & VarType(varSample1) & Chr(9) & Len(varSample1) & Chr(10) & _
"varSample2:" & Chr(9) & varSample2 & Chr(9) & Chr(9) & VarType(varSample2) & Chr(9) & Len(varSample2) & Chr(10) & _
"varSample3:" & Chr(9) & varSample3 & Chr(9) & Chr(9) & VarType(varSample3) & Chr(9) & Len(varSample3) & Chr(10) & _
"varSample4:" & Chr(9) & varSample4 & Chr(9) & Chr(9) & VarType(varSample4) & Chr(9) & Len(varSample4) & Chr(10) & _
"varSample5:" & Chr(9) & varSample5 & Chr(9) & VarType(varSample5) & Chr(9) & Len(varSample5) & Chr(10)
End Sub
実行結果
以下のように表示されます。
出力を表でまとめてみます。
変数名 | 値 | varType (型を表す番号) | データの長さ |
varSample0 | 空 | 0(Empty) | 0 |
varSample1 | 12345 | 2(Integer) | 5 |
varSample2 | 123.456 | 5(Double) | 7 |
varSample3 | 文字列 | 8(String) | 3 |
varSample4 | True(真偽値) | 11(Boolean) | 4 |
varSample5 | Date(日付) | 7(Date) | 10 |
上のプログラムで変数「varSample0」 から 「varSample5」 は全て「Variant型」として利用されています。そして、上の表の通り、Variant型の変数は、様々な型の値を格納できます。
※ varType関数で返されている型は変数の型ではなく、Variant型の変数に格納されている「値の型」となっています。
また、Variant型の変数は、初期化(値の入力)した後からでも、別の型の代入(整数↔文字列などの型の変更)が行えます。
バリアント型の変数に対して異なる型の入力が行えるかを確認します。
※今回は結果の表示にイミディエイトウィンドウを利用しています。イミディエイトウィンドウについて
サンプルプロシージャ2(プログラムを書いてみる)
(結果表示に今回はイミディエイトウィンドウを利用しています)
Sub varSample_Part2()
Worksheets("Sheet1").Activate
Dim varSample1 As Variant
varSample1 = 12345
Debug.Print "値"; Chr(9); varSample1 & Chr(9); Chr(9) & " VarType:"; Chr(9); VarType(varSample1)
varSample1 = 123.456
Debug.Print "値"; Chr(9); varSample1 & Chr(9); Chr(9) & " VarType:"; Chr(9); VarType(varSample1)
varSample1 = "文字列"
Debug.Print "値"; Chr(9); varSample1 & Chr(9); Chr(9) & " VarType:"; Chr(9); VarType(varSample1)
varSample1 = True
Debug.Print "値"; Chr(9); varSample1 & Chr(9); Chr(9) & " VarType:"; Chr(9); VarType(varSample1)
varSample1 = Date
Debug.Print "値"; Chr(9); varSample1 & Chr(9) & " VarType:"; Chr(9); VarType(varSample1)
Set varSample1 = Range("C3")
Debug.Print "値"; Chr(9); varSample1 & Chr(9); Chr(9); Chr(9) & " VarType:"; Chr(9); VarType(varSample1)
End Sub
実行結果
VBAの変数は、通常、宣言時には「データ型」の指定を行います。これはVBAでは変数が「データ型」を持っていることを意味します(静的型付け)。そして、これとは別に変数に結び付く「値」は、プログラミング言語に関係なく、必ず「データ型」を持っています。(例:「1」は整数型)
そして、VBAでは、値(リテラル)が持つ「データ型」と変数が持つ「データ型」が共通でないと変数と値は結びつけることができないというのが基本の考え方です。
バリアント型の変数は、この「共通している必要」を柔軟にした結び付けを行える変数といえます。
バリアント型がよく用いられる利用パターンに配列があります。それ以外には、型は決まっていないけど、とりあえず間に合わせの変数が欲しいときなどでも利用します。
プリミティブ型と参照型
これまで様々な型の変数を宣言し利用してきましたが、これらの型は大きくふたつに分類できます。これが「プリミティブ型(基本型)」と「参照型」です。
扱う型の種類 | データ型 | 型 |
整数 | Byte | プリミティブ型 |
Integer | プリミティブ型 | |
Long | プリミティブ型 | |
浮動小数 | Single | プリミティブ型 |
Double | プリミティブ型 | |
通貨 | Currency | プリミティブ型 |
日付 | Date | プリミティブ型 |
文字列 | String | プリミティブ型 |
真偽値 | Boolean | プリミティブ型 |
オブジェクト | Object | 参照型 |
様々な型 | Variant | ― |
プリミティブ型は「変数名」と「値」を結びつけます。
参照型は「変数名」と「オブジェクト(オブジェクト型)」を結びつけます。
プリミティブ型は変数名と値を「1:1」で結びつけますが、参照型は複数の変数名とひとつのオブジェクトを「複数:1」で結びつけ共有することができます。
- プリミティブ型…変数が値を別々に管理する
- 参照…ひとつまたは複数の変数がオブジェクトを共有して管理する
サンプルプロシージャ1(参照型の利用)
プログラムでの確認:オブジェクト変数を利用した参照のプログラム
Sub compareVariable1()
Worksheets("Sheet1").Activate
Dim Sample1 As Range
Dim Sample2 As Range
Dim Sample3 As Range
Range("C3").Value = "ABC"
Set Sample1 = Range("C3")
Set Sample2 = Range("C3")
Set Sample3 = Range("C3")
Sample1 = "EFG"
MsgBox "Sample2:" & Chr(9) & Sample2 & Chr(10) & _
"Sample3:" & Chr(9) & Sample3 & Chr(10)
End Sub
プログラムの実行
全てのオブジェクト変数に対してRange(“C3”)への参照を代入しています。この時点で全ての変数でRange(“C3”)を共有して読み書きができる状態となります。
その後、Sample1に対して”EFG”を代入しています。これによってRange(“C3”)の値を上書きすることになり、Sample2やSample3からもRange(“C3”)の新しい値”EFG”を見ることになります。
サンプルプロシージャ2(プリミティブ型の利用)
プログラムでの確認:参照をしないプリミティブ型の変数を利用したプログラム
Sub compareVariable2()
Dim Sample1 As String
Dim Sample2 As String
Dim Sample3 As String
Range("C3").Value = "ABC"
Sample1 = Range("C3").Value
Sample2 = Range("C3").Value
Sample3 = Range("C3").Value
Sample1 = "EFG"
MsgBox "Sample2:" & Chr(9) & Sample2 & Chr(10) & _
"Sample3:" & Chr(9) & Sample3 & Chr(10)
End Sub
参照でないプログラムの実行結果
全ての変数に対してRange(“C3”).Value(値)を代入しています。この時点で全ての変数で”ABC”という値が保管されました。
その後、Sample1に対しては”EFG”を代入していますが、参照とは違ってセルC3の値や変数Sample2やSample3に変化はありません。(変数Sample1は”EFG”)
バリアント型の変数にオブジェクト型や配列を格納する
サンプルプロシージャ4
ここでは、オブジェクト型の格納と配列の格納を行い、格納したオブジェクトと配列のメモリ上のアドレス番地の取得と、その大きさの確認を行います。
Sub varSample_Part3()
Worksheets("Sheet1").Activate
Dim varSample6 As Variant
Set varSample6 = Range("C3")
Dim varSample7 As Variant
varSample7 = Array(12345, "あいうえお", 123.456, False, Date)
MsgBox _
"varSample6:" & Chr(9) & VarPtr(varSample6) & Chr(9) & Chr(9) & VarType(varSample6) & Chr(9) & Len(varSample6) & Chr(10) & _
"varSample7:" & Chr(9) & VarPtr(varSample7) & Chr(9) & Chr(9) & VarType(varSample7) & Chr(9) & UBound(varSample7) & Chr(10) & _
"varSample7(0):" & Chr(9) & VarPtr(varSample7(0)) & Chr(10) & _
"varSample7(1):" & Chr(9) & VarPtr(varSample7(1)) & Chr(10) & _
"varSample7(2):" & Chr(9) & VarPtr(varSample7(2)) & Chr(10) & _
"varSample7(3):" & Chr(9) & VarPtr(varSample7(3)) & Chr(10) & _
"varSample7(4):" & Chr(9) & VarPtr(varSample7(4)) & Chr(10) & _
"varSample7:" & varSample7(0) & "," & varSample7(1) & "," & varSample7(2) & "," & varSample7(3) & "," & varSample7(4)
End Sub
実行結果
以下のように表示されます
変数名 | VarPtr メモリアドレス | varType (型を表す番号) | データの長さ 配列の長さ |
varSample6 | 2050581068968 | 0(Empty) | 0 |
varSample7 | 2050581068920 | 8204(Variant + Array) | 4 |
VarPtr関数は変数が結びつくオブジェクトのメモリアドレスを取得します。メモリアドレスはIntegerやStringなどで宣言した変数でも確認ができます。
データの長さについてはLen関数を利用しています。その長さは「0」となっています。これはオブジェクトとして参照しているセルC3に数値や文字の値が入っていないためです。オブジェクト変数はSetステートメントを利用して参照を代入します。
配列も基本的には参照を利用するオブジェクトです。配列の場合はデータの長さをLen関数で表示しようとするとエラーとなります。配列についてはUBound関数を利用して要素数を数えます。
今回は以上となります。
ブックマークのすすめ
「ほわほわぶろぐ」を常に検索するのが面倒だという方はブックマークをお勧めします。ブックマークの設定は別記事にて掲載しています。