Excel VBAマクロ パスワード解除方法

Excel VBAでパスワードロックを解除する方法です。

Excel VBAマクロ パスワード解除方法

VBAのパスワードロックは、ユーザーがプログラムを変更できないよう制限する為に設定するものです。しかし、時にパスワードが紛失するということがあります。「パスワードを忘れてしまった」「開発者が退職し、パスワードがわからない」などが理由として多いのではないでしょうか。

ひどい案件でVBAのパスワードがかかったまま渡され、担当者に聞いたところ「知らない」と言われて途方に暮れるプログラマーもいたと聞いたことがあります。

そんな方たちの助けになればと、VBAのパスワード解除方法を紹介します。

くれぐれも悪用したり、他人の著作物を覗き見るような不正はしないでください。

全て自己責任において実施してください。当方では一切の責任を負いません。


検証したExcelのバージョン

今回は Windows7 / Excel 2010 を使って検証しました。Excel 2007 以降であれば同じ操作で適用できると思います。

追記:Excel 2010 / 2013 / 2016 / 2019で検証済。

本記事の対象はOffice 32Bit版のみです。64Bit版は対象外です。

詳細なバージョン情報は「ファイル」-「アカウント」から「Excelのバージョン情報」をクリックして出てきた下記の画面で確認できます。

Excel 詳細なバージョン情報

動作可能か事前に確認しておいてください。

64Bit版の場合には下記のページを参考にしてみてください。

無理に64Bit版でコードを書くよりも32Bit版を利用している人に頼むことをおすすめします。

VBAパスワードの解除方法

VBAのパスワードを解除するには、VBAを記述します。プログラムによって解除するというものです。

以降の操作をする前に、該当の Excel ブックはコピーしてバックアップしておいてください。ファイルが破損する可能性があります。

まず最初に、パスワードロックされている xlsm ファイルを開きます。

ここではファイル名を「locked.xlsm」としています。

「開発タブ」から「Visual Basic」を選択します。下図のように、パスワードロックがかかっていることを確認します。

VBA Project パスワードロック確認

次に「ファイルタブ」から「新規作成」-「空白のブック」をクリックします。

Excel 空白のブック新規作成

「名前を付けて保存」から、ファイルの種類を xlsm として適当な場所に保存します。

ファイルの種類をxlsmで保存

ここではわかりやすいように、「unlocked.xlsm」として保存しました。

再び VBA の画面に戻って、新規作成した xlsm ファイルを右クリックして「挿入」-「標準モジュール」をクリックします。

VBA 標準モジュールの挿入

下図のように Module1 にソースを貼り付けます。

VBA Module1にソースを貼り付け

貼り付けるソースは以下のとおりです。

Option Explicit

Private Const PAGE_EXECUTE_READWRITE = &H40
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Long, Source As Long, ByVal Length As Long)
Private Declare Function VirtualProtect Lib "kernel32" (lpAddress As Long, ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As Long
Private Declare Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function DialogBoxParam Lib "user32" Alias "DialogBoxParamA" (ByVal hInstance As Long, ByVal pTemplateName As Long, ByVal hWndParent As Long, ByVal lpDialogFunc As Long, ByVal dwInitParam As Long) As Integer
Dim HookBytes(0 To 5) As Byte
Dim OriginBytes(0 To 5) As Byte
Dim pFunc As Long
Dim Flag As Boolean
 
Private Function GetPtr(ByVal Value As Long) As Long
    GetPtr = Value
End Function
 
Private Sub RecoverBytes()
    If Flag Then MoveMemory ByVal pFunc, ByVal VarPtr(OriginBytes(0)), 6
End Sub
 
Private Function Hook() As Boolean
    Dim TmpBytes(0 To 5) As Byte
    Dim p As Long
    Dim OriginProtect As Long
 
    Hook = False
    pFunc = GetProcAddress(GetModuleHandleA("user32.dll"), "DialogBoxParamA")
    If VirtualProtect(ByVal pFunc, 6, PAGE_EXECUTE_READWRITE, OriginProtect) <> 0 Then
        MoveMemory ByVal VarPtr(TmpBytes(0)), ByVal pFunc, 6
        If TmpBytes(0) <> &H68 Then
            MoveMemory ByVal VarPtr(OriginBytes(0)), ByVal pFunc, 6
            p = GetPtr(AddressOf MyDialogBoxParam)
            HookBytes(0) = &H68
            MoveMemory ByVal VarPtr(HookBytes(1)), ByVal VarPtr(p), 4
            HookBytes(5) = &HC3
            MoveMemory ByVal pFunc, ByVal VarPtr(HookBytes(0)), 6
            Flag = True
            Hook = True
        End If
    End If
End Function
 
Private Function MyDialogBoxParam(ByVal hInstance As Long, ByVal pTemplateName As Long, ByVal hWndParent As Long, ByVal lpDialogFunc As Long, ByVal dwInitParam As Long) As Integer
    If pTemplateName = 4070 Then
        MyDialogBoxParam = 1
    Else
        RecoverBytes
        MyDialogBoxParam = DialogBoxParam(hInstance, pTemplateName, _
        hWndParent, lpDialogFunc, dwInitParam)
        Hook
    End If
End Function

Public Sub unprotected()
    If Hook Then
        MsgBox "VBA Project is unprotected!", vbInformation, "*****"
    End If
End Sub

「Sub/ユーザー フォームの実行」ボタンを押下するか、「F5キー」を押下します。

VBA Sub/ユーザー フォームの実行

「unprotected」を選んで「実行」ボタンを押下します。

VBA unprotectedを実行

このメッセージが出ればパスワードロックは解除されています。

VBAパスワードロックは解除

VBA Project を開いてパスワードロックが解除されていることを確認してみましょう。

VBA パスワードロック解除の確認

新しいブックを作ってインポート

上述の方法でパスワード解除した後、ファイルを保存して再パスワード設定しようとすると Excel が強制終了することがあります。どうやらブックに何か障害で出てしまうようですね。xls形式, xlsm形式共にNGでした。新しいブックを作ってそちらにインポートすることで解決できます。

パスワード解除した後、パスワードロックのかかったVBAプロジェクトを右クリックして「VBAProject のプロパティ」を開きます。

VBAパスワード解除 VBAProjectのプロパティを開く

「保護」タブの「プロジェクトを表示用にロックする」のチェックを外します。

VBAパスワード解除 「プロジェクトを表示用にロックする」のチェックを外す

次に、VBAの記述されたファイルを選んで「ファイルのエクスポート」を選択します。

VBAパスワード解除 ファイルのエクスポート

適当な場所に保存します。

VBAパスワード解除 VBAファイル保存

次に、新しいブックを作って保存します。(xls形式かxlsm形式)

新規ブックの VBA プロジェクトを右クリックして「ファイルのインポート」を選びます。

VBAパスワード解除 VBAファイルのインポート

先ほど保存した場所に移動し、エクスポートしたファイルを選択します。

VBAパスワード解除 VBAファイルの選択

インポートされたことを確認します。

VBAパスワード解除 VBAファイルインポートの確認

エクスポート・インポートを使わなくても、VBAソースをコピペしても同じです。シートはExcel上でコピーすればOKですし、ThisWorkbookに何か記述していた場合もコピペでOKです。フォームを使っている場合は、エクスポート・インポートを利用しましょう。

参考サイト

まとめ

Excel VBAでパスワードロックを解除する方法を紹介しました。

Excel シートやブックの保護パスワード解除方法」でも書きましたが、パスワード管理って安易におこなわれているケースが多いですね。企業の大小にかかわらず、担当者任せのパスワード管理となっていて、きちんと管理・共有されていないように感じられます。

特に、Excel や VBA では簡単にパスワード設定できることから、開発者が安易に変更した後、忘れてしまうこともあるようですね。

ソースを書き換えた後、パスワード設定を間違ってしまうなどのケースもあるのかな・・。

上述の方法で解除できる範囲であればいいですが、VBAの場合パスワードを紛失すると、もう一度同じものを作らなくてはならないなどの大きな損害が発生する可能性があります。

私も開発者の一人として、きちんとしたパスワード管理と、変更時の情報共有をしっかりやりたいと思います。

おつかれさまでした。

この記事がお役に立ちましたら シェア をお願いいたします。