RangeとCellsのメリットデメリットの使い分け
どっちを使うべきかわかります。
-
A1セル表記
Range:Range(“A1”)
Cells:Cells(1,1) -
A1からB3までの表記
Range:Range(“A1:B3”))
Cells:Range(Cells(1,1),Cells(3,2)) - RangeよりCellsの方が速度は速い
-
RangeとCellsの使い分け
Range:位置を把握する必要がある処理。For文で処理しないもの。
Cells:For文処理
こんにちは、hokkyokunです。
VBA使いなら毎日書いていると思われるRangeとCells。
これってどっち使ってますか?
私が優先すべきは
- コード量
- メンテナンス性
- 開発のしやすさ
です。
もう少し噛み砕いて言うなら、
少ないコードでかけるか、
コードはすっきりしているか、
パッとどこのセルをあらわしているのか分かるかです。
Cells(1,25)がどこのセルを表すか、パッと分かる人って何人います?
僕なら左から順に数えちゃいます笑
具体的に見ていきましょう。
Range、Cellsの表記の仕方
先ず、Range、Cellsの表記の仕方についてまとめておきましょう。
Range:Range(“A1”)
Cells:Cells(1,1)
Range:Range(“A1:B3”))
Cells:Range(Cells(1,1),Cells(3,2))
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のメリット、デメリット
Cellsのメリット、デメリット
お勧めの使い方
Range:位置を把握する必要がある処理。For文で処理しないもの。
Cells:For文処理
個人的には速度は余り気にしていません。
確かにスピードは実感できるくらい変わる可能性はあります。
でもそれよりも大事なことは
コード量とメンテナンスです。
視覚的に分かりやすく、少ないコードで書ける方を選ぶと良いと思います。
ではでは。