VBA

【VBA初級者必見:どっち使う?】RangeとCellsのメリット、デメリットそして使い分けについて

記事内に商品プロモーションを含む場合があります

このページでわかること

RangeとCellsのメリットデメリットの使い分け
どっちを使うべきかわかります。

覚えること
  1. A1セル表記
    Range:Range(“A1”)
    Cells:Cells(1,1)
  2. A1からB3までの表記
    Range:Range(“A1:B3”))
    Cells:Range(Cells(1,1),Cells(3,2))
  3. RangeよりCellsの方が速度は速い
  4. RangeとCellsの使い分け
    Range:位置を把握する必要がある処理。For文で処理しないもの。
    Cells:For文処理

こんにちは、hokkyokunです。
VBA使いなら毎日書いていると思われるRangeとCells。
これってどっち使ってますか?

私が優先すべきは

  • コード量
  • メンテナンス性
  • 開発のしやすさ

です。

もう少し噛み砕いて言うなら、
少ないコードでかけるか、
コードはすっきりしているか、
パッとどこのセルをあらわしているのか分かるかです。
Cells(1,25)がどこのセルを表すか、パッと分かる人って何人います?
僕なら左から順に数えちゃいます笑

具体的に見ていきましょう。

Range、Cellsの表記の仕方

先ず、Range、Cellsの表記の仕方についてまとめておきましょう。

単独のセル:【例】A1セルを表すとき

Range:Range(“A1”)
Cells:Cells(1,1)

複数の連続セル:【例】A1からB3までを表すとき

Range:Range(“A1:B3”))
Cells:Range(Cells(1,1),Cells(3,2))

複数の非連続セル:【例】A1とB3を表すとき

Range:Range(“A1 , B3”))
Cells:Union(Cells(1,1),Cells(3,2))

Rangeは位置がイメージしやすい、Cellsは数値だけで書ける

上記のRangeとCellsの表記方法でどういった印象をもたれたでしょうか?

私は

Rangeはどこのセルを指しているか分かりやすい
Cellsは文字列を使わなくていい→For文に入れるのが簡単

Rangeはひとめでどこのセルかわかりますよね。
例えばCells(1,32)ってどこかわかりますか?
僕は分かりません笑
ちなみにCells(1,32)はAF1のセルです。
Range(”AF1”)ならすぐ分かりますよね。

これってメンテナンスをする上では非常に大事な感覚だと思います。
位置を確認しなければいけないときはRangeを使うことをお勧めします!!

Cellsの良いところは数値だけで書けるところです。
具体的に見てみましょう。

例えば1行目から5行目までのセルの値を処理しなければいけないマクロを作るとき

Rangeバージョンは

Sub if文Rangeバージョン()
Dim i As Long
For i = 1 To 5
    Range("A" & i).Value = 1
Next i
End Sub

かけなくはないですが、美しくないですね。
一方、Cellsは

Sub if文Cellsバージョン()
Dim i As Long
For i = 1 To 5
    Cells(i, 1).Value = 1
Next i
End Sub

美しく、すっきりしていますね。
それだけでなく、列の移動(横の移動にもすぐ対応できます)

Sub if文Cells列バージョン()
Dim i As Long
For i = 1 To 5
    Cells(1, i).Value = 1
Next i
End Sub

最適解ではない気がしますが、無理やりRangeで列バージョンを書いてみました。

Sub if文Range列バージョン()
Dim Arrs As Variant
Dim arr As Variant

Arrs = Array("A", "B", "C", "D", "E")
For Each arr In Arrs
    Range(arr & 1).Value = 1
Next

End Sub

コード長いし、美しくないし。最初からCells使っとけって話ですね。

離れたセルの取得は若干Rangeがやりやすい

上記でも書きましたが、離れたセルの取得には
Rangeは「,」でつなげることでかけます。
一方CellsはUnionでつなげる必要があります。

複数のセル(非連続)
例えばA1とB3

Range:Range("A1 , B3"))
Cells:Union(Cells(1,1),Cells(3,2))

こちらはRangeの方がすっきりしますね。
ちなみにRange(“A1 , B3 , B5”)とつなげることで無限に増やすことが出来ます。
ただ、For文などでいくつ増やすか決まっていない場合はUnionを使ったほうがいいですね。

特殊な使い方

名前をつけたセル範囲はRangeで取得する

セルの範囲に名前をつけることができます。
名前を付けたい範囲を選択し、左上の名前ボックスに名前を入力します。

このセル範囲はCellsではとれないので、Rangeを使うことになります。

Sub 名前をつけたセル範囲()

Dim rng As Range

Set rng = Range("果物リスト")
MsgBox "名前を付けた範囲は" & rng.Address

End Sub

表内のセルの位置を取得するにはCells

表の範囲内で位置を取るときにはそこそこ使えます。

どういうことかというと、
まず、表のセル範囲を取得します。例えばRange(”A1:B5”)みたいな感じで。
このなかから左上から順に何番目のセルかを指定できます。
表の左上から2番目のセルはRange(“A1:B5”).Cells(2)みたいな感じです。
表の右下(=最後のセル)はRange(“A1:B5”).Cells(Range(“A1:B5”).Count)となります。
全部のセルはRange(“A1:B5”).CellsでOKです。

Sub 表内のセル位置()

Dim rng As Range

Set rng = Range("A1:B5")
MsgBox ("左から2番目のセルは" & rng.Cells(2).Address & _
        vbCrLf & "表の右下のセルは" & rng.Cells(rng.Count).Address & _
        vbCrLf & "全部のセルは" & rng.Cells.Address)

End Sub

このままだとかなり微妙ですが、例えば表内のセルを全検索するときとかはまあまあ使えます。

下記のプログラムは表内の空白の背景色を黄色にするマクロです。
空白セルを見つける方法はこれだけじゃないですが、それなりの処理は出来ると思います。

Sub 空白探知()
Dim Rng As Range
Dim r As Range

Set Rng = ActiveSheet.Range("A1:C4")
For Each r In Rng.Cells
    If r.Value = "" Then
        r.Interior.Color = RGB(255, 255, 0)
    End If
Next

End Sub

RangeとCellsどっちが早い?

みんな大好き速度系の実験です。
結論先に言います。

Cellsの方が早いです。

簡単なマクロを作りました。
A列の上から下まで一つずつセルに値を入力し、その入力を消していくってマクロです。

先ずはRangeを使ってみます。

Sub 速度Rangeバージョン()

Dim Start, Goal As Date
Dim i As Long

Start = Time
For i = 1 To Rows.Count
    Range("A" & i).Value = 1
Next i

For i = 1 To Rows.Count
    Range("A" & i).Value = ""
Next i
Sub 速度Cellsバージョン()

Dim Start, Goal As Date
Dim i As Long

Start = Time
For i = 1 To Rows.Count
    Cells(i, 1).Value = 1
Next i

For i = 1 To Rows.Count
    Cells(i, 1).Value = ""
Next i

Goal = Time
MsgBox ("時間:" & Format(Goal - Start, "hh:nn:ss"))

End Sub

CellsはRangeの8割程度の時間で処理できますね。

まとめ

Rangeのメリット、デメリット

Rangeのメリット

  • セルの位置を直感的に把握できる
  • 離れたセルを複数取得するのは若干手軽
  • 名前をつけたセル範囲を取得できる
  • Rangeのデメリット

  • 変数に入れにくい→For文でまわしにくい
  • 名前をつけたセル範囲を取得できる
  • Cellsのメリット、デメリット

    Cellsのメリット

  • 変数に入れやすく、For文で処理しやすい
  • 処理が若干Rangeより早い
  • 表内のセル取得しやすい
  • Cellsのデメリット

  • セル位置が分かりにくい→メンテナンス、開発がちょっとやりにくい
  • お勧めの使い方

    Range:位置を把握する必要がある処理。For文で処理しないもの。
    Cells:For文処理

    個人的には速度は余り気にしていません。
    確かにスピードは実感できるくらい変わる可能性はあります。

    でもそれよりも大事なことは
    コード量とメンテナンスです。

    視覚的に分かりやすく、少ないコードで書ける方を選ぶと良いと思います。

    ではでは。