別シートのセルにジャンプする


VBAでは、うまくいきそうに見えて、実は失敗するケースがあります。たとえば、アクティブシートがSheet1のとき、次のコードを実行するとSheet2のセルB3が選択されます。あ、もちろん、Sheet2は存在するとします。

Sub Sample1()
    Sheets("Sheet2").Select
    Range("B3").Select
End Sub

また、アクティブシートではないシートのセルを、直接操作することもできます。アクティブシートがSheet2のとき、次のコードを実行すると、アクティブシートは移動せずに、Sheet1のセルC4に数値を入力できます。、

Sub Sample2()
    Sheets("Sheet1").Range("C4") = 123
End Sub

Sample2のように、別シートのセルを直接操作できるのなら、次のように書いたとしても、正常に動作するような気がします。

Sample3()
    Sheets("Sheet1").Range("C4").Select
End Sub

構文的には間違っていません。しかし、実行するとエラーになります。Sheet2を開いた状態で実行してみてください。

エラーメッセージは「RangeクラスのSelectメソッドが失敗しました」です。失敗しましたって言われても、何が原因で失敗したのかがわかりませんね。何しろ「Sheets("Sheet1").Range("C4") = 123」のように、別シートのセルを直接操作することは、可能なのですから。

実はVBAでは、アクティブでないシートのセルを直接Selectできないんです。これは、そういう仕様なのですから、素直に2行で書けば済む話です。もっとも、方法がないわけではありません。アクティブでないシートのセルを一発で選択するには、ApplicationオブジェクトのGotoメソッドを使います。次のコードは、アクティブシートではないSheet3のセルD5を選択します。

Sub Sample4()
    Application.Goto Sheets("Sheet3").Range("D5")
End Sub

このGotoメソッドは、少し変わった使い方ができます。引数に渡すジャンプ先には、セルを表すRangeオブジェクトだけでなく、VBE上で作成したプロシージャ名も指定できるんです。次のコードは、同じモジュール内の、プロシージャ「Test1」にカーソルが移動します。

Sub Sample5()
    Application.Goto "Test1"
End Sub

また、次のように、別モジュールのプロシージャにカーソルを移動することも可能です。

Sub Sample6()
    Application.Goto "Module2.Test1"
End Sub

まぁ、あまり便利ではありませんから、使う機会は少ないでしょうけど。要するに、ワークシート上で定義する"名前"と、プロシージャの名前は、同じように扱われるということですね。