Rangeオブジェクトと引数のカッコの話
Sub CopySample1() Range("A1").Copy (Cells(1, 2)) Range("A2").Copy (Range("B2")) End Sub
このコード、どちらもCopyメソッドの引数Destinationを指定しています。違いと言えば、貼り付け対象のセル(Rangeオブジェクト)をCellsプロパティで指定しているか、Rangeプロパティで指定しているかです。
このコードですが、「Range("A2").Copy (Range("B2"))」がエラーになります。
しかし、次のコードの場合、どちらもエラーにはなりません。
Sub CopySample2() Range("A1").Copy Cells(1, 2) Range("A2").Copy Range("B2") End Sub
「CopySample1」プロシージャと「CopySample2」プロシージャの違いは、引数を「()」で囲んでいるかいないかです。
では、この「()」で囲んだことで何が起きているのか、次のコードで確認してみます。
Sub TypeNameTest() Debug.Print "Cells : " & TypeName((Cells(1, 1))), TypeName(Cells(1, 1)) Debug.Print "Range : " & TypeName((Range("A1"))), TypeName(Range("A1")) End Sub
TypeName関数は、引数に関する情報(主にデータ型)を返します。
実行結果は次のようになります。
Cells : Range Range
Range : Empty Range
TypeName関数の引数にCellsプロパティを使ったものとRangeプロパティを使ったものの2パターン。さらに、それぞれ引数そのものをカッコで囲んだものと囲まないものの2パターンです。
Cellsプロパティが両方とも「Range」を返しているのに対し、Rangeプロパティの方は、引数そのものをカッコで囲んだ方は「Empty」が返っています。
この「Empty」ですが、実はこのテストをする時にセルA1には何も入力されていません。何も入力されていないセルの値はEmptyなので、それが返っています。
念のため、セルA1に文字列を入力して、このコードを実行すると「String」が返りました。
ということは、「(Range("A1"))」と指定したときには、セルの値を評価している、ということになります。つまり「(Range("A1").Value)」ということですね。
となると、最初のコード(再掲します)で、「Range("A2").Copy (Range("B2"))」がエラーになったのも理解できます。
Sub CopySample1() Range("A1").Copy (Cells(1, 2)) Range("A2").Copy (Range("B2")) End Sub
「()」で囲んだことで、「Range("B2")」が、「Range("B2").Value」と解釈されたということです。となると、Copyメソッドの引数にはRangeオブジェクトを指定しなくてはなりませんから、エラーになるのも当然と言えます。
それに対して、「(Cells(1, 2))」の方は、「()」で囲んでもRangeオブジェクトを返していたので、エラーにはならなかった、ということです。