TL;DR —
ws.Visible = xlSheetHiddenでシートが非表示になり、xlSheetVisibleで再び表示されます。三つ目の状態xlSheetVeryHiddenもあり、これはシートを「再表示」ダイアログから消すので、コードか VBA エディターからしか元に戻せません。三つのどれも変えるのは ユーザーに見えるものであって、シートそのものではありません。非表示のシートも計算を続け、それを指すすべての数式に値を供給し、コードからは完全に読み書きできます。Excel は最後の表示シートを隠すことを拒否し(エラー 1004)、非表示のシートをSelectすることはできません — そもそもその必要はありません。シートを隠すのはブックを整理するためです。中身を秘密にしなければならないなら、それはファイルに入れておくべきものではありません。
Sub HideHelperSheets()
With ThisWorkbook
.Worksheets("Lookups").Visible = xlSheetHidden ' ユーザーは右クリックで再表示できる
.Worksheets("Config").Visible = xlSheetVeryHidden ' 「再表示」ダイアログに表示されない
End With
End Sub
これは、シートの「身元」を扱う三部作の第二回です。シート見出しの名前は、ユーザーが持ち主のラベルです。リネーム はそのラベルを変え、ここで扱う 非表示 はシートに手が届く状態のまま見出しを画面から消し、シートの存在確認 はその名前が使われているかを確かめます。三つを貫く軸はこうです。シート見出しの並びは Sheets コレクションの ビュー にすぎません。非表示はビューを編集するだけで、コレクションは変わりません。
この記事で学べること
- 考え方の軸:非表示はブックではなくビューを編集する
Visibleの三つの状態と、それぞれで何ができるか- 二つのエラー:最後の表示シートと、非表示シートの選択
- 非表示のシートを一度も表示せずに操作する方法
- すべてのシートを一つのループで再表示する方法と、一枚だけ残してすべて隠す方法
- 非表示も完全非表示もセキュリティにならない理由と、代わりにすべきこと
考え方の軸:非表示はビューを編集する
ブックのシートは Sheets コレクションの中にあります。画面下のシート見出しの並びはそのコレクションの ビュー であり、非表示はビューから見出しを一つ取り除くだけです — それ以外は何も変えません。シートはコレクション内の位置、インデックス、名前、数式、データをすべて保ったままです。ですから:
=Lookups!B2のような数式は、Lookupsが非表示でも動き続けます。Worksheets.Countは非表示のシートも数えますし、Worksheets(2)が非表示のシートであることも十分ありえます。Worksheetsを回す For Each ループは非表示のシートも訪れます。- コードはそのセルを以前とまったく同じように読み書きできます。
だからこそ、非表示はヘルパーシート — 参照用の表、設定、作業用のデータ — には正しい道具であり、守る必要があるものには間違った道具なのです。列の非表示 のシート版と考えてください。表示はゼロ、存在は完全にそのままです。
Visible の三つの状態
Visible は三つの XlSheetVisibility 定数のいずれかを取ります。
| 定数 | 値 | 見出しの表示 | 「再表示」ダイアログ | 再表示できるのは |
|---|---|---|---|---|
xlSheetVisible |
-1 | あり | — | — |
xlSheetHidden |
0 | なし | 表示される | 誰でも(右クリック >「再表示」) |
xlSheetVeryHidden |
2 | なし | 表示されない | コード、または VBA エディターのプロパティウィンドウ |
ws.Visible = False でも動き、xlSheetHidden と同じ意味になりますが、定数で書きましょう。True と False では三つ目の状態を表現できませんし、読む人に False が 0 であることを覚えさせるべきではありません。
自分で作るツールで役に立つのは 完全非表示 のほうです。ユーザーにはシートが一覧されないので、好奇心で設定シートを再表示して、うっかり書き換えてしまうことがありません。コードを使わずに設定するには、VBA エディターのプロジェクトエクスプローラーでシートを選び、プロパティウィンドウで Visible を変更します。
必ず出会う二つのエラー
最後の表示シートを隠す。 ブックは常に少なくとも一枚のシートを表示していなければなりません。唯一の表示シートを隠すと、実行時エラー 1004 Unable to set the Visible property of the Worksheet class が起きます。完全非表示と非表示のシートは数に入らないので、表示シート一枚と非表示シート十枚のブックでも拒否されます。ループでシートを隠すときは、表示のまま残すべきシートがループの開始 前に 表示されていることを確かめましょう。
非表示のシートを選択する。 非表示のシートに対する Worksheets("Lookups").Select はエラー 1004 を起こします。そのシート上の範囲を選択する場合も同じです。解決策は先に再表示することではありません — そもそも選択しないことです。
' 誤り: 書き込むために非表示のシートを選択する
' Worksheets("Lookups").Select
' Range("A1").Value = "更新済み"
' 正しい: 参照を通して書き込む。シートは非表示のまま
ThisWorkbook.Worksheets("Lookups").Range("A1").Value = "更新済み"
表示されているシートでもこちらのほうが良い習慣である理由は、Select と Activate のガイド で説明しています。もう一つ、まれな三つ目のエラーがあります。ブックの 構成 が保護されていると(ブックの構成の保護)、どのシートの Visible プロパティを変更しても、ブックに対して Unprotect を呼ぶまで失敗します。
すべてのシートを再表示する、一枚だけ残して隠す
「再表示」ダイアログに表示できるのは xlSheetHidden のシートだけです。完全非表示のシートも含めてすべてを戻すには、Sheets コレクションをループします — Worksheets ではなく Sheets を使うので、グラフシートも戻ってきます。
Sub UnhideAllSheets()
Dim sh As Object
For Each sh In ThisWorkbook.Sheets
sh.Visible = xlSheetVisible
Next sh
End Sub
逆の操作 — ダッシュボードを一枚だけ見せて他をすべて隠す — は最後の表示シートのルールを守る必要があるので、順序が重要です。残すシートを先に表示してから、残りを隠します。
Sub ShowOnly(keep As Worksheet)
Dim sh As Object
keep.Visible = xlSheetVisible ' 最初に実行し、表示シートが常に一枚あるようにする
For Each sh In keep.Parent.Sheets
If Not sh Is keep Then sh.Visible = xlSheetVeryHidden
Next sh
keep.Activate
End Sub
keep.Parent はそのシートが属するブックなので、このルーチンはコードを持つブックだけでなく、開いているどのブックでも動きます。
判断の分かれ目:非表示は見せ方であって、セキュリティではない
完全非表示を鍵のように扱いたくなりますが、鍵ではありません。誰でも Alt+F11 で VBA エディターを開き、プロジェクトエクスプローラーで完全非表示のシートを見つけ、表示に戻せます。VBA プロジェクトをパスワードでロックすれば一般のユーザーにはその扉が閉じ、ブックの構成を保護すれば右クリックの「再表示」も止められます — それでもデータはファイルの中にあります。.xlsx ファイルを直接読むツールは、Power Query から Python スクリプトまで、Visible プロパティに関係なくすべてのシートを読みますし、非表示のシートは送ったブックのすべてのコピーに付いていきます。
私のルール:散らかりを減らし事故を防ぐために隠す。秘密を守るためには削除する。 ユーザーに踏み込んでほしくない設定には完全非表示を使い、「再表示」メニューをグレーアウトしたければブックの構成の保護を加え、給与の表、原価、認証情報を非表示のシートに入れて配布することは決してしないでください。受け取る相手に見せてはいけないなら、送るコピーから削除しましょう — 確認メッセージを出さずに削除する方法は シートの削除のガイド で紹介しています。
ExcelMaster の活用
表示状態のバグは静かです。ユーザーが他のシートをすでに隠していたときにだけエラー 1004 で止まるマクロ、非表示のシートを選択して一台のパソコンでだけ失敗するレポート、ブックの中に入ったまま顧客に届いてしまった「秘密の」価格シート。
ExcelMaster には、やりたいことをそのまま伝えられます — 「Dashboard シートだけを表示して、設定用のシートは完全非表示にし、ブックの構成を保護して」 — すると、最後の表示シートのルールに決して引っかからない順序で表示状態のコードを書き、非表示のシートは選択せずに参照を通して操作してくれます。
よくある質問
VBA でシートを非表示にするには?
Visible プロパティを設定します。Worksheets("Data").Visible = xlSheetHidden です。ユーザーは右クリック >「再表示」で元に戻せます。「再表示」ダイアログにまったく表示させたくないなら xlSheetVeryHidden を、再び表示するには xlSheetVisible を使います。
非表示と完全非表示の違いは何ですか?
非表示のシートは「再表示」ダイアログに表示されるので、どのユーザーでも元に戻せます。完全非表示のシートはそこに表示されず、コードか VBA エディターのプロパティウィンドウからしか再表示できません。どちらも計算は続き、どちらもコードから完全に操作できます。
VBA ですべてのシートを再表示するには?
For Each で Sheets コレクションをループし、すべてのシートに sh.Visible = xlSheetVisible を設定します。これで、「再表示」ダイアログでは戻せない完全非表示のシートとグラフシートも元に戻ります。
シートを非表示にするとエラー 1004 が出るのはなぜですか?
多くの場合、それが最後の表示シートだからです。ブックは常に少なくとも一枚のシートを表示していなければなりません。先に別のシートを表示しましょう。もう一つの原因はブックの構成の保護で、ブックの保護を解除するまでシートの表示状態は一切変更できません。
VBA は非表示のシートを読み書きできますか?
できます。非表示は見出しを画面から消すだけなので、Worksheets("Data").Range("A1").Value は非表示のシートでも同じように動きます。失敗するのは Select や Activate ですが、これらは必要ありません。参照を通して書き込めば、シートは非表示のままです。
検証環境
検証環境: Excel 365 (Windows 11)、VBA 7.1 — 最終確認 2026-09-30。
関連ガイド: VBA シート名の変更 · VBA シートの存在確認 · VBA 列の非表示 · VBA Worksheets · VBA シートの削除 · VBA シートの保護 · VBA Select と Activate · VBA For Each
