• ベストアンサー

ExcelVBA: アクティブシート/アクティブブックの変更を禁止したい?

お世話になります。 最初に「アクティブシート/アクティブブックの変更」というと (1)今、あるブック、シートがアクティブになっている(最前面に出ている)状態から、別のブック、シートをクリックして、そっちにフォーカスを移す。別のブック、シートがアクティブになる。 という意味と、 (2)あるブック、シートがアクティブになっていて、その内容を変更する。シートの名前や、シート状の式を変更する という意味と2つあると思いますが、(1)の方です。 ExcelVBAで、あるワークブックの、あるワークシートにおいて、ユーザーフォームを使って作業をしているとします。 この作業はしばらく掛かるので、ユーザーフォームを(モードなしで)出しっぱなしにして作業してもらいます。 その時に、別のシート/ブックに行かれてしまうと整合性が分からなくなってしまうので、別のシート、ブックをクリックしてフォーカスの移動をしようとしたり、今のブックをクローズしようとしたり、今のシートを非表示にされたりした場合は、その動作を検知して、 「別のシートにいくならいったんユーザーフォームの作業をやめてください。やめていいですか(Yes/No)」 と言い、Yesというとフォームを閉じ、Noの場合は別のシート、ブックへのフォーカスの移動、今のブックのクローズ、今のシートの非表示化の動作をとりやめ、作業中のシートにフォーカスを当て続けたいです。 あるいは、それが難しければ、ユーザーフォームの作業中は別のシート、ブックへのフォーカスの移動、今のブックのクローズ、今のシートの非表示化の動作を禁止し、それらの操作をしようとしたら、 「ユーザーフォームの作業中に別のシートにいくことはできません。いくならいったんユーザーフォームの作業をやめてください。(Yes)」 と言うだけでもいいです。 上記のような動作をさせるにはどうすればいいでしょうか。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • nda23
  • ベストアンサー率54% (777/1415)
回答No.2

対象ワークブックの所に以下のコーディングを行います。 Dim 応答  As Long Dim 処理中 As Boolean '★フォームの処理を開始したらTrueにする Const Msg = "別のシートにいくならいったんユーザーフォームの作業をやめてください。やめていいですか(Yes/No)" Private Sub Workbook_SheetActivate(ByVal Sh As Object) If Not 処理中 Then Exit Sub If Sh Is Nothing Then Exit Sub If ActiveSheet.Name = "Sheet1" Then Exit Sub If 応答 = vbYes Then   応答 = vbNo   Exit Sub End If Dim WKS As Worksheet Set WKS = ActiveSheet Sh.Previous.Activate 応答 = MsgBox(Msg, vbQuestion + vbYesNo) If 応答 = vbNo Then Exit Sub WKS.Activate End Sub Private Sub Workbook_WindowDeactivate(ByVal Wn As Window) If Not 処理中 Then Exit Sub If ActiveWorkbook.Name = ThisWorkbook.Name Then Exit Sub If 応答 = vbYes Then   応答 = vbNo   Exit Sub End If Dim WKB As Workbook Set WKB = ActiveWorkbook ThisWorkbook.Activate 応答 = MsgBox(Msg, vbQuestion + vbYesNo) If 応答 = vbNo Then Exit Sub WKB.Activate End Sub でも、正しくはブック、シートを明示的に指定してコードを書くべき です。アクティブなブックやシートが変化して、オカシクなるのは バグと言えます。

その他の回答 (2)

  • imogasi
  • ベストアンサー率27% (4737/17069)
回答No.3

こういう手の問題は難しい。 たまたま思い付きをやっていたら、 ThisWorkbookのWorkbook_SheetActivateイベントで、下記のようにすると、どうかな。特定のシートではだめ、面倒。 下記はSheet1に限定する例 Private Sub Workbook_SheetActivate(ByVal Sh As Object) If Sh.Name <> "Sheet1" Then Sheet1.Activate End Sub 他シートタブをクリックしてもSheet1に戻る。 ーー ただ色んな場合でこれでうまく行くか、難しい問題だが。 手操作だけでなく Sub test01() Worksheets("Sheet4").Activate End Sub でも有効のようだ。 == エクセルでは、こういう操作者に対する、防御的な、仕様の組み込みは、一般に難しい。エクセルはそういう使い方をあまり考慮した対策を用意してくれてない。シートの保護はか。 ウィンドウズの(エクセル)よいところはどこでも順序を強制されず触れるところ。昔の大中型コンピュタはコンピュタから指示されることに操作者が答えて処理が進んでいたので、余分なことは出来なかったが。

TYWalker
質問者

お礼

まとめてで申し訳ありません。 SheetActivateハンドラというのがまさにぴったりです。 ただ、確かに設計にも問題がありますねー。 どうもありがとうございました!

  • YEND77
  • ベストアンサー率56% (21/37)
回答No.1

(本回答になってないんでご参考程度に・・・) アクティブじゃなくて絶対指定にしてしまう。

関連するQ&A