HOME > 即効テクニック > Excel VBA > セル操作関連のテクニック > アクティブセルの位置を特定する

即効テクニック

セル操作関連のテクニック

アクティブセルの位置を特定する

(Excel 97/2000/2002/2003/2007)

マクロを実行するとき、アクティブセルや選択範囲がどの位置にあるかを知ることは重要です。 たとえば次のコードは、アクティブセルが属するリスト全体に格子の罫線を引きますが、アクティブセルがリストの外に置かれた状態で実行すると失敗します。

Sub Sample1()
    ActiveCell.CurrentRegion.Borders.LineStyle = True
End Sub
このマクロは「アクティブセルがリスト内にあるはずだ」という前提で作成されていますが、不特定多数のユーザーに提供するマクロでは、こうしたプログラマの「勝手な思いこみ」が予期せぬバグを産む原因になります。 アクティブセルの位置を知るにはいくつかの方法があります。 最も簡単な方法の一つはアクティブセルのアドレスを調べることです。 セルのアドレスはAddressプロパティで取得できますが、普通に指定すると「$A$1」のように絶対参照形式が返ります。 相対参照形式のアドレスを取得したい場合はAddressプロパティの引数を指定します。
Sub Sample2()
    MsgBox ActiveCell.Address(False, False)
End Sub
また、Addressプロパティの引数ExternalにTrueを指定することで「[Book1]Sheet1!$A$1」のようにブック名やシート名を取得することも可能です。
Sub Sample3()
    MsgBox ActiveCell.Address(External:=True)
End Sub
アクティブセルが任意のセル範囲内に置かれているかどうかは、アクティブセルの行と列を調べることで判定できます。 次のコードは、アクティブセルが1〜5行目かつA〜C列に置かれているかどうかを判定します。
Sub Sample4()
    With ActiveCell
        If 1 <= .Row And .Row <= 5 Then
            If 1 <= .Column And .Column <= 3 Then
                MsgBox "正しい範囲です"
            End If
        End If
    End With
End Sub
このように、RowプロパティやColumnプロパティを使ってアクティブセルの位置を特定することができますが、実はもっと簡単な方法があります。 ApplicationオブジェクトのIntersectメソッドは、引数に指定した複数のセル範囲が共有するセル範囲を返します。 このIntersectメソッドを使うことで、アクティブセルが特定のセル範囲内に存在するかどうかを調べることができます。 次のコードは、アクティブセルがセル範囲A1:C5内にあるかどうかを判定します。
Sub Sample5()
    Dim rc
    Set rc = Application.Intersect(ActiveCell, Range("A1:C5"))
    If rc Is Nothing Then
        MsgBox "A1:C5の範囲外です"
    Else
        MsgBox "A1:C5内に置かれています"
    End If
End Sub
Intersectメソッドは、共有するセル範囲が存在する場合はそのRangeオブジェクトを返し、存在しない場合はNothingを返します。 上記のSample5では、共有するセル範囲の位置が重要ではないので、返り値がNothingかどうかを判定しています。 ワークシートのSelectionChangeイベントと併用することで、アクティブセルの移動可能範囲を制限することも可能です。 次のコードは、アクティブセルがセル範囲A1:C5の外に移動しようとすると、注意のメッセージを表示して、アクティブセルをセル範囲A1:C5内に戻します。
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Dim c As Long, r As Long
    If Application.Intersect(Target, Range("A1:C5")) Is Nothing Then
        MsgBox "A1:C5の外には移動できません", vbExclamation
        r = WorksheetFunction.Min(Target.Row, 5)
        c = WorksheetFunction.Min(Target.Column, 3)
        Cells(r, c).Select
    End If
End Sub