このサイトの記事内では「アフィリエイト広告」などの広告を掲載している場合があります。
消費者庁が問題としている「誇大な宣伝や表現」とならないよう配慮しコンテンツを制作しておりますのでご安心ください。
問題のある表現が見つかりましたらお問い合わせよりご一報いただけますと幸いです。

【VBA】Offsetのバグか? 結合セルにはご注意を!

Excel VBAで久々に「Offset」を使ったら、見事にやらかしました。

昔から「Offsetは挙動が怪しい」と感じてて避けてたんですが、同じセル範囲で離れたデータを操作しようと使ったらハマりました。原因は結合セルです。これ、ほんと要注意です。

普通のセルならRange(“A1:A2").Offset(,1)でB列の2つのセルを取れるはずなのに、結合セルが混ざると結果がズレるんです。

今回は備忘録をかねて、Offsetメソッドでは何をするとダメなのか説明します。

VBAが難しいと感じたら
ココナラにてVBAの作成依頼を受け付けています。
ご依頼・ご相談はこちらから

結合セルからオフセットするのはダメ

例えば、こんな風に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セルずつ確認してしまえばアッという間に終わります。

《VBA上級者になりたい人へ》
VBA上級者を目指したい人にはパーフェクトExcel VBA一択です。
この本を読み切れば間違いなくVBA上級者になれます。

VBAが難しいと感じたら
ココナラにてVBAの作成依頼を受け付けています。
ご依頼・ご相談はこちらから

VBA

Posted by やろまい