ExcelのVBAにて欠かせない、セルの参照方法です。
結論
例えばこのような表で、セル「B3」を参照したい場合ですが、方法は2通りあります。

方法1:Rangeを使用
Range(“B3”)
方法2:Cellsを使用
Cells(3, 2)
解説
- Rangeの場合は、「列の名前(A、B、C、・・・)」+「行番号」 を指定します。
関数で使うような、見慣れた形式になっているかと思います。 - Cellsの場合は、「行番号」+「列番号」 を指定します。
Rangeと違って、行番号が先になることと、列の名前を数字で表すことに注意です。
上記のように、セルの位置を固定で指定する場合は、どちらでも構いません。好みの問題かと思います。
では、どう使い分ければ良いかというと、変数を使って行番号や列番号を変えたいときに、違いが出ます。
列に対して変数を使いたい場合はCells一択です。
まず、やり方を書くと、このようになります。
■行に対して変数(Idx)を使う場合
Cells(Idx,1) または Range(“A” & Idx)
■列に対して変数(Idx)を使う場合
Cells(1,Idx)
Rangeの場合は、列の名前を”A”のように文字で表すため、変数で列を変化させることが出来ません。
Rangeについては、私の主観も交えた補足がございますが、長くなるので、当記事の末尾に記載しました。
例:行に対して変数を使う場合
簡単なサンプルとして、先ほどの表で、「平成生まれ(生年月日>1989/1/7)の場合、D列に”平成生まれ”と表示する」場合、こんな感じになります。
(これぐらいなら関数で出来ますが、説明用の簡単なサンプルということで・・・)
Cellsを使用
Sub test()
Dim Idx1 As Integer
For Idx1 = 2 To 5
If Sheets("Sheet1").Cells(Idx1, 3) > #1/7/1989# Then
Sheets("Sheet1").Cells(Idx1, 4) = "平成生まれ"
End If
Next
End Sub
補足をします。
・ 行番号をループカウンターIdx1として、For文でループさせています。
・ 「C列」は「左から3番目の列」ということで、Cells(Idx1, 3)
「D列」は「左から4番目の列」ということで、Cells(Idx1, 4)
となります。
・ 日付を扱いたい場合、#1/7/1989# のように、##で囲んで下さい。
なお、VBAのエディタ上で #1989/1/7# のように入力すると、自動的に #1/7/1989# のように変換されます。
・ セルを扱う場合は、上記のSheets(“Sheet1”)のように、シート名を必ず指定するクセをつけて下さい。
複数のシートを扱うことになった場合に、正しく動かなくなります。
Rangeを使用
Sub test2()
Dim Idx1 As Integer
For Idx1 = 2 To 5
If Sheets("Sheet1").Range("C" & Idx1) > #1/7/1989# Then
Sheets("Sheet1").Range("D" & Idx1) = "平成生まれ"
End If
Next
End Sub
今度はRangeを使用した例です。
違いは、Range(“C” & Idx1)の部分ですね。
セル「C2」~「C5」をループさせるという意味で、列の名前 ”C” をダブルクォーテーション「”」で括って、行番号Idx1を「&」で繋げればOKです。
”C”をダブルクォーテーション「”」で括らないと、「C」が変数として扱われてしまうので、気を付けてください。
実行結果

無事、D列に”平成生まれ”が表示されました。
例:列に対して変数を使う場合
簡単なサンプルとして、「1行目の入力値を順に表示させる」という場合、こんな感じになります。
(またしても全く実用的でないプログラムですが、説明用の簡単なサンプルということで・・・)
Sub test3()
Dim Idx1 As Integer
For Idx1 = 1 To 3
MsgBox Sheets("Sheet1").Cells(1, Idx1)
Next
End Sub
今度は、行番号が「1」で固定で、列番号をループカウンター「Idx1」として、ループさせます。
実行結果

[OK]を押すと、1行目の値が順番にメッセージボックスに表示されます。
Rangeについての補足
行に対して変数を使う場合
この記事を書くにあたり色々と調べたところ、上記のように「Range(“A” & Idx)」といった書き方は好ましくないという情報が、複数ありました。
理由としては、以下の通りです。
・Cellsを使えば行・列ともに変数を使えるので、あえてRangeを使う必然性が無い。
・強引な記述方法に思える
・性能がやや劣る
しかし、あくまで個人的な主観ですが、私としてはどちらでも良いと思っています。
Rangeのほうが、関数で使うような見慣れた形式に思えますし、性能をシビアに求められるような場合は、セル範囲をまとめて配列に格納して、配列を操作するという、有識者には割と知られたテクニックがあります。
(このテクニックは、別の機会に述べようと思います。)
列に対して変数を使う場合
Rangeの場合でも、文字コードを使ったり、列の名前を格納した配列を別に用意したりすれば、出来ないことはありません。
しかし、手間がかかるうえに、コードが読みづらくなるため、そこまでする必然的は無いと思います。
コメント