t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

VBA:全てのブックで読み取り専用で開くかどうかを確認させる方法

ブック自体に設定を行うことなく、どのブックを開いたときにも読み取り専用の確認を表示させるためには、他のブックのイベントをキャッチするというテクニックが必要となる。それをするには、Excel自体をイベント付きの変数に格納してしまえば良い。
アドインに書いても良いが、今回は個人用マクロブックでやってみようと思う。


まずPERSONAL.XLSBのThisworkbookコードに以下のように記述する。

Dim WithEvents ExcelApplication As Application

Private Sub Workbook_Open()
    Set ExcelApplication = Application
End Sub

これで、個人用マクロブックを開いたとき(つまりExcelの起動時)、Excel自体が変数にセットされる。

次に、イベントのコードである。表題の件に加えて読み取り専用ブックを編集しようとした際の警告も追加した。

'ブックを開く時に常に読み取り専用で開くかどうかを確認させる。
Sub ExcelApplication_WorkbookOpen(ByVal wb As Workbook)
    If Not wb Is ThisWorkbook Then
        If Not wb.ReadOnly Then
            If MsgBox(wb.Path & "\" & wb.Name & "を読み取り専用で開きますか?", _
                vbYesNo + vbQuestion + vbDefaultButton1, "確認") _
                = vbYes Then
                    wb.Saved = True
                    wb.ChangeFileAccess Mode:=xlReadOnly
            End If
        End If
    End If
End Sub

'読み取り専用で開いているブックに編集しようとすると警告する。
Sub ExcelApplication_SheetChange(ByVal Sh As Object, ByVal Target As Range)
    Static 編集許可ブック As New Collection
    Dim b As Workbook
    For Each b In 編集許可ブック
        If Sh.Parent Is b Then Exit Sub
    Next
    If Sh.Parent.ReadOnly Then
        If MsgBox("このブックは読み取り専用として開かれています。" _
            & vbNewLine & "編集を続行しますか。", vbYesNo + vbInformation, "確認") _
            <> vbYes Then
                Application.EnableEvents = False
                On Error Resume Next
                Application.Undo
                On Error GoTo 0
                Application.EnableEvents = True
        Else
            編集許可ブック.Add Sh.Parent
        End If
    End If
End Sub

WithEvents付きで変数を宣言すると、オブジェクトボックス(下図左)で宣言した変数を選ぶことができ、次のように右側でイベントを選択できるようになるので、その他のイベントを利用したい場合はそちらから確認・追加すると良い。
f:id:t-hom:20150224005521p:plain

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。