No.011
右クリック、印刷、上書き保存などブックに規制をかける 《イベント プロシージャ Cancel=True》
2003/2007/2010/2013
VBAのイベント プロシージャは、イベント、これは何かしらのタイミングによって自動的に動作させるVBAとなります。
イベント プロシージャを記述していく場所は、標準モジュールではなく、ブックやシートのモジュールを使用します。
VBEを開いて左上のプロジェクト エクスプローラーには、Excelに存在する各シートと ThisWorkbook というモジュールがあり(下図左赤枠)、ダブルクリックすると、シートやブックに特定したイベント プロシージャを記述できるモジュールが表示されます。
今回はおもに ThisWorkbook、ブックのイベント プロシージャを使用して、印刷や右クリックなど、動作を規制する簡単なマクロを楽しく作ってみましょう。
ThisWorkbook のモジュールを表示して、左上の初期は「(General)」と表示されている[オブジェクト]ボックスの▼をクリックして「Workbook」を指定します。
続いて、右上の[プロシージャ ボックス]の▼より表示される一覧は、数多くのブックにかかわるイベントです。
一覧の中で「SheetBeforeRightClick」を選択し、挿入してみます。
すると自動的に、「Private Sub Workbook_SheetBeforeRightClick~」の記述が入りました。
最初に挿入されていた「Workbook_Open」のプロシージャは、不要なので削除しましょう。
プロシージャ名となる1行目を見ていくと、() 内に引数があらかじめ設定されており、「Cancel As Boolean」に注目します。
「As Boolean」はブール型、つまり「True/False」で、引数Cancelを設定することができるということです。
挿入した「SheetBeforeRightClick」のイベント プロシージャ、これは右クリックする直前でイベントが発生します。
記述を書く前に動作の確認、現在Excelのすべてのシートにおいて、右クリックするとショートカット メニューが表示されます。これはOKですね。
では、次のように記述してみます。
Private Sub Workbook_SheetBeforeRightClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)
Cancel = True
MsgBox "右クリック無効です。"
End Sub
ではこれで、各シートで右クリックしてみますと、ショートカット メニューは表示されず、メッセージが表示されます。
「Cancel = True」と指定すると、イベントの右クリックはその直前にキャンセルされるため、機能しなくなるのです。
もし、特定のシートだけ右クリックをさせたくないのであれば、各シートのイベント プロシージャにある「BeforeRightClick」(似ているが先ほどと違う)を使用し、同様に設定します。
イベント プロシージャの「Cancel = True」は楽しく使えて役に立つわけですが、使えるケースは、引数Cancel が設定されていることです。
Excel2013では、引数Cancel がある主なイベントは次のとおり、「Cancel = True」を使用すると、それぞれ次のような規制をかけることができます。
- BeforeClose …閉じる時→閉じる不可
- BeforePrint …印刷時→印刷不可
- BeforeSave …保存時→保存不可
- SheetBeforeDoubleClick …ダブルクリック時→ダブルクリック不可
- SheetBeforeRightClick …右クリック時→右クリック不可
- BeforeXmlExport …Xmlデータエクスポート時→Xmlデータ出力不可
- BeforeXmlImport …Xmlデータインポート時、更新時→Xmlデータ取り込み・更新不可
印刷させたくない場合も、同様です。
Private Sub Workbook_BeforePrint(Cancel As Boolean)
Cancel = True
MsgBox "印刷不可です。"
End Sub
気を付けたいのは、「Cancel = True」のみ記述して何もお知らせをしないと、Excelの不具合と思われてしまう可能性がありますので、メッセージなりを付けた方がいいでしょう。
特定シートのみ印刷を不可にする場合、、シートのイベントにはありませんので、次のようにIf文で対応します。
Private Sub Workbook_BeforePrint(Cancel As Boolean)
If ActiveSheet.Name = "Sheet1" Then
Cancel = True
MsgBox "印刷不可です。"
End If
End Sub
イベント プロシージャの「Cancel = True」、使い方は簡単です。