アクティブでないシートのアクティブセル


某所で質問されたのですが、おもしろいネタだったので、こちらで解説します。質問の内容は「アクティブでないシートのアクティブセルを取得するにはどうしたらいいですか?」ということです。

たとえば今、Sheet1を開いているとします。アクティブセルをセルC1に移動します。次にSheet2を開きます。アクティブセルをセルB2にします。さて、この状態でSheet1のアクティブセル(C1)を取得するにはどうしたらいいでしょう?

まず、アクティブセルという概念を理解する必要があります。アクティブなセルというのは「現在Excelが注目しているセル」だと考えられます。あるいは「キーボードで打った文字が入力されるのがアクティブセル」という解釈もあります。このことから、Excelでアクティブセルは1つしか存在しないことがわかります。アクティブセルとは、アクティブシート上にしか存在しないのです。ですから、アクティブでないシートのアクティブセル…という発想自体が間違っていることになります。

ついでに、"アクティブセル"と"選択されているセル"の違いについても整理しておきましょう。下図をごらんください。セル範囲B2:D5が選択されている状態です。このとき、アクティブセルは背景が白色の「B2」で、選択されているのが「B2:D5」となります。

これは次のようなコードで確認できます。

Sub Sample()
    MsgBox ActiveCell.Address & vbCrLf & Selection.Address
End Sub

複数のセルを選択していないときは、アクティブセル(ActiveCell)=選択されているセル(Selection)になりますが、両者は別物です。マクロではこの違いが思わぬ問題を招きますので、十分に注意してください。

さて、それでも何とか"アクティブでないシートのアクティブセル"を知りたいことがあります。これは、次のように発想を転換すれば解決できます。アクティブでないシートにはアクティブセル(選択されたセル)がありません。それなら、シートをアクティブにしてやればいいのです。

Sub Sample2()
    Dim buf As String, s As Variant, ReturnSheet As Worksheet
    ''現在のシートを記憶する
    Set ReturnSheet = ActiveSheet
    Application.ScreenUpdating = False
    ''すべてのシートを開いてアクティブセルのアドレスを取得する
    For Each s In Worksheets
        s.Select
        buf = buf & s.Name & "のアクティブセル:" & ActiveCell.Address(0, 0) & vbCrLf
    Next s
    ''元のシートに戻る
    ReturnSheet.Select
    Application.ScreenUpdating = True
    MsgBox buf
End Sub

まず現在のシートを記録しておきます。そして、調べたいシートをSelectして開き、そこでアクティブセルを取得します。ここでは、すべてのシートを対象にしました。最後に元のシートを開いて終わりです。画面の切り替わりが気になるようなら、ScreenUpdatingプロパティを使って画面の更新を抑止しましょう。