Excel VBAマクロ パスワード解除方法
Excel VBAでパスワードロックを解除する方法です。
VBAのパスワードロックは、ユーザーがプログラムを変更できないよう制限する為に設定するものです。しかし、時にパスワードが紛失するということがあります。「パスワードを忘れてしまった」「開発者が退職し、パスワードがわからない」などが理由として多いのではないでしょうか。
ひどい案件でVBAのパスワードがかかったまま渡され、担当者に聞いたところ「知らない」と言われて途方に暮れるプログラマーもいたと聞いたことがあります。
そんな方たちの助けになればと、VBAのパスワード解除方法を紹介します。
くれぐれも悪用したり、他人の著作物を覗き見るような不正はしないでください。
全て自己責任において実施してください。当方では一切の責任を負いません。
検証したExcelのバージョン
今回は Windows7 / Excel 2010 を使って検証しました。Excel 2007 以降であれば同じ操作で適用できると思います。
追記:Excel 2010 / 2013 / 2016 / 2019で検証済。
本記事の対象はOffice 32Bit版のみです。64Bit版は対象外です。
詳細なバージョン情報は「ファイル」-「アカウント」から「Excelのバージョン情報」をクリックして出てきた下記の画面で確認できます。
動作可能か事前に確認しておいてください。
64Bit版の場合には下記のページを参考にしてみてください。
無理に64Bit版でコードを書くよりも32Bit版を利用している人に頼むことをおすすめします。
VBAパスワードの解除方法
VBAのパスワードを解除するには、VBAを記述します。プログラムによって解除するというものです。
以降の操作をする前に、該当の Excel ブックはコピーしてバックアップしておいてください。ファイルが破損する可能性があります。
まず最初に、パスワードロックされている xlsm ファイルを開きます。
ここではファイル名を「locked.xlsm」としています。
「開発タブ」から「Visual Basic」を選択します。下図のように、パスワードロックがかかっていることを確認します。
次に「ファイルタブ」から「新規作成」-「空白のブック」をクリックします。
「名前を付けて保存」から、ファイルの種類を xlsm として適当な場所に保存します。
ここではわかりやすいように、「unlocked.xlsm」として保存しました。
再び VBA の画面に戻って、新規作成した xlsm ファイルを右クリックして「挿入」-「標準モジュール」をクリックします。
下図のように 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キー」を押下します。
「unprotected」を選んで「実行」ボタンを押下します。
このメッセージが出ればパスワードロックは解除されています。
VBA Project を開いてパスワードロックが解除されていることを確認してみましょう。
新しいブックを作ってインポート
上述の方法でパスワード解除した後、ファイルを保存して再パスワード設定しようとすると Excel が強制終了することがあります。どうやらブックに何か障害で出てしまうようですね。xls形式, xlsm形式共にNGでした。新しいブックを作ってそちらにインポートすることで解決できます。
パスワード解除した後、パスワードロックのかかったVBAプロジェクトを右クリックして「VBAProject のプロパティ」を開きます。
「保護」タブの「プロジェクトを表示用にロックする」のチェックを外します。
次に、VBAの記述されたファイルを選んで「ファイルのエクスポート」を選択します。
適当な場所に保存します。
次に、新しいブックを作って保存します。(xls形式かxlsm形式)
新規ブックの VBA プロジェクトを右クリックして「ファイルのインポート」を選びます。
先ほど保存した場所に移動し、エクスポートしたファイルを選択します。
インポートされたことを確認します。
エクスポート・インポートを使わなくても、VBAソースをコピペしても同じです。シートはExcel上でコピーすればOKですし、ThisWorkbookに何か記述していた場合もコピペでOKです。フォームを使っている場合は、エクスポート・インポートを利用しましょう。
参考サイト
まとめ
Excel VBAでパスワードロックを解除する方法を紹介しました。
「Excel シートやブックの保護パスワード解除方法」でも書きましたが、パスワード管理って安易におこなわれているケースが多いですね。企業の大小にかかわらず、担当者任せのパスワード管理となっていて、きちんと管理・共有されていないように感じられます。
特に、Excel や VBA では簡単にパスワード設定できることから、開発者が安易に変更した後、忘れてしまうこともあるようですね。
ソースを書き換えた後、パスワード設定を間違ってしまうなどのケースもあるのかな・・。
上述の方法で解除できる範囲であればいいですが、VBAの場合パスワードを紛失すると、もう一度同じものを作らなくてはならないなどの大きな損害が発生する可能性があります。
私も開発者の一人として、きちんとしたパスワード管理と、変更時の情報共有をしっかりやりたいと思います。
おつかれさまでした。