
Excelマクロを勉強している過程で、「Cells」と「Range」の使い分けに、迷う方も多いと思います。
みなさん、こんにちは。セルネッツ竹本です。
今回は、「CellsとRange使い分けの考え方」をテーマに、解説したいと思います。
結論から言うと、決まったセル番地を指すならRange、行や列を数値で動かすならCellsが向いています。
範囲を数値で決めたいときは、Range(Cells(1, 1), Cells(10, 3))のように組み合わせて使います。
この記事では、次のことがわかります。
- RangeとCellsの違いと、開発での使い分けの考え方
- Cellsで範囲を指定する方法と、Range型の変数の使い方
- 配列でまとめて読み書きして、処理を速くする方法
自作マクロの見直しに
書き方がばらばらのマクロ、整理しませんか
- 担当者ごとにRangeとCellsの書き方が混在
- 大量データの処理で応答なしになる
- 不具合の修正箇所をすぐに特定できない
そのお悩み、マクロのレビューと改修で解決できます。Excel専門のシステム開発会社『セルネッツ』なら、配列を使った高速化や記述ルールの統一に対応します。ログ出力も加え、直しやすく引き継ぎやすいマクロに整えます。
\Excel専門特化 × 低価格 × スピード対応/
全国対応・お見積もり無料
RangeとCellsの違い
どちらもセルを表すRangeオブジェクトを返しますが、場所の指定のしかたが違います。
| 比べる点 | Range | Cells |
| 書き方の例 | Range(“A1”) | Cells(1, 1) |
| 指定の順番 | 列(アルファベット)+行 | 行, 列(数値) |
| 範囲の指定 | Range(“A1:C10”) | 単独では1セル。Rangeと組み合わせて範囲にする |
| 繰り返し処理 | 行は “A” & i で回せるが、列は苦手 | 行も列も数値で回せる |
| 向いている場面 | 決まったセル番地・見出し・LOGの出力先 | ループ処理・位置が変わる範囲 |
.Valueを書く・書かないの考え方は、「.Valueを省略したときの動き」で解説しています。
(参考:Microsoft Learn「Range.Cells プロパティ」)
◆アルファベット列番号と数値の違いをどう考えるか
表現方法という面では、構文の違いがあり、行と列が逆転しています。
以下のように、単一セルに文字列を出力するような場合であれば、どちらを使った場合でも、速度も変わらず、見易さも変わらないので、「どちらでも良い」ように感じるかもしれません。
1.「Range」は、「列番号+行番号」
2.「Cells」は、「行番号,列番号」
Range("A1").Value = "商品CD"
Cells(1, 1).Value = "商品CD"
が、列をずらしながら、[先頭列] から [末尾列] へ向かって、繰り返し処理を行う場合はどうでしょう。
両者には、繰り返し処理で、数値カウンターを使えるかどうか、といった大きな違いがあります。
↓[Range] 数値カウンターを使えない (列の増分値を1として繰り返したいが出来ない)
Range("D2").Value = "4"
Range("E2").Value = "5"
Range("F2").Value = "6"
↓[Cells] 列番号をカウントアップできる
Cells(2, 4).Value = "4"
Cells(2, 5).Value = "5"
Cells(2, 6).Value = "6"
※コピーしてそのまま動くよう、コード内の引用符(“ ”)を半角の「”」に直しました。
※行だけを変えるなら、Rangeでも Range(“D” & i) のように数値を使えます。苦手なのは、列を数値で動かす処理です。
Cellsの場合は、行番号、列番号を数値で指定するため、プログラミング処理に欠かせない「数値カウンター」を使うことができます。
いっぽう、Rangeの場合は、アルファベットに変換する必要があるので、列が変化してゆくようなケースでは、アルファベット変換も不要な分、Cellsのほうが可読性が高まります。
列を数値で回す実践例は、「列の削除を繰り返すならCellsと数値でループする方法」で紹介しています。
【結論】
プログラム開発の場合は、
1.「繰り返し処理をするかどうか」(カウンターを活用できるかどうか)
2.「高速処理を必要とするかどうか」(
セルを1つずつ読み書きすると遅く、配列でまとめて読み書きすると速くなります。個数が少ないなら大差はないが大量だと応答なしの可能性も)
を一つの判断基準とすることをおすすめします。
【実際にセル番地を固定で出力しているVBAツール例】
ファイル入出力の情報をLOG履歴として、「単一の固定セル番地」へ出力しているRange("M10") = P_入File名 と記述するが、あえて、Cells(10, 13) = P_入File名と記述しない!

上図のように、処理実行後の実測やファイル名を結果LOGとしてシート固定セル番地に出力するケースは、「Range」とする、そんなガイドラインがあると不具合があった際の修正箇所の特定に役立つことが多いです。
シート内のデータを配列で高速処理する場合は、配列の中を行・列の番号で扱うため、Cellsと同じ考え方になります。
このため、「固定セル番地」を使う場合のみ「Range」と考えましょう。
すると、繰り返し処理を行いやすい処理が「Cells」といった考え方が、切り分けのガイドラインとしてわかりやすいかもしれません。
CellsとRangeを組み合わせて範囲を指定する
Rangeの中に、始まりと終わりのCellsを2つ書くと、数値で範囲を指定できます。
Sub M_範囲を指定する()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
'A1〜C10(1〜10行目、1〜3列目)に色を付ける
ws.Range(ws.Cells(1, 1), ws.Cells(10, 3)).Interior.Color = vbYellow
'Withを使うと短く書ける(2〜10行目の値を消す)
With ws
.Range(.Cells(2, 1), .Cells(10, 3)).ClearContents
End With
End Sub
中のCellsにもシートを付けるのがポイントです。
付け忘れると、別のシートを開いているときにエラーになります(詳しくは後述の注意点で)。
選んだ範囲のアドレスを取ったり、値を入れたりする方法は、「選択範囲のアドレスを取得して値をセットする方法」で解説しています。
Range型の変数に入れて使う
何度も使う範囲は、Range型の変数にSetで入れておくと、コードが短く読みやすくなります。
Dim ws As Worksheet
Dim rng As Range
Set ws = ThisWorkbook.Worksheets("Sheet1")
Set rng = ws.Range("A1:C10")
rng.Cells(1, 1).Value = "見出し" '範囲の1行1列目(A1)
rng.Offset(1, 0).Resize(9, 3).Interior.Color = vbYellow 'A2:C10
- 変数に入れるときは、Setが必要です。忘れると実行時エラーになります。
- rng.Cells(1, 1)は、シートのA1ではなく「範囲の左上から数えた位置」です。
- Offsetは範囲をずらし、Resizeは範囲の大きさを変えます。
(参考:Microsoft Learn「Range オブジェクト」)
配列でまとめて読み書きして高速化する
大量のセルを処理するときは、範囲の値を配列に読み込み、計算してからまとめて書き戻します。
Sub M_配列でまとめて処理()
Dim ws As Worksheet
Dim vntData As Variant
Dim lngLast As Long
Dim i As Long
Set ws = ThisWorkbook.Worksheets("Sheet1")
lngLast = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row 'A列の最終行
vntData = ws.Range(ws.Cells(2, 1), ws.Cells(lngLast, 3)).Value 'まとめて読む
For i = 1 To UBound(vntData, 1)
vntData(i, 3) = vntData(i, 1) * vntData(i, 2) '3列目 = 1列目 × 2列目
Next i
ws.Range(ws.Cells(2, 1), ws.Cells(lngLast, 3)).Value = vntData 'まとめて書く
End Sub
読み込んだ配列は、vntData(行, 列)の形で、1から始まる番号で扱います。
セルを1つずつ読み書きするより、シートとのやり取りが2回で済むため速くなります。
最終行の求め方は、「シート内データの最下行を求める2つの方法」で解説しています。
RangeとCellsの注意点
エラーの多くは、シートの指定漏れと、行・列の順番の取り違えです。
- ws.Range(Cells(1, 1), Cells(10, 3)) のように中のCellsにシートが無いと、別のシートを開いているときに実行時エラー1004になります。
- Cellsは「行, 列」、Rangeは「列+行」の順です。Cells(1, 3)はC1で、A3ではありません。
- Webページからコードをコピーすると、引用符が全角の“ ”になり、エラーになることがあります。
- シート名で指定していると、シート名を変えただけでマクロが止まります。
シート名の変更に強くする方法は、「ワークシートをID管理するテクニック」で紹介しています。
よくある質問
Q. Cellsで列をアルファベットで指定できますか?
できます。Cells(1, “D”) と書くと、D1を指します。
ただし、列を数値で回すメリットはなくなります。
Q. RangeとCellsで処理速度は違いますか?
1つのセルを扱うだけなら、ほとんど変わりません。
遅くなる原因は、どちらを使うかではなく、セルを1つずつ読み書きすることです。
大量のデータは、配列でまとめて扱います。
Q. Cellsだけを書くと、どこを指しますか?
括弧を付けずにCellsと書くと、シートのすべてのセルを指します。
たとえば ws.Cells.ClearContents は、シート全体の値を消します。
まとめ
- 決まったセル番地はRange、行・列を数値で動かすならCells
- 範囲を数値で決めるなら Range(Cells(), Cells()) と組み合わせ、中のCellsにもシートを付ける
- 何度も使う範囲はRange型の変数にSetで入れる
- 大量データは配列でまとめて読み書きすると速い
今回のテーマは、「CellsとRange使い分けの考え方」について、解説を行いました。
本記事が、Excel実務の効率化において、お役に立てれば幸いです。
相見積もり歓迎
レビューだけ、改修だけのご依頼もどうぞ
- 基本料金50,000円+時間単価で見積もり
- 開発の時間単価は10,000円(税別)
- 60分の無料相談でセカンド・オピニオンも
作り直しを前提にせず、今のマクロを活かす改修からご提案します。料金は基本料金50,000円+時間単価(開発10,000円/時・税別)が目安です。相見積もりも歓迎です。セカンド・オピニオンも60分無料で承ります。
\Excel専門特化 × 低価格 × スピード対応/
全国対応・お見積もり無料
Excel業務改善事例ショート動画
文章だけでは伝わりにくい改善事例を、ショート動画でご覧いただけます。
◆よくある質問 ◆Excel業務改善の実例 ◆VBA・マクロ活用事例
