\ お問い合わせはこちら /

【VBA】RangeとCellsを活用してセル操作をする

Excel VBAのセル操作は、次の二つで行います。

  • Range()
  • Cells()

この二つを理解すれば、セルの値の書き換え、取得、削除、背景色の変更…などなど。

たくさんのことができるようになります。

基本の文法からちょっと応用的な高速化のテクニックまで、解説していきます。

【基本】RangeオブジェクトとCellsオブジェクトを理解しよう

セル操作をするためには、Range, Cellsの理解が不可欠です。

最後にはそれぞれを組み合わせたテクニックもご紹介します。

1. Rangeオブジェクト

Range は「セル範囲」を表すオブジェクトです。

VB
' A1セルの値をHelloに置き換える
Range("A1").Value = "Hello"

' B2からC5セルまでを全て100という値に置き換える
Range("B2:C5").Value = 100

飛び地のセルを選択したい場合にはRange("A1,A3,A5")のような指定もできます。

ただし、この方法はループをする時には速度が遅くなるので非推奨です。

2. Cellsオブジェクト

Cells は「行番号・列番号」でセルを指定します。

VB
' A1セルをHelloに置き換える
Cells(1, 1).Value = "Hello"

' C2セルを100に置き換える
Cells(2, 3).Value = 100

Rangeと違ってセルの番地を数値で扱うので、ループ処理や動的範囲指定との相性が良いです。

多くのプログラミング言語は0スタートですが、セル番地の指定は1からスタートします。
普段からプログラム組んでいる方は、ちょっと混乱する人もいるかも。

3. Range × Cells の組み合わせ

開始セルと終了セルを変数で動的に変更したい場合には、RangeCellsを組み合わせます。

これは実務でもかなり多用するテクニックです。

VB
Range(Cells(1, 1), Cells(5, 3)).Value = "OK"

必ず親ワークシートを明示しておくこと。

VB
With Worksheets("データ")
    .Range(.Cells(1, 1), .Cells(5, 3)).Value = "OK"
End With

どのシートかを指定しないとアクティブシートとみなされます。
事故のもとなので、上記のようにWithとして指定することが推奨です。

【応用】高速化テクニック2選

扱うセルの数が増えてくると、処理速度の遅さが気になってくるものです。

ここでは処理を高速化するためのテクニックを2つご紹介します。

1. 配列でまとめて入出力

1セルずつ操作すると極端に遅くなるので、複数セルをまとめて処理する方法です。

次のように配列を使えば、1回のアクセスで完結するので段違いに高速化できます。

VB
Dim data As Variant
Dim ws As Worksheet

Set ws = Worksheets("データ")

' 取得
data = ws.Range("A1:C1000").Value

' 配列内で計算しておく
Dim i As Long
For i = 1 To UBound(data)
    data(i, 3) = data(i, 1) + data(i, 2)
Next i

' 計算結果を取得したセルに戻す
ws.Range("A1:C1000").Value = data

12行目のロジックを1セルずつ計算することも可能ですが、処理速度はかなり遅いです。

そのため、11行目から13行目でメモリ内で先に計算してしまい、セル操作は16行目の1回だけとすることで高速化しています。

2. 画面更新・計算を抑制

大量処理前後で設定を切り替える方法です。

VB
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual

' 大量処理…

Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True

大量処理が終わったら、設定を元に戻すことは忘れずに。

【具体例】動的最終行・最終列取得と範囲操作

ここまでご紹介してきた内容を具体例に落とし込んでみました。

VB
Sub ProcessData()
    Dim ws As Worksheet
    Dim lastRow As Long, lastCol As Long
    Dim rng As Range

    Set ws = Worksheets("売上")

    ' 最終行・列
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
    lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column

    ' 範囲指定して一括処理
    Set rng = ws.Range(ws.Cells(1, 1), ws.Cells(lastRow, lastCol))
    ' 行列を入れ替えて貼り付け
    rng.Value = Application.WorksheetFunction.Transpose(rng.Value)
End Sub

まとめ

本記事の内容をまとめます。

  • Rangeは名前付き範囲やA1形式での多セル処理に強い
  • Cellsは番号指定でループや動的構築に強い
  • 事故を防ぐため、シート指定は必須
  • 大量データを扱う場合は、高速化のため配列の利用を検討

本ブログでは、このほかにもVBAに関する記事を執筆しています。

https://tabigrammer.com/tag/vba

ぜひ業務効率化のヒントとしてお役立てください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

はじめまして。旅行をこよなく愛するITエンジニアのNommyです。
これまでUberEatsの配達員、金融業界、ミステリーショッパーなど色々なお仕事を経験してきました。
本ブログでは僕が経験してきたことなどを執筆していきます。

コメント

コメントする

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)