まるで魔法!!簡単ExcelVBAのプロジェクトロックをさらっと解除する方法。本当は教えたくない!?いたずら厳禁の簡単解決法

今回は、EXCEL VBAで困った時に役立つ「VBAプロジェクトのロック解除コード」をご紹介しちゃいます。

注意

※今回ご紹介するコードは、私が開発したものではありません。
流用元はすでに削除されていましたので、改めて掲載させていただきました。

VBAでプログラミングをしていると、コードの保護をするためにプロジェクトをロックすることがあります。

主な目的は誰かが勝手にコードを変更して、エラーなどのトラブルにならないように行ったりするためにロックしますが、実はこれがくせ者なんです。

プログラミングしている人が一人であれば良いんですが、その人が退職したりロックの解除用パスワードを伝え忘れたりしていると、後任の人は基になるExcelを改良したり、作り変えたり出来ないのでこれがトラブルの原因になります。

なにせコードが見られない。ということは最初から同じものを作り直さなくてはいけない可能性が高くなってしまいます。

こうなると、相当の時間使うことになってしまいます。

それに同じものが作れるとは限らないです。

これは、会社にとっても後任の方にとっても大きな損失にですよね。

そんな時は、これから紹介する方法を試してみて下さい。VBAプロジェクトを解除できる可能性があります。

それでは、早速本編に行ってみましょう!!

VBAロック解除_通常Office 64bit対応版

いきなりですが、64bit版のExcelを使っていてロックが掛かって困っている場合は、次の2つのコードをそれぞれのモジュールにコピペしてコードを実行してみましょう。

上手くいけば実行するだけで、ロックを外してくれる優れたプログラムです。

※このコードを実行する時は、必ずロックを解除したいファイルのバックアップをして下さい。もしもに備えることが大切です。 

【実行するコード (モジュール1) 】

Option Explicit

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

【セットで記述するコード(モジュール2)】

Option Explicit

Private Const PAGE_EXECUTE_READWRITE = &H40

Private Declare PtrSafe Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As LongPtr, Source As LongPtr, ByVal Length As LongPtr)

Private Declare PtrSafe Function VirtualProtect Lib "kernel32" (lpAddress As LongPtr, _
ByVal dwSize As LongPtr, ByVal flNewProtect As LongPtr, lpflOldProtect As LongPtr) As LongPtr

Private Declare PtrSafe Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As LongPtr

Private Declare PtrSafe Function GetProcAddress Lib "kernel32" (ByVal hModule As LongPtr, _
ByVal lpProcName As String) As LongPtr

Private Declare PtrSafe Function DialogBoxParam Lib "user32" Alias "DialogBoxParamA" (ByVal hInstance As LongPtr, _
ByVal pTemplateName As LongPtr, ByVal hWndParent As LongPtr, _
ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer

Dim HookBytes(0 To 5) As Byte
Dim OriginBytes(0 To 5) As Byte
Dim pFunc As LongPtr
Dim Flag As Boolean

Private Function GetPtr(ByVal Value As LongPtr) As LongPtr
    GetPtr = Value
End Function

Public Sub RecoverBytes()
    If Flag Then MoveMemory ByVal pFunc, ByVal VarPtr(OriginBytes(0)), 6
End Sub

Public Function Hook() As Boolean
    Dim TmpBytes(0 To 5) As Byte
    Dim p As LongPtr
    Dim OriginProtect As LongPtr

    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 LongPtr, _
ByVal pTemplateName As LongPtr, ByVal hWndParent As LongPtr, _
ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer

    If pTemplateName = 4070 Then
        MyDialogBoxParam = 1
    Else
        RecoverBytes
        MyDialogBoxParam = DialogBoxParam(hInstance, pTemplateName, _
                   hWndParent, lpDialogFunc, dwInitParam)
        Hook
    End If
End Function

VBAロック解除_Office365 64bit対応版

ポイント

【Office365 64-bit対応版】を公開します。
今回、コメントを頂きなんとOffice365対応版を作成していただきました!!
公開の了承も頂いておりますので、ありがたく公開させていただきます。
動作確認もさせて頂きました。使い方はほぼ同じですが「モジュール1」にすべて記載すれば使うことが出来ます。
Office365以外のバージョンでは、エラーが発生する可能性がありますので、今までのものも掲載しておきます。
ご助力頂き本当にありがとうございました。
【動作テスト環境】
Windows 10 Home 1909(ビルド 18363.720)
Office365 MSO バージョン2003(ビルド 12624.20466)

▼ Office365 64bit対応版コード

Option Explicit
 
Private Const PAGE_EXECUTE_READWRITE = &H40
Private Declare PtrSafe Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As LongPtr, Source As LongPtr, ByVal Length As Long)
Private Declare PtrSafe Function VirtualProtect Lib "kernel32" (lpAddress As LongPtr, ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As LongPtr) As Long
Private Declare PtrSafe Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As LongPtr
Private Declare PtrSafe Function GetProcAddress Lib "kernel32" (ByVal hModule As LongPtr, ByVal lpProcName As String) As LongPtr
Private Declare PtrSafe Function DialogBoxParam Lib "user32" Alias "DialogBoxParamA" (ByVal hInstance As Long, ByVal pTemplateName As LongPtr, ByVal hWndParent As Long, ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As Long) As Integer
Dim HookBytes(0 To 11) As Byte
Dim OriginBytes(0 To 11) As Byte
Dim pFunc As LongPtr
Dim Flag As Boolean
  
Private Function GetPtr(ByVal Value As LongPtr) As LongPtr
    GetPtr = Value
End Function
  
Private Sub RecoverBytes()
    If Flag Then MoveMemory ByVal pFunc, ByVal VarPtr(OriginBytes(0)), 12
End Sub
  
Private Function Hook() As Boolean
    Dim TmpBytes(0 To 11) As Byte
    Dim p As LongPtr
    Dim OriginProtect As LongPtr
  
    Hook = False
    pFunc = GetProcAddress(GetModuleHandleA("user32.dll"), "DialogBoxParamA")
    If VirtualProtect(ByVal pFunc, 12, PAGE_EXECUTE_READWRITE, OriginProtect) <> 0 Then
        MoveMemory ByVal VarPtr(TmpBytes(0)), ByVal pFunc, 12
        If TmpBytes(1) <> &HB8 Then
            MoveMemory ByVal VarPtr(OriginBytes(0)), ByVal pFunc, 12
            p = GetPtr(AddressOf MyDialogBoxParam)
            HookBytes(0) = &H48
            HookBytes(1) = &HB8
            MoveMemory ByVal VarPtr(HookBytes(2)), ByVal VarPtr(p), 8
            HookBytes(10) = &H50
            HookBytes(11) = &HC3
            MoveMemory ByVal pFunc, ByVal VarPtr(HookBytes(0)), 12
            Flag = True
            Hook = True
        End If
    End If
End Function
  
Private Function MyDialogBoxParam(ByVal hInstance As Long, ByVal pTemplateName As LongPtr, ByVal hWndParent As Long, ByVal lpDialogFunc As LongPtr, 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

公開コードの表記に問題があった時の対応法

ポイント 【コードに関する補足】
今回、コードの内容( セットで記述するコード(モジュール2) )の表記の問題をご指摘いただきました。

原因と解決法が分かりましたので、同じようなトラブルで悩まれている方は参考にしてみて下さいね。

《問題点》「&」→「 &amp; 」と表示されてしまう
《原因》「SyntaxHighlighter Evolved」というプラグインの影響
《解決法》基本的には、作者様に対応していただけることを待ちますが、「functions.php」にコードを書くことで一時的ですが解決出来ます。

尚、問題が発生していた部分は「ハイライト表示」にしてありますのでコピペし直すか、コピペ済みの方はお手数ですが置換機能などで修正して下さい。

▼ 「functions.php」の追記に必要なコードはこちらです。

function kagg_syntaxhighlighter_precode( $code, $atts, $tag ) {
    if ( 'code' === $tag ) {
        $code = wp_specialchars_decode( $code );
    }
    return $code;
}
add_filter( 'syntaxhighlighter_precode', 'kagg_syntaxhighlighter_precode', 10, 3 );

同じ悩みを持っている方は参考にしてみてくださいね。

使い方を確認してロックを解除しよう

使い方は、シンプル

  1. 解除したいEXCELファイルを開きます。
  2. 作成したロック解除用のEXCELファイルを開いておきます。
  3. ロック解除ファイルの『unprotected』というプログラムを実行します。
  4. 下記のメッセージボックスが表示されればプログラムのロックは解除されます。

ちょっと分かり辛いので今回は動画を用意したので見てみて下さい。

※事前にロックが掛かっているファイルと新規のExcelファイルを2つ開いておきましょう。
コードを記入したファイル(解除用のExcel)でマクロを実行するとロックを解除することが出来ます。

最後の仕上げを忘れずに

ふぅ~。無事ロックを解除することに成功しました。

これで次回からは、コードを改良してサクサク便利なプログラムが書けそうだ。

そう思って上書き保存して安心してはダメです。

ここでポイントが1つあります。

このプログラムは、ロックを解除してくれるのは良いんですが、暗証番号の削除まではしてくれません。

では、何も対策せず保存してもう一度ファイルを開くと、どうなるんでしょう?

答えは… … … 。

ファイルを開いた時にまたロックされてしまいます。

そんなときは一度、暗証番号を削除しておきましょう。

その後に新しいパスワードでロックすれば、安全性は上がっても心配は減ります。

もちろん、暗証番号を設定しなくても使うことは出来るので、そのままでもOKです。

じゃあ、どうすれば暗証番号を削除出来るのか?

答えは簡単です。順を追って説明しますね。

事前にロック解除済みのExcelを開いてVBEの画面を表示しておいて下さい。

①「ツール」→「VBAProjectのプロパティ(E)…」をクリックします

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

③2ヶ所のパスワードを両方とも削除します。

④「OK」ボタンをクリックします。

⑤上書き保存をして完了です。

すごく簡単でしたよね

これをしないと、何度も保護の解除をしなくてはいけません。

忘れずに最後の仕上げをしましょう!!

まとめ

今回のお話は以上です。

私も以前ロックが掛かったマクロ有効ブックで同じ目にあったのでこの方法で解決しました。

本当に困った時にこの方法を使ってみましょう。

きっと助けてくれますよ。

但し、悪用は厳禁です。

意図的にコードを削除したり、書き換えたりすれば大切なデータが壊れてしまったり、下手にいじってプログラム自体を壊してしまわないように注意しましょう。

プログラムというのは、良い使い方をすれば多くの人を助けてくれる素晴らしいものですが、悪いことに使おうと思えばコンピューター・ウイルスです。

今回紹介したコードは、64bit(64ビット)というタイプにも対応しているプログラムです。

実は、Excel(Office)には、32bit版と64bit版があります。

64bit版の特徴は、平たく言うとたくさんの情報を扱う時に処理速度が向上する大容量ファイル 対応 タイプのExcelです。

あまり大きな容量のファイルを扱うことは、実務ではそんなに無いので、通常は32bit版を使われる方が多いかと思いますが、私のように多くの情報を扱うことがある場合は、64bit版の方が良いですね。

もし、上手くいかない場合や作り方が分からない場合は相談して下さい。

分かる範囲で回答します。

コメント・各SNSなんでも大丈夫です。お気軽にどうぞ。

今回も最後まで読んでいただきありがとうございました。

それではまた次回お会いしましょう。じゃあね。

12 件のコメント

  • EXCEL2010で記載のモジュールを実行しましたが、プロジェクトのロックは解除
    されませんでした。

    解除したいEXCELは2010以前に記述されているものなのですが。
    拡張子をXLSMで保存して実行してもダメでした。
    他に方法がありますでしょうか?

    • のぶ さん
      こんにちは

      気楽生活管理人の鶴谷です。
      先日は、コメントいただきありがとうございます。

      私なりにVBA以外の方法でロックを外す方法について検証してみました。
      前提として必ず解除出来ますという話では無いですし、ファイルが壊れる可能性がありますが、一つ方法を見つけました。
      実行してもらうときには、あくまで自己責任でお願いします。

      やり方は、こちらのサイトさんの方法であれば、私の場合解除出来ました。

      私の場合は、Microsoft Office 365 Business(バージョン2001 ビルド121430.20288)にて試しました。

      手順を簡易的に説明すると
      ①解除したいファイルを開きます
      ②「.xls」形式で保存します
      ③ファイルをコピーしておきます(バックアップとファイルが壊れても問題ないように)
      ④③のファイルをバイナリエディターでパスワード部分を書き換えます
      ⑤開き直すと無事開くことができます

      以上となります。

      私の場合は、上手くいきましたがコードやデータ自体壊れてしまう可能性もありますので、くれぐれも気をつけてやってみてはいかがでしょうか?
      今回、私も新しいことにチャレンジ出来たので、また改めて記事に反映出来たらと思います。

      少しでもお役に立てれば何よりです。
      また、何かありましたら気軽にご連絡下さい。

    • のぶ さん
      こんにちは

      気楽生活管理人の鶴谷です。
      コメントを頂きありがとうございます。

      コメント内容を拝見してExcel2010(以前)で作成したファイルを最新版として保存
      拡張子が「.xlsm」として保存出来たので当サイトのコードをコピペして実行してみたものの上手くいかないということですね。

      ご質問は、今回の方法が上手くいかないので他に手段は無いか?
      とのことですが、残念ならがら分かりません。
      お力になれず申し訳ありません。

      ただ、何も無いです。
      とお答えするのは心苦しかったので、他の手段は探ってみました。
      今の所上手く行ったものは無いので、もし可能性のある方法を見つけましたら改めてお返事させていただきます。

      気楽生活を読んで頂きありがとうございます。
      これからも、読んでもらえるように更新頑張っていきたいと思います。

    • grainrigi さん

      今回は、Office365版への対応をご教授頂きありがとうございました。
      動作確認もとれ、公開させていただきました。

      このようなご連絡をいただけるとは思っておらず、大変うれしいです。
      これからも、気楽生活を見ていただけると嬉しいです。
      ありがとうございました。

    • grainrigiさん

      コメントいただきありがとうございます。
      Office365 64-bit対応版の制作をして頂いたんですね。
      ありがとうございます。

      最近、コメントをいただくことが増えていた案件なので、ご助力頂き大変ありがとうございます。
      確認させて頂き反映の準備ができ次第すぐに反映させていただきたいと思います。

      返信が遅れてしまい申し訳ありませんが、まずはお礼を申し上げます。

  • プログラムを実行し、メッセージボックスも表示されました。
    VBAProjectのプロパティを開こうとすると、強制的にファイルが閉じてしまいます。VBA自体を見ようとクリックしても同様です

    • たなか さん

      以前コメントを頂きありがとうございました。
      今回、Office365でも動作するコードを作成していただきましたので、公開させていただきました。
      もしかしたら、解決出来るかもしれませんので、試してみて下さい。

      これからも、気楽生活をよろしくお願いします。

    • たなか さん

      コメントを頂きありがとうございます。
      処理完了のメッセージボックが表示されても、「VBEが表示出来ずExcelが強制的に終了してしまう」という現象についてのお問い合わせですね。
      Officeのバージョンが明記されていなかったので、あくまで憶測での回答となってしまいしまいますが、ご了承下さい。

      結論からお伝えすると、Officeのバージョンによるエラーでは無いかと思います。
      ブログにも書かせていただいているように残念ながらOffice365には対応していません。
      また、サポートが切れているOfficeに関してもテスト対象外となってしまいます。

      私もコメントを頂き、《Microsoft Office 365 Business バージョン2001(ビルド1243.20288)》の環境で試してみましたが、ご指摘の通りメッセージは表示されてもロックを解除出来ずExcelが強制終了してしまいます。
      また、サポート切れのOfficeや全てのバージョンでの検証ができる訳ではないのではっきりとした線引が出来ず申し訳ありません。

      また、申し訳ありませんがこちらのソースコードについては、私が作ったものでは無いので解決策が見つかれば更新させていただきたいと思っています。
      お力になれず心苦しいですができる限り努力させていただきます。

      わざわざコメントを頂きありがとうございました。

  • 【セットで記述するコード(モジュール2)】にあるソースコードにおいて
    &を&に修正しないとそのままコピペしてEXCELの標準モジュールに張り付けてもコンパイルエラーとなります。

    • gyokusen_sinceさん
      こんにちは

      気楽生活管理人の鶴谷です。
      モジュール2の「&」→「&」になってコンパイルエラーになってしまう件のご指摘ありがとうございます。

      結論から言うと、今回の原因はソースコードの表示用プラグインの仕様に問題があったことが分かりました。
      再調整をしたところ、表記の問題は解決出来たと思います。(私も再度コピペを行いコンパイルエラーにはならないことを確認しました)
      詳細は、後ほど記事内容に追記する予定ですので、そちらで確認をお願いします。

      教えて下さり、ありがとうございました。

    • Web上ではアンパサントは&amp;と書いても&になってしまうようですね。
      そのあたりで発生した問題なのでしょうか?
      VBE上で張り付けた後に置換をすれば解決します。

  • コメントを残す

    メールアドレスが公開されることはありません。 * が付いている欄は必須項目です