Excel VBA | 「基準セルからの相対位置」を指定する(Offset プロパティ)

VBA
スポンサーリンク

Offset(オフセット)って何?

Offset は「ある基準セルから、行・列を相対的にずらした場所のセル」を指し示すためのプロパティです。
イメージ:基準セルが 出発点(0,0)Offset(1,2) は「下に1、右に2」移動した場所を指します。

  • Offset(RowOffset, ColumnOffset)
    • RowOffset:行方向のずらし(正=下へ、負=上へ、0=同じ行)
    • ColumnOffset:列方向のずらし(正=右へ、負=左へ、0=同じ列)
  • 省略可:Offset(ColumnOffset:=2) のように名前付き引数で列だけ指定できます。

基本例(まずはこれを試してみて)

Sub Example1_BasicOffset()
    ' 基準:セル C3
    Dim r As Range
    Set r = Range("C3").Offset(1, 2)  ' C3 から 1行下、2列右 → E4
    r.Interior.ColorIndex = 6         ' 背景色を変更(見やすくするため)
End Sub
VB

解説:Range("C3").Offset(1,2)E4 を返すので、そのセルの色を変えます。


使い方パターン(よく使う場面ごとに例題)

1) 「隣のセル」に値を書き込む

右隣に計算結果を入れたいとき:

Sub Example2_WriteRight()
    Dim base As Range
    Set base = Range("B2")
    base.Offset(0, 1).Value = base.Value * 2 ' B2 の右隣(C2)に B2*2 を書く
End Sub
VB

2) 負のオフセット(上や左に行く)

Sub Example3_NegativeOffset()
    Range("D5").Offset(-2, -1).Value = "ここはB3" ' D5 から上2行・左1列 → B3
End Sub
VB

3) ループで「横にずらしながら」処理する(For)

見出し行の右に順に値を入れる例:

Sub Example4_LoopOffset()
    Dim startCell As Range
    Set startCell = Range("A1") ' A1 をスタート
    Dim i As Integer
    For i = 0 To 4
        startCell.Offset(0, i).Value = "項目" & (i + 1)
    Next i
End Sub
VB

4) 表の「隣列を合計して書く」実務的な例

各行の B 列〜D 列の合計を E 列へ:

Sub Example5_RowSumToRight()
    Dim r As Range
    Dim lastRow As Long
    lastRow = Cells(Rows.Count, "B").End(xlUp).Row ' B列の最終行
    For Each r In Range("B2:B" & lastRow)
        r.Offset(0, 3).Value = WorksheetFunction.Sum(r, r.Offset(0, 1), r.Offset(0, 2))
        ' r = B列、r.Offset(0,1)=C列、r.Offset(0,2)=D列、r.Offset(0,3)=E列
    Next r
End Sub
VB

5) 範囲ごとずらしてコピーする(Resize と併用)

2×3 のブロックを 3列右にコピー:

Sub Example6_CopyBlockWithOffset()
    Dim src As Range
    Set src = Range("A1").Resize(2, 3)   ' A1 から 2行×3列 のブロック
    src.Copy Destination:=src.Offset(0, 3) ' 右に3列ずらして貼る
End Sub
VB

Resize は範囲サイズを変えるメソッドで、Offset と組むと便利です。


エラー回避(端に行ってしまう問題)

Worksheet の端(最上行/最左列/最下行/最右列)近くで大きくオフセットすると存在しないセルを参照してエラーになります。安全に使う方法:

Function IsOffsetValid(base As Range, rOffset As Long, cOffset As Long) As Boolean
    Dim newRow As Long, newCol As Long
    newRow = base.Row + rOffset
    newCol = base.Column + cOffset
    If newRow < 1 Or newCol < 1 Then
        IsOffsetValid = False
        Exit Function
    End If
    If newRow > base.Worksheet.Rows.Count Or newCol > base.Worksheet.Columns.Count Then
        IsOffsetValid = False
        Exit Function
    End If
    IsOffsetValid = True
End Function

Sub Example7_SafeOffset()
    Dim b As Range
    Set b = Range("A1")
    If IsOffsetValid(b, -1, 0) Then
        b.Offset(-1, 0).Value = "上へ"
    Else
        MsgBox "上に移動できません(シート端)"
    End If
End Sub
VB

よくある質問(Q&A 形式)

Q
OffsetCells はどう使い分ける?
A

Offset は「相対移動」に強い。Cells(row, col) は「絶対位置を数値で指定」するときに便利(例えば Cells(i, j) をループで使う)。両方併用すると柔軟です:Cells(1,1).Offset(2,3) も可能。

Q
Offset は範囲にも使える?
A

使えます。Range("A1:B2").Offset(1,1) はそのブロックを下1・右1移動したブロックを返します。

Q
Offset の戻り値は Range ?
A

はい。Range オブジェクトなので .Value, .Interior, .Copy などがそのまま使えます。


練習問題

  1. シート A1 を基準に、斜め下に 5 個のセル(A1, B2, C3, D4, E5)に順に 1〜5 を書くマクロを作ってみる。
  2. B2:B10 の右隣の列に、各行の B 列の 2 倍を書き込むマクロを作る。
  3. 表の最終行を自動で検出して、最終行の右隣に「合計」と書くマクロを作る(Offset を使う)。

解答と解説

練習問題 1

A1 を基準に、斜め下に 5 個のセル(A1 → B2 → C3 → D4 → E5)へ 1〜5 を書く

解答コード(初心者向けに超シンプル)

Sub Answer1_DiagonalNumbers()
    Dim startCell As Range
    Set startCell = Range("A1")

    Dim i As Long
    For i = 0 To 4
        startCell.Offset(i, i).Value = i + 1
        ' i=0 → A1
        ' i=1 → B2
        ' i=2 → C3 …というふうに斜めに進む
    Next i
End Sub
VB

解説

  • Offset(i,i) なので、行も列も同じ分だけ下へ右へ動く→斜めになる
  • ループが 5 回まわるので 1〜5 が順に斜めに入力される

練習問題 2

B2:B10 の右隣(C 列)に、B列の2倍を書き込む

解答コード

Sub Answer2_MultiplyRight()
    Dim r As Range
    For Each r In Range("B2:B10")
        r.Offset(0, 1).Value = r.Value * 2
        ' Offset(0,1) →右隣の列(C列)
    Next r
End Sub
VB

解説

  • For Each r In Range("B2:B10") で B2〜B10 を順に取り出す
  • r.Offset(0,1) は右隣(C列)
  • r.Value * 2 を書き込むだけ
  • ループしながら横に書くときは Offset が最強

練習問題 3

表の最終行を自動で検出し、最終行の右隣に「合計」と書く(Offset を使う)

(※ B 列にデータが入っている表を想定)

解答コード

Sub Answer3_WriteTotal()
    Dim lastRow As Long
    Dim targetCell As Range

    ' B列の最終行を自動取得
    lastRow = Cells(Rows.Count, "B").End(xlUp).Row

    ' B列の最終行のセルを基準とする
    Set targetCell = Cells(lastRow, "B")

    ' 右隣(ColumnOffset:=1)に「合計」を書く
    targetCell.Offset(0, 1).Value = "合計"
End Sub
VB

解説

  • Cells(Rows.Count, "B").End(xlUp).Row
    → B列の下端から上に向かってデータを探し、最後の行番号を取る
  • その行の B 列セルを targetCell とする
  • targetCell.Offset(0,1) → 右隣(C列)
  • そこへ "合計" と書き込む

まとめ(初心者向けワンポイント)

  • Offset = 「基準から何行・何列ずらすか」を指定する方法。直感的でループ処理で非常に便利。
  • シート端のチェックを忘れないこと。大きくずらすとエラーになる。
  • Resize と組むとブロック操作が簡単になる。
  • 実際に小さなマクロを何回も試すと速く覚えられます。

VBA
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました