「Set Range1 = Range2」と「Range1 = Range2」の違いを検証する(VB/VBAにおけるオブジェクトの代入・比較)
VBAを触り始めて6年目なわけだが、未だにSetの使い方をよく知らなかったので(つまるところオブジェクトというものをちゃんと理解していなかったわけだが)少なくともとSetの使い方をRangeを用いて調べてみた。
今までは何となくRangeオブジェクトを使うときはSetと合わせて使うんだという風に覚えていたわけだが、ググった結果、
「Set Range1 = Range2」とするとオブジェクトとして代入になり、
「Range1 = Range2」とするとRangeのデフォルトプロパティであるValueが代入される
ということになるらしい。
実験準備
早速それを試すため以下のようなコードをVBAで作って検証してみた。
Sub main() Dim rng1 As Range, rng2 As Range Set rng1 = Range("A1") Set rng2 = Range("B1") Call MsgBoxRngDetail(rng1) Call MsgBoxRngDetail(rng2) 'rng2 = rng1 Set rng2 = rng1 Call MsgBoxRngDetail(rng1) Call MsgBoxRngDetail(rng2) If rng1 Is rng2 Then MsgBox ("rng1 is rng2") End If If rng1 = rng2 Then MsgBox ("rng1 = rng2") End If End Sub Sub MsgBoxRngDetail(ByRef rng As Range) Dim msg As String msg = rng.Value msg = msg & vbCr & rng.Address msg = msg & vbCr & rng.Interior.ColorIndex MsgBox (msg) End Sub
7行目の「rng2 = rng1」と8行目の「Set rng2 = rng1」とのどちらかをコメントアウトし、それぞれの動作を確認した。
Sheet1は以下のように、A1にaが、B1にbが入っている。
実験1:「Set rng2 = rng1」の場合
メッセージボックスは以下のものが順に表示され、シートはこのようになった:
5行目:Call MsgBoxRngDetail(rng1) | 6行目:Call MsgBoxRngDetail(rng2) |
「Set rng2 = rng1」を実行
9行目:Call MsgBoxRngDetail(rng1) | 10行目:Call MsgBoxRngDetail(rng2) |
評価
11行目のIf文の条件式がTrueのため | 14行目のIf文の条件式もTrueのため |
12行目:MsgBox ("rng1 is rng2") | 15行目:MsgBox ("rng1 = rng2") |
ということで、「Set rng2 = rng1」ではrng2の中身が丸々rng1と同じになったため、9行目と10行目の表示内容が同じになった。
rng2をrng1で置き換えたようなものだから、シートでは変化は起こらない。
実験2:「rng2 = rng1」の場合
メッセージボックスは以下のものが順に表示され、シートはこのようになった:
5行目:Call MsgBoxRngDetail(rng1) | 6行目:Call MsgBoxRngDetail(rng2) |
「rng2 = rng1」を実行
9行目:Call MsgBoxRngDetail(rng1) | 10行目:Call MsgBoxRngDetail(rng2) |
評価
11行目のIf文の条件式がFalseのため | 14行目のIf文の条件式もTrueのため |
15行目:MsgBox ("rng1 = rng2") | |
というわけで、一方で「rng2 = rng1」ではRangeオブジェクトのデフォルトプロパティであるValueの代入が行われただけであり、
つまり「rng2 = rng1」は「rng2.Value = rng1.Value」と等価であることを意味している。
なので、rng2は依然B1セルを指している一方で、B1の値がaに変わっているわけである。
当然「rng1 Is rng2」ではないが「rng1 = rng2」つまり「rng1.Value = rng2.Value」であるから、
評価のメッセージは後半しか表示されないわけだ。
環境:Microsoft Excel 2010/ Microsoft Visual Basic for Applications 7.0