category name  »  page title date

ワークシートの移動

ワークシートの間を行ったり来たりして作業するようなプロジェクトの場合、それぞれのシートに別のシートへのジャンプボタンをつけたり、元に戻るボタンをつけたりしたくなります。普通は、そうしているでしょう。
その際に、ちょっと手間を節約するようなサブルーチンを作ってみました。

ワークシートに配置したボタンAの Shape 名に、移動先のワークシートの名前(たとえば "ProgressBar" など)をそのままつけて、下のコードに示した GotoSheet() をマクロに登録しておきます。ボタンAは、ProgressBar 以外にも必要に応じて複数できますね。ひょっとすると、ワークシートの数だけ。
同様に、戻るボタンBには適当な名前をつけて(たとえば "ReturnSheet" など) BackToSheet() をマクロに登録しておきます。
こうすると、これらのボタンは、コピーしてどこへ持って行っても、ボタンAをクリックするといつも所定のワークシート(たとえば ProgressBar)に移動し、ボタンBをクリックするといつも直前のワークシートに戻ることになります。

  
いずれも単純なマクロで、どうということもありませんが、あらかじめこういうものを用意しておくと、あとあととても便利です。ボタンAの名前の解釈をもう少し複雑にするとか、きちんとエラー処理を追加するとかといった場合にも、この GotoSheet() の中だけをいじれば済むので、手間がはぶけます。

標準モジュール         GotoSheet()、BackToSheet()

'----- 直前のワークシートの名前
Private prevSheetName
'----- 新しいワークシートに移動
Public Sub GotoSheet()
      prevSheetName = ActiveSheet.Name
      changeSheet Application.Caller
End Sub
'----- 直前のワークシートに戻る
Public Sub BackToSheet()
Dim sheetName
      sheetName = prevSheetName
      If IsEmpty(sheetName) Then Exit Sub
      If sheetName = ActiveSheet.Name Then Exit Sub
      changeSheet sheetName
End Sub
'----- 指定のワークシートに移動
Private Sub changeSheet(sheetName)
      ThisWorkbook.Worksheets(sheetName).Activate
End Sub

ここで、prevSheetName はこのブックが起動されるたびにクリアされているので、一度ほかのワークシートに移動した後でないと機能しません。また、戻れるのは直前のワークシートで、それ以前は記録されていません。
それはそれで、そういうものだと思えばよいのですが、できればブックを落とした後も記憶しておいてほしい、しかも、直前だけでなく、その前も、という要求があるとすれば、prevSheetName をちょっと工夫することで可能になります。

上のコードから Private prevSheetName を消して、その替わりに次のコードを追加すればそれが実現します。prevSheetName を変数ではなく、ワークシート上に動的に記録していくプロパティとしています。
LIFO(Last In First Out) 型のスタックを使った簡単なものですが、これを各ボタンごとに呼び出す異なるマクロに対応しようとすると手間ですね。

標準モジュール

'スタック領域を、ワークシート上に確保して、
'最初のセルの名前を Stack とし、
'最大のスタック深度を 10 としておきました
Private Const stackCellName = "Stack"
Private Const maxStackIndex = 10
  (この2行をモジュールの最初に書いておきます)

'----- prevSheetName の取り出し
Private Property Get prevSheetName()
Dim index
      prevSheetName = ""
      With Range(stackCellName)
            index = .value
            If index = 0 Then Exit Property
            prevSheetName = .Offset(index, 0).value
            index = index - 1
            .value = index
      End With
End Property
'----- prevSheetName の格納
Private Property Let prevSheetName(sheetName)
Dim index
      With Range(stackCellName)
            index = .value
            If index < maxStackIndex Then
                  index = index + 1
                  .Offset(index, 0).value = sheetName
                  .value = index
                  Exit Property
            End If
            .Offset(1, 0).delete Shift:=xlUp
            .Offset(index, 0).value = sheetName
      End With
End Property