更新日:、 作成日:
VBA 値型と参照型の違い
はじめに
Excel VBA マクロの値型と参照型の違いを紹介します。
変数名 = 値 のように代入するのが値型です。Integer や String などがあります。
Set 変数名 = オブジェクト のように Set を付けて代入するのが参照型です。Worksheet や Range、クラスなどがあります。
値型と参照型の違いは、参照型の変数を別の変数に代入しても同じインスタンスです。そのため、どちらの変数の値を変更しても、もう一方にも反映されます。
値型と参照型とは
データ型には値型と参照型があります。
値型には Integer や String や Date などがあります。変数名 = 値 のように代入できるものはすべて値型です。
参照型には Worksheet や Range、クラスで作成されたものがあります。すべてオブジェクトです。Set 変数名 = オブジェクト のように、代入に Set が必要な型はすべて参照型です。
値型と参照型の違い
参照型の変数を別の変数に代入したときに値型との違いがあります。Excel のセル参照を使ったことがあれば理解しやすいと思います。
次のような単純な Value 変数だけを持ったクラスで説明します。
Class1 (参照型) のコード
Public Value As Integer
Sheet1 のコード
Class1 の変数を 2 つ宣言します。
Dim c1 As Class1
Dim c2 As Class1
Class1 をインスタンス化します。これは新しいセルを参照するのと同じです。
Set c1 = New Class1
インスタンスを別の変数に代入します。これはセル参照をコピーするのと同じです。Value の値をコピーするのではなく参照をコピーする、この部分が値型と参照型の違いです。
Set c2 = c1
c1 の Value に値を設定します。c2 も同じセルを参照しているので、同じ値になります。
c1.Value = 10
Debug.Print(c1.Value) ' 10
Debug.Print(c2.Value) ' 10
c2 に新しいインスタンスを設定します。これは別のセルを参照するのと同じです。インスタンス化する度に、新しいセルを参照することになります。
Set c2 = New Class1
参照先が違うので c1 と c2 の Value は別の値になります。
c2.Value = 20
Debug.Print(c1.Value) ' 10
Debug.Print(c2.Value) ' 20
スポンサーリンク
引数に参照型を渡す
関数の引数に参照型を渡すと、インスタンスを別の変数に代入しているのと同じで、参照を渡しています。そのため、関数の中で参照型の値が変更されると渡した変数の値も変更されます。
Sub 実行()
Dim c As Class1
Set c = New Class1
Call 参照型渡し(c)
Debug.Print(c.Value) ' 10
Set c = Nothing
End Sub
Sub 参照型渡し(ByVal c As Class1)
c.Value = 10 ' 引数に渡した変数の Value も変更される
End Sub
まとめ
オブジェクト型の変数にはインスタンスが入っています。インスタンスとはオブジェクトの参照先です。
その変数を別の変数に代入すると、インスタンスがコピーされるので同じオブジェクトが参照されます。参照先が同じなら、どちらの変数で値を変更しても両方に反映されます。
2 つの変数で別の値を持ちたいのなら、新たにインスタンス化します。新しい参照先になるので、それぞれで別の値を持てます。
値型はそのまま値がコピーされるだけなので単純です。参照型はインスタンスを意識すると理解できると思います。