【VBA】Offsetのバグか? 結合セルにはご注意を!
Excel VBAで久々に「Offset」を使ったら、見事にやらかしました。
昔から「Offsetは挙動が怪しい」と感じてて避けてたんですが、同じセル範囲で離れたデータを操作しようと使ったらハマりました。原因は結合セルです。これ、ほんと要注意です。
普通のセルならRange(“A1:A2").Offset(,1)でB列の2つのセルを取れるはずなのに、結合セルが混ざると結果がズレるんです。
今回は備忘録をかねて、Offsetメソッドでは何をするとダメなのか説明します。
結合セルからオフセットするのはダメ

例えば、こんな風にA1セルとA2セルがセル結合されていたとします。
Sub OffsetMergedRange()
Debug.Print Range("A1:A2").Offset(, 1).Address ' $B$1($B$1:$B$2とはならない)
End Subこの状態でA1とA2セルの範囲から、右に1セルずらしたいとします。
すると、Range(“A1:A2").Offset(, 1)と書くのですが、これは思った動作をしません。
B1:B2セルの範囲となって欲しいのですが、実際はB1セルだけになります。
これはバグではなく、Offsetメソッドの仕様みたいです。
(結合セルを選択した状態から右矢印キーを押すと1セルだけ選択される、という挙動と同じなのかな)
微妙な挙動だなぁ、とは思うのですが、少なくとも結合セルのあるシートでOffsetを使うのは避けた方が良さそうです。
Offsetの代わりに、Resizeメソッドを使いましょう。
Offsetほどではないですが、Resizeメソッドも結構少ない文字数できれいに書けます。
余談:シートに結合セルがあるか確認する方法
もし、Offsetを使うのなら前処理でシート内に結合セルがないか調べておくのが無難です。
結合セルがあったら、最初にエラーメッセージを出して止めてしまう、といった使い方。
Sub CheckMergedCells()
Dim rng As Range
' アクティブシート全体をループして結合セルを探す
For Each rng In ActiveSheet.UsedRange
If rng.MergeCells Then
MsgBox "結合セルがあります!"
Exit Sub
End If
Next
MsgBox "結合セルは見つかりませんでした。", vbInformation, "確認結果"
End Sub
結合セルの有無はMergeCellsを使えば簡単にできます。
シートのUsedRangeに対して、Forループで1セルずつ確認してしまえばアッという間に終わります。
