【VBA】VBAコードにパスワードを設定して保護する方法(コピペOK)

VBA
スポンサーリンク
スポンサーリンク
  1. この記事でできること
  2. どんな場面で使う?
  3. 完成イメージ(Before / After)
  4. 実行前の準備
    1. バックアップを取る
    2. パスワードを控えておく
    3. Excelをマクロ有効ブック(.xlsm)で保存する
  5. 手順1:手動でVBAProjectにパスワードを設定する
    1. VBE(コードを書く画面)を開く
    2. VBAProjectのプロパティを開く
    3. 「保護」タブでパスワードを設定する
  6. 手順2:VBAからパスワードを自動設定する(コード版)
    1. VBE(コードを書く画面)を開く
    2. 標準モジュールを挿入する
    3. コードを貼り付けて実行する
  7. コード(基本版)– SendKeysでVBAProjectにパスワードを設定
    1. 書き換えポイント
    2. コードの流れ
    3. 「VBAプロジェクト オブジェクト モデルへのアクセスを信頼する」設定
  8. コード(実務版)– パスワード自動設定+保護レベル比較+配布対応
    1. 書き換えポイント
    2. コードの流れ
    3. 保護レベルの比較
  9. VBAProject保護の限界について(正直な話)
    1. 解析ツールで突破できる
    2. つまり何のために設定するのか
    3. 本気で守りたい場合の選択肢
  10. 配布時の注意点
    1. マクロ有効ブック(.xlsm)で配布する
    2. マクロのセキュリティ設定を案内する
    3. パスワードをコード内にハードコードしない(配布版)
  11. よくある落とし穴5選
    1. 1. パスワード設定後に保存せず閉じてしまった
    2. 2. SendKeysが効かない・タイミングがずれる
    3. 3. 「VBAプロジェクト オブジェクト モデルへのアクセスを信頼する」が無効
    4. 4. VBAProjectのパスワードとブックパスワードを混同する
    5. 5. 配布先で「マクロが無効」になってしまう
    6. VBAでSendKeysによるパスワード設定が効かないときの対処法
    7. VBAProjectの保護でVBEが開けなくなったときの対処法
  12. FAQ
    1. Q1: VBAProjectのパスワードを解除するには?
    2. Q2: .xlsb(バイナリ形式)でもVBAProjectの保護はできる?
    3. Q3: VBAProjectのパスワードを忘れた場合の対処法は?
    4. Q4: 複数のブックにまとめてVBAProjectパスワードを設定したい
    5. Q5: VBAProjectの保護とシート保護は両方かけるべき?
  13. まとめ
    1. 関連記事
  14. 次にやりたくなること
  15. もっとカスタマイズしたい場合

この記事でできること

  • VBAProjectにパスワードを設定してコードを閲覧・編集から保護できる
  • 手動設定の手順と、VBAからの自動設定方法の両方がわかる
  • ブックパスワード・シート保護・VBAProject保護の違いが整理できる

対象: Excel 2016以降 / Microsoft 365、Windows 10/11

どんな場面で使う?

  • 自作マクロを他部署や社外に配布するとき、コードの閲覧・編集を防ぎたいとき
  • 誤ってVBAコードを書き換えてしまう事故を防止したいとき
  • ブックパスワード・シート保護・VBAProject保護を一括で設定したいとき
  • アドイン(xlam)として配布するマクロの知的財産を保護したいとき

完成イメージ(Before / After)

Before(コードが丸見え):

  1. .xlsm ファイルを配布
  2. 受け取った人が Alt + F11 でVBEを開く
  3. コードが全部見える。書き換えも自由
  4. 意図しない改変で動かなくなり、「壊れた」と問い合わせが来る

After(VBAProjectにパスワード設定済み):

  1. .xlsm ファイルを配布
  2. 受け取った人が Alt + F11 でVBEを開く
  3. VBAProjectがロックされていて、パスワードなしではコードを見られない
  4. マクロは通常通り実行できる。改変による事故を防止

VBAProject (報告書マクロ.xlsm)
  ├─ Microsoft Excel Objects
  │    ├─ Sheet1
  │    └─ ThisWorkbook
  └─ 標準モジュール
       └─ Module1   ← 🔒 パスワードなしでは閲覧不可

自分も以前、業務用マクロを部署に配布したら、誰かがコードを触って動かなくなったことがある。「マクロが壊れた」と問い合わせが来て、調べたらセルのアドレスが書き換えられていた。悪意はなく、ちょっと中身を見てみたかっただけらしい。VBAProjectにパスワードをかけるようにしてからは、この手のトラブルがゼロになった。

この記事では、手動でのパスワード設定手順と、VBAから自動でパスワードを設定する方法を紹介する。配布用マクロを作る人に役立つはず。

コードを見られたくないなら、VBAProjectのパスワードが一番手軽な方法。

なお、ブックを開くときのパスワード(読み取りパスワード)については ブックにパスワードを自動で設定・解除する方法 を参照。シート単位の保護は 特定シートだけ保護・解除する方法 を参照。本記事では「VBAコード自体の保護」に特化する。

実行前の準備

バックアップを取る

パスワード設定後にパスワードを忘れると、コードの閲覧・編集ができなくなる。設定前に必ずファイルのバックアップを取っておくこと。

パスワードを控えておく

設定するパスワードはメモやパスワード管理ツールに記録しておく。VBAProjectのパスワードを忘れると、自分自身もコードを編集できなくなる。

Excelをマクロ有効ブック(.xlsm)で保存する

拡張子が .xlsx のままだとVBAコード自体が保存できない。

  1. 「ファイル」→「名前を付けて保存」
  2. ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
  3. 保存

手順1:手動でVBAProjectにパスワードを設定する

まずは手動での設定手順を押さえておく。VBAからの自動化は後述する。

VBE(コードを書く画面)を開く

  1. Excelで Alt + F11 を押す
  2. VBE(Visual Basic Editor)が開く

VBAProjectのプロパティを開く

  1. VBEの左側「プロジェクト エクスプローラー」で、対象の VBAProject(ブック名.xlsm) を右クリック
  2. 「VBAProject のプロパティ」を選択
  3. プロパティダイアログが表示される

「保護」タブでパスワードを設定する

  1. 「保護」タブを開く
  2. 「プロジェクトを表示用にロックする」にチェックを入れる
  3. 「パスワード」と「パスワードの確認」に同じパスワードを入力
  4. 「OK」をクリック
  5. ブックを上書き保存(Ctrl + S)して閉じる

重要: パスワード設定後、ブックを一度閉じて再度開くまでロックは有効にならない。保存せずに閉じるとパスワード設定が破棄される。

手順2:VBAからパスワードを自動設定する(コード版)

VBE(コードを書く画面)を開く

  1. Excelで Alt + F11 を押す
  2. VBE(Visual Basic Editor)が開く

標準モジュールを挿入する

  1. VBEのメニュー →「挿入」→「標準モジュール」
  2. 白い画面(コードウィンドウ)が表示される

コードを貼り付けて実行する

  1. コードウィンドウに、下のコードをそのままコピペする
  2. Alt + F8 → マクロ名を選んで「実行」

ボタンに割り当てれば毎回Alt+F8を押さなくて済む。方法は マクロをボタン1つで実行する方法 を参照。

コード(基本版)– SendKeysでVBAProjectにパスワードを設定

VBAProjectのパスワードはオブジェクトモデルから直接設定するAPIが用意されていない。そのため、SendKeys でVBEのダイアログ操作をシミュレートする方法が一般的に使われる。参照設定は不要。


'============================================================
' ■ VBAProjectにパスワードを設定(基本版)
'   → SendKeys でVBEのプロパティダイアログを操作
'   → 参照設定不要。VBA標準機能のみ
'   → 実行後、ブックを保存→閉じる→再度開くとロックが有効
'============================================================
Sub SetVBAProjectPassword()

    '--- ★書き換えポイント ---
    Dim pw As String
    pw = "MyVbaPass123"      '← 設定するパスワード
    '--- ★ここまで ---

    '--- 確認ダイアログ
    If MsgBox("このブックのVBAProjectにパスワードを設定します。" & vbCrLf & vbCrLf & _
              "パスワード:" & pw & vbCrLf & vbCrLf & _
              "設定後、ブックを保存して閉じます。" & vbCrLf & _
              "再度開くとVBAコードがロックされます。" & vbCrLf & vbCrLf & _
              "実行しますか?", vbYesNo + vbQuestion) = vbNo Then
        Exit Sub
    End If

    '--- VBEを開いてプロパティダイアログを表示
    Application.VBE.CommandBars(1).FindControl(ID:=2578, Recursive:=True).Execute

    '--- SendKeysでパスワードを入力
    '    「保護」タブ→チェックボックスON→パスワード入力→確認入力→OK
    SendKeys "^{TAB}"             ' 「保護」タブに移動
    SendKeys " "                  ' チェックボックスをON
    SendKeys "{TAB}"              ' パスワード欄に移動
    SendKeys pw                   ' パスワード入力
    SendKeys "{TAB}"              ' 確認欄に移動
    SendKeys pw                   ' パスワード確認入力
    SendKeys "{ENTER}"            ' OKボタン

    '--- ブックを保存
    Application.OnTime Now + TimeValue("00:00:02"), "SaveAndNotify"

End Sub

Sub SaveAndNotify()
    On Error GoTo ErrHandler
    ThisWorkbook.Save
    MsgBox "VBAProjectにパスワードを設定しました。" & vbCrLf & _
           "ブックを閉じて再度開くとロックが有効になります。", vbInformation
    Exit Sub

ErrHandler:
    MsgBox "保存中にエラーが発生しました:" & vbCrLf & Err.Description, vbExclamation
End Sub

書き換えポイント

変数 説明 初期値
pw VBAProjectに設定するパスワード "MyVbaPass123"

コードの流れ

  1. 確認ダイアログ: パスワードを表示して最終確認
  2. VBEのプロパティダイアログを表示: CommandBarsFindControl でプロパティダイアログを開く
  3. SendKeysで操作: 「保護」タブ→チェックON→パスワード入力→確認入力→OK
  4. ブックを保存: Application.OnTime で2秒後に保存を実行(SendKeysの処理完了を待つため)

ポイント:

  • SendKeys はキー入力をシミュレートするため、実行中にキーボードやマウスを操作すると失敗する
  • VBEへのアクセスには「VBAプロジェクト オブジェクト モデルへのアクセスを信頼する」設定が必要な場合がある
  • パスワード設定後、ブックを閉じて再度開くまでロックは有効にならない

「VBAプロジェクト オブジェクト モデルへのアクセスを信頼する」設定

この設定が無効だと Application.VBE にアクセスした時点でエラーになる。

  1. Excelの「ファイル」→「オプション」→「トラストセンター」→「トラストセンターの設定」
  2. 「マクロの設定」を選択
  3. 「VBA プロジェクト オブジェクト モデルへのアクセスを信頼する」にチェック
  4. 「OK」で閉じる

コード(実務版)– パスワード自動設定+保護レベル比較+配布対応

配布用マクロを作るとき、VBAProjectのパスワード設定に加えて、ブックパスワードの設定やシート保護を組み合わせることが多い。以下のコードは、VBAProjectのパスワード設定に加え、ブックの読み取りパスワードも同時に設定できる実務版。

自分は配布用マクロを作るとき、VBAProjectのパスワードだけでなく、シート保護とブックパスワードも併用するようにしている。この3つを組み合わせることで、「コードを見られない」「シートの構造を壊されない」「ファイル自体の閲覧を制限する」が全部できる。


'============================================================
' ■ VBAProject保護+ブックパスワードの一括設定(実務版)
'   → VBAProjectにパスワードを設定(SendKeys)
'   → ブックに読み取りパスワードを設定(SaveAs)
'   → シート保護も一括適用(Protect)
'   → 配布前の保護作業を1回の実行で完了
'============================================================
Sub ProtectForDistribution()

    '--- ★書き換えポイント ---
    Dim vbaPw As String
    vbaPw = "MyVbaPass123"            '← VBAProjectのパスワード

    Dim bookPw As String
    bookPw = ""                        '← ブックの読み取りパスワード(不要なら "")

    Dim sheetPw As String
    sheetPw = "SheetPass456"           '← シート保護のパスワード(不要なら "")

    Dim protectSheets As Boolean
    protectSheets = True               '← シート保護を適用するか

    Dim savePath As String
    savePath = ""                      '← 別名保存先("" なら上書き保存)
    '--- ★ここまで ---

    '--- 確認ダイアログ
    Dim msg As String
    msg = "以下の保護を設定します。" & vbCrLf & vbCrLf
    msg = msg & "■ VBAProject保護:" & IIf(vbaPw <> "", "ON(パスワード設定)", "OFF") & vbCrLf
    msg = msg & "■ ブックパスワード:" & IIf(bookPw <> "", "ON", "OFF") & vbCrLf
    msg = msg & "■ シート保護:" & IIf(protectSheets, "ON(全シート)", "OFF") & vbCrLf
    msg = msg & vbCrLf & "実行しますか?"

    If MsgBox(msg, vbYesNo + vbQuestion) = vbNo Then
        Exit Sub
    End If

    On Error GoTo ErrHandler

    '--- ① シート保護(VBAProjectロック前に実行)
    If protectSheets And sheetPw <> "" Then
        Dim ws As Worksheet
        For Each ws In ThisWorkbook.Worksheets
            '--- 既に保護済みなら一度解除してから再設定
            If ws.ProtectContents Then
                ws.Unprotect Password:=sheetPw
            End If
            ws.Protect Password:=sheetPw, _
                       UserInterfaceOnly:=True, _
                       AllowFiltering:=True, _
                       AllowSorting:=True
        Next ws
    End If

    '--- ② VBAProjectパスワード設定(SendKeys)
    If vbaPw <> "" Then
        Application.VBE.CommandBars(1).FindControl(ID:=2578, Recursive:=True).Execute
        SendKeys "^{TAB}"
        SendKeys " "
        SendKeys "{TAB}"
        SendKeys vbaPw
        SendKeys "{TAB}"
        SendKeys vbaPw
        SendKeys "{ENTER}"
    End If

    '--- ③ ブックパスワード設定+保存
    Application.DisplayAlerts = False

    If savePath <> "" Then
        '--- 別名保存
        ThisWorkbook.SaveAs Filename:=savePath, _
                            FileFormat:=xlOpenXMLWorkbookMacroEnabled, _
                            Password:=bookPw
    ElseIf bookPw <> "" Then
        '--- 上書き保存(パスワード付き)
        ThisWorkbook.SaveAs Filename:=ThisWorkbook.FullName, _
                            FileFormat:=ThisWorkbook.FileFormat, _
                            Password:=bookPw
    Else
        '--- 通常の上書き保存
        ThisWorkbook.Save
    End If

    Application.DisplayAlerts = True

    '--- 結果通知
    Dim result As String
    result = "保護設定が完了しました。" & vbCrLf & vbCrLf
    If vbaPw <> "" Then result = result & "✓ VBAProjectにパスワードを設定" & vbCrLf
    If bookPw <> "" Then result = result & "✓ ブックに読み取りパスワードを設定" & vbCrLf
    If protectSheets Then result = result & "✓ 全シートに保護を適用" & vbCrLf
    result = result & vbCrLf & "VBAProjectのロックはブックを閉じて再度開くと有効になります。"

    MsgBox result, vbInformation
    Exit Sub

ErrHandler:
    Application.DisplayAlerts = True
    MsgBox "エラーが発生しました:" & vbCrLf & Err.Description, vbExclamation

End Sub

書き換えポイント

変数 説明 初期値
vbaPw VBAProjectのパスワード "MyVbaPass123"
bookPw ブックの読み取りパスワード(不要なら "" ""(設定しない)
sheetPw シート保護のパスワード(不要なら "" "SheetPass456"
protectSheets シート保護を適用するか True
savePath 別名保存先パス("" なら上書き保存) ""(上書き保存)

コードの流れ

  1. 確認ダイアログ: 設定する保護の内容を一覧表示して最終確認
  2. シート保護: 全シートに Protect を適用。UserInterfaceOnly:=True でVBAからの操作は許可
  3. VBAProjectパスワード: SendKeys でプロパティダイアログを操作
  4. ブックパスワード設定+保存: SaveAsPassword 引数でブックパスワードを同時設定
  5. 結果通知: 設定した保護の内容を一覧表示

保護レベルの比較

保護の種類 何を守るか 設定方法 解除の難易度
VBAProjectパスワード VBAコードの閲覧・編集 VBEのプロパティ 低(解析ツールで突破可能)
ブック読み取りパスワード ファイルを開くこと自体 SaveAs Password:= 中(ブルートフォースで突破される可能性)
ブック書き込みパスワード ファイルの編集・保存 SaveAs WriteResPassword:=
シート保護 セルの編集・構造の変更 ws.Protect Password:= 低(解析ツールで突破可能)

結論: VBAProjectのパスワードとシート保護は「善意のユーザーによる誤操作を防ぐ」レベル。悪意を持った人が本気で解析すれば突破できる。機密性が高い場合は、ファイル自体のアクセス制御(フォルダのアクセス権限設定やDRM)を併用すること。

VBAProject保護の限界について(正直な話)

ここは正直に書いておく。VBAProjectのパスワード保護は完全な保護ではない

解析ツールで突破できる

インターネット上には、VBAProjectのパスワードを解析・除去するツールが存在する。バイナリエディタで .xlsm ファイル内の特定バイトを書き換えるだけでパスワードを無効化できる。

つまり何のために設定するのか

  • 善意のユーザーによる誤操作防止: 「ちょっと中身を見てみよう」でコードを壊されるのを防ぐ
  • カジュアルな改変抑止: パスワードがかかっていると、ほとんどの人はそれ以上触らない
  • プロ意識の表現: 「配布用マクロにはパスワードをかける」のが実務の基本作法

本気で守りたい場合の選択肢

  1. COM アドイン化: VBAコードをDLLに変換して配布する。VBAコードは配布先に存在しない
  2. フォルダのアクセス権限: Windowsのファイルシステム権限でアクセスを制限する
  3. 情報漏洩防止(DLP)製品: 企業レベルのセキュリティが必要な場合

自分の経験では、VBAProjectのパスワードだけで社内配布の99%のケースは問題なく運用できている。「絶対に見られたくない」ロジックがある場合だけ、COMアドイン化を検討すればよい。

配布時の注意点

マクロ有効ブック(.xlsm)で配布する

.xlsx にはVBAコードが保存できない。必ず .xlsm 形式で配布する。

マクロのセキュリティ設定を案内する

受け取った人のExcelで「マクロを有効にする」操作が必要。配布時に以下を伝えておく:

  • ファイルを開いたら画面上部に「セキュリティの警告」が表示される
  • 「コンテンツの有効化」をクリックするとマクロが使える

パスワードをコード内にハードコードしない(配布版)

配布するファイルのコード内にパスワード文字列が残っていると、VBAProjectのパスワードを解除された場合にパスワードが見えてしまう。配布前にコード内のパスワード文字列を削除するか、パスワード設定用のコードは別のマクロブックで実行する。

参照設定と実行時バインディングの使い分けについては 参照設定と実行時バインディング(CreateObject)の使い分け方 を参照。

よくある落とし穴5選

1. パスワード設定後に保存せず閉じてしまった

原因: VBAProjectのパスワードは、ブックを保存して初めてファイルに反映される。保存せずに閉じると、パスワード設定が破棄される。

対策: パスワード設定後は必ず Ctrl + S で保存する。実務版コードでは設定後に自動保存を行っている。

2. SendKeysが効かない・タイミングがずれる

自分もこれで30分溶かした。SendKeysを実行したのにダイアログが正しく操作されず、パスワードが設定されなかった。原因はPCの処理速度。ダイアログの表示が完了する前にSendKeysが発行されていた。

対策: Application.OnTime で少し待ってから保存する。環境によっては DoEventsApplication.Wait を挟む必要がある。

3. 「VBAプロジェクト オブジェクト モデルへのアクセスを信頼する」が無効

原因: この設定が無効だと Application.VBE にアクセスした時点で「実行時エラー 1004」が発生する。

対策: Excelの「トラストセンター」→「マクロの設定」で有効にする。企業のPCではIT部門のポリシーで変更できない場合がある。その場合は手動設定(手順1)で対応する。

4. VBAProjectのパスワードとブックパスワードを混同する

原因: VBAProjectのパスワードは「コードの閲覧・編集を制限」するもの。ブックパスワードは「ファイルを開くこと自体を制限」するもの。両者は完全に別物。

対策: 保護レベルの比較表を参照。用途に応じて使い分ける。ブックのパスワード設定は ブックにパスワードを自動で設定・解除する方法 を参照。

5. 配布先で「マクロが無効」になってしまう

原因: 受け取った人のExcelでマクロが無効化されている。VBAProjectのパスワードとは無関係の問題。

対策: 配布時に「コンテンツの有効化」の操作方法を案内する。企業環境では、信頼できる場所(Trusted Location)にファイルを配置する運用が一般的。

VBAでSendKeysによるパスワード設定が効かないときの対処法

「SendKeysを実行したのにダイアログが正しく操作されない」場合、PCの処理速度によってダイアログの表示完了前にキー送信が走っていることが原因だ。Application.Wait Now + TimeValue("00:00:01")で1秒待ってからSendKeysを実行するか、Application.OnTimeで遅延実行しよう。

VBAProjectの保護でVBEが開けなくなったときの対処法

「パスワードを設定したがパスワードを忘れてしまった」場合、VBEからVBAProjectを開けなくなる。パスワード設定前のバックアップファイルがあればそこから復元するのが最も確実だ。パスワード設定の前にはブックのバックアップを必ず取っておこう。

FAQ

Q1: VBAProjectのパスワードを解除するには?

VBEで対象の VBAProject を右クリック →「VBAProject のプロパティ」→「保護」タブ →「プロジェクトを表示用にロックする」のチェックを外す → パスワードを空にして「OK」→ ブックを保存。


' SendKeysでパスワード解除する場合
Sub RemoveVBAProjectPassword()
    Application.VBE.CommandBars(1).FindControl(ID:=2578, Recursive:=True).Execute
    SendKeys "^{TAB}"         ' 「保護」タブに移動
    SendKeys " "              ' チェックボックスをOFF
    SendKeys "{TAB}"          ' パスワード欄(空のまま)
    SendKeys "{TAB}"          ' 確認欄(空のまま)
    SendKeys "{ENTER}"        ' OK
    Application.OnTime Now + TimeValue("00:00:02"), "SaveAndNotify"
End Sub

Q2: .xlsb(バイナリ形式)でもVBAProjectの保護はできる?

できる。手動設定の手順は .xlsm と同じ。VBAからの自動設定も同じコードで動作する。.xlsb はファイルサイズが小さく処理が速いため、大量データを扱うマクロブックでは .xlsb 形式が有利。

Q3: VBAProjectのパスワードを忘れた場合の対処法は?

正規の方法ではパスワードをリセットできない。インターネット上には解析ツールが存在するが、利用は自己責任。バックアップファイルがあればそちらを使うのが最善。パスワードは必ず記録しておくこと。

Q4: 複数のブックにまとめてVBAProjectパスワードを設定したい

Workbooks.Open で各ブックを開いてから SendKeys で設定する方法は技術的には可能だが、SendKeys のタイミング制御が難しく安定しない。複数ブックへの一括設定は手動で行うか、VBAプロジェクトをテンプレートブックに作成しておいて配布する方がよい。

Q5: VBAProjectの保護とシート保護は両方かけるべき?

配布用マクロの場合は両方かけるのがおすすめ。VBAProjectの保護はコードの改変を防ぎ、シート保護はセル構造の破壊を防ぐ。シート保護の詳細は 特定シートだけ保護・解除する方法 を参照。

まとめ

この記事で、VBAProjectにパスワードを設定してコードを保護できるようになった。

  • 手動設定: VBEの「VBAProject のプロパティ」→「保護」タブでパスワード設定
  • VBA自動設定: SendKeys でダイアログ操作をシミュレート
  • 実務版: VBAProject保護 + ブックパスワード + シート保護を一括設定

重要:VBAProjectのパスワード保護は「善意のユーザーによる誤操作防止」が目的。解析ツールで突破される可能性がある点は理解しておくこと。

関連記事

次にやりたくなること

もっとカスタマイズしたい場合

「配布先の環境に応じて保護レベルを切り替えたい」「COMアドイン化でコードを完全に隠蔽したい」「パスワードをExcelの管理シートから読み込んで設定したい」など、業務に合わせたカスタマイズが必要な場合は、ココナラで相談できます。

相談時に以下の情報があるとスムーズです:

  • Excel のバージョン / OS
  • 配布対象(社内 / 社外 / 顧客)
  • 保護したい範囲(VBAコード / シート構造 / ファイル自体)
  • 配布するファイルの形式と数

コメント

タイトルとURLをコピーしました