VBAでの処理速度や効率を考えると、ループの回数をできる限り少なくすることがとても重要です。
たとえば数千行あるデータを1行ずつループするマクロは、少し工夫するだけで数倍速くなります。この記事では、処理の無駄を減らし、ループ回数を最小限に抑えるための基本的な考え方と書き方を紹介します。
条件を見直すだけでループは減らせる
まずは、次のようなコードを見てみましょう。
Dim i As Long
For i = 2 To 1000
If Cells(i, 1).Value <> "" Then
Cells(i, 2).Value = "済"
End If
Next i
このコードは、A列にデータがある行に対してB列に「済」と書き込むものです。一見問題ないように見えますが、対象が1000行でも、A列にデータが入っているのが100行だけなら、残りの900回は無駄なチェックをしていることになります。
このようなときは、「データがある行だけ」を対象にすれば、無駄なループを減らせます。
Dim i As Long
Dim lastRow As Long
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lastRow
If Cells(i, 1).Value <> "" Then
Cells(i, 2).Value = "済"
End If
Next i
lastRow 変数を使って、A列の最終行を取得することで、余計なループ処理を回避できます。
条件に一致するセルだけを対象にする
さらに効率化を目指すなら、「条件を満たすセルだけ」を直接対象にするという方法もあります。
たとえば「A列に空白でないセルだけを一括で処理したい」といった場合には、次のような書き方が可能です。
Dim rng As Range
Dim c As Range
Set rng = Range("A2:A1000").SpecialCells(xlCellTypeConstants)
For Each c In rng
c.Offset(0, 1).Value = "済"
Next c
この方法では、ループ対象が「データが入っているセル」に限定されるため、ループ回数は最小限になります。
ここで使っている For Each は、特定の範囲内のセルなどを1つずつ取り出して処理する書き方です。For i = 1 To 100 のように数値を1つずつ増やすのではなく、実際に「存在している対象」だけを順番に処理できます。
この構文は、対象が明確なときに読みやすく、エラーも出にくいというメリットがあります。
配列を使って一括処理する
より高度な方法として、「配列」を使って一括処理するという手法があります。これは少し上級ですが、理解しておくと非常に便利です。
Dim data As Variant
Dim i As Long
data = Range("A2:A1000").Value
For i = 1 To UBound(data, 1)
If data(i, 1) <> "" Then
data(i, 1) = "済"
End If
Next i
Range("A2:A1000").Value = data
このように、まず対象のセル範囲を「配列」という一時的なデータ入れ物に取り込み、配列の中で全ての処理を済ませてから、まとめてシートに書き戻す形です。
ポイントは次の通りです。
Variant型の変数は、様々なデータを一時的に扱える柔軟な型です。- 配列に取り込んだデータは、行と列の「二次元の形」で管理されます(たとえば、data(1,1) は1行目1列目のセルに相当します)。
UBound(data, 1)は、配列の「行数」を調べています。
この方法の最大のメリットは、Excelシートとのやりとり(読み書き)を最小限にできることです。特に数千行以上ある場合は、処理速度が圧倒的に速くなります。
まとめ
ループはVBAでの基本処理ですが、漫然と使うと処理が遅くなったり無駄な繰り返しが発生したりします。ループ回数を減らすだけで、スピードも見やすさも大きく変わってきます。
lastRowを使って必要最小限の行だけ処理するSpecialCellsとFor Eachで対象セルを絞り込む- 配列に読み込んでから処理し、まとめて書き戻す
このような工夫を取り入れて、効率的なマクロを目指していきましょう。ちょっとした意識の差が、実務のスピード感に直結します。
