はじめに
ExcelVBAでセルを操作するとき、「今いるセルの1つ下」「3列右」のように、基準となるセルから相対的な位置を指定したい場面がよくあります。そんなときに便利なのがOffsetプロパティです。
Offsetを使いこなせると、ループ処理で1行ずつずらしながらデータを転記したり、見出し行を除いて処理したりと、実務コードの幅がぐっと広がります。この記事では、Offsetプロパティの基本的な書き方から、実務でよく使うパターン、注意すべきエラーまで分かりやすく解説します。
Offsetプロパティの基本構文
基本の書き方
Offsetプロパティは、基準となるセルから「行方向」「列方向」にどれだけ離れたセルを取得するかを指定します。
Range.Offset(RowOffset, ColumnOffset)
RowOffset: 行方向の移動量(下がプラス、上がマイナス)ColumnOffset: 列方向の移動量(右がプラス、左がマイナス)
例えば、セルA1から見て「1つ下」のセルを取得したい場合は次のように書きます。
Sub OffsetSample1()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
' A1の1つ下(A2)に値を入力する
ws.Range("A1").Offset(1, 0).Value = "1つ下のセルです"
End Sub
Offset(1, 0)の1番目の引数が「行」、2番目の引数が「列」です。両方とも省略はできませんが、0を指定すれば「その方向には動かさない」という意味になります。
負の値を指定して逆方向に移動する
行や列の移動量にはマイナスの値も指定できます。上や左のセルを参照したいときに使います。
Sub OffsetSample2()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
' B5から見て1つ上、1つ左のセル(A4)を取得
MsgBox ws.Range("B5").Offset(-1, -1).Address
End Sub
このように、Offsetは基準セルを起点とした「相対参照」であることがポイントです。
Offsetの実務活用例
ループ処理で連続入力する
Offsetが最も活躍するのは、繰り返し処理でセルの位置を1つずつずらしていくケースです。次の例は、A列の値をB列にコピーしながら、C列に連番を振っていくマクロです。
Sub OffsetLoopSample()
Dim ws As Worksheet
Dim baseCell As Range
Dim i As Long
Dim lastRow As Long
Set ws = ThisWorkbook.Worksheets("Sheet1")
Set baseCell = ws.Range("A1")
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
For i = 0 To lastRow - 1
' A列の値をB列にコピー
baseCell.Offset(i, 1).Value = baseCell.Offset(i, 0).Value
' C列に連番を入力
baseCell.Offset(i, 2).Value = i + 1
Next i
End Sub
基準セルbaseCellを固定しておき、ループ変数iを行方向のオフセットとして使うことで、常に「基準セルから何行目か」だけを考えればよくなり、コードがすっきりします。
見出し行を除いて処理する
表の1行目が見出しの場合、データ部分だけをループしたいことがよくあります。Offsetを使えば、見出し行を除いた範囲を簡単に指定できます。
Sub SkipHeaderSample()
Dim ws As Worksheet
Dim dataRange As Range
Dim lastRow As Long
Set ws = ThisWorkbook.Worksheets("Sheet1")
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
' A1(見出し)を除いた、A2から最終行までを取得
Set dataRange = ws.Range("A1", ws.Cells(lastRow, 1)).Offset(1, 0).Resize(lastRow - 1, 1)
Dim c As Range
For Each c In dataRange
Debug.Print c.Value
Next c
End Sub
Offset(1, 0)で範囲全体を1行下にずらし、Resizeで範囲のサイズを調整することで、見出し行を除いたデータ範囲を作れます。
CellsとOffsetの使い分け
セルを相対位置で指定する方法としてはCellsプロパティもよく使われますが、役割が少し異なります。
Cells(行, 列): シート上の絶対位置を行番号・列番号で指定するRange.Offset(行, 列): 特定のセル(起点)からの相対位置を指定する
「表の中で基準セルから何マス移動するか」を表現したいときはOffset、「シート全体の中で座標を直接指定したい」ときはCells、と使い分けるとコードの意図が伝わりやすくなります。
注意点・よくあるエラー
シートの端を超えるとエラーになる
Offsetで指定した移動量が、シートの行数・列数の範囲を超えてしまうと、実行時エラーが発生します。特にマイナス方向へのオフセットで、1行目や1列目からさらに上・左に移動しようとするとエラーになるので注意してください。
Sub OffsetErrorSample()
' A1から見て1つ上のセルは存在しないためエラーになる
Range("A1").Offset(-1, 0).Select
End Sub
ループ処理でOffsetを使う場合は、移動量が想定範囲に収まっているか、lastRowやlastColumnの計算が正しいかを事前に確認しましょう。
Offsetは相対参照であることに注意
Offsetはあくまで「基準セルからの相対位置」を返すプロパティです。基準セルの参照がずれると、Offsetで取得されるセルもずれてしまいます。ループの中で基準セル自体を書き換えてしまわないよう、変数の使い方には気をつけてください。
まとめ
この記事では、Offsetプロパティの基本構文から、ループ処理や見出し行を除く処理といった実務での活用例、そして注意すべきエラーまでを解説しました。
Offset(行, 列)で基準セルからの相対位置のセルを取得できる- 移動量にはマイナスの値も指定でき、上下左右どちらにも移動可能
- ループ処理と組み合わせることで、データ転記や連番入力のコードがシンプルになる
Resizeと組み合わせると、見出し行を除いた範囲の取得なども簡単にできる- シートの端を超えるオフセットはエラーになるので、移動量の範囲チェックを忘れない
Offsetは非常に基本的なプロパティですが、使いこなすことでループ処理のコードが格段に読みやすくなります。ぜひ実務のマクロに取り入れてみてください。

コメント