パスワード入力画面をスキップする


ブックを開くには「Workbooks.Open ファイル名」と書きます。ところが、もしこのブックに「読み取りパスワード」が設定されていた場合、パスワードを入力する画面でマクロが停止してしまいます。もちろん、パスワードを知っていれば、Openメソッドの引数に指定してやればいいのですが、では、そもそも、パスワードが設定されているブックかどうかを知らなかったとしたらどうでしょう。つまり、開いてみるまで分からないと。そんなブックを複数処理するとき、いちいちマクロが停止するようでは困ります。ここでは、パスワード入力画面をスキップする方法をご紹介します。

パスワード入力画面には、パスワードを入力するテキストボックスのほかに、[OK]ボタンと[キャンセル]ボタンが配置されています。この[OK]ボタンにはEnterキーが割り当てられ、[キャンセル]ボタンにはESCキーが割り当てられています。つまり、パスワード入力画面をマクロから閉じるには、ESCキーを押したことにしてやればいいんです。これには、SendKeysを使います。

SendKeys "{ESC}"

問題は、SendKeysを実行するタイミングです。パスワード入力画面は、ブックを開こうとした後で表示されるのですが、

Sub Sample()
    Workbooks.Open "C:\Password.xlsx"
    SendKeys "{ESC}"
End Sub

のように、Openメソッドの後ろに記述すると失敗します。Openメソッドを実行した後、パスワード入力画面が表示されてマクロが停止しますので、次のSendKeysはまだ実行されません。こんなときは、Openメソッドよりも先にSendKeysを実行します。

Sub Sample()
    SendKeys "{ESC}"
    Workbooks.Open "C:\Password.xlsx"
End Sub

コード的に、先にESCキーを押すというのは、何となく不思議な感じもしますが、Excel 5.0/95時代から知られているテクニックです。以前は、Microsoftの公式本にもこうしたやり方が紹介されていました。

さて、パスワード入力画面をESCキーでスキップすると、Openメソッドはエラーになります。そこで、SendKeysの前でエラーを無視しておきます。

Sub Sample()
    On Error Resume Next
    SendKeys "{ESC}"
    Workbooks.Open "C:\Password.xlsx"
End Sub

最後に、ブックが開けたのかどうかを判定します。これは簡単ですね。いろいろな方法が考えられますけど、ここではファイル名で判定してみましょう。

Sub Sample()
    On Error Resume Next
    SendKeys "{ESC}"
    Workbooks.Open "C:\Password.xlsx"
    If ActiveWorkbook.Name <> "Password.xlsx" Then
        MsgBox "パスワードが設定されています"
    End If
End Sub