🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

Excel VBA で列・行を非表示にする — 非表示は削除ではない(なぜ合計が変わらないのか)

|

Excel VBA で列・行を非表示にする — 非表示は削除ではない(なぜ合計が変わらないのか)

TL;DR — 非表示は 3 つの構造変更の中でいちばん穏やかで、いちばん誤解されています。 削除(行を取り除く)や挿入(行を足す)と違い、非表示はデータについては何も変えません — 列や行の表示サイズをゼロにするだけです。セルはそのまま残り、すべての SUM に含まれ、 範囲をコピーすれば一緒にコピーされ、コードからは完全に編集できます。.Hidden = True は 迷子のセルではなく .EntireColumn.EntireRow に属します。誰もがはまる罠 — 列を 非表示にしても合計からは外れませんSUM(B:B) は非表示の B 列も足します。見せる ための非表示です。計算から何かを外したいなら、それは削除・フィルター・SUBTOTAL で あって、非表示ではありません。

' 補助列 B:D を隠し、Status が "Done" の行をすべて隠す。
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Report")

ws.Columns("B:D").Hidden = True                 ' 列全体を 1 文で
ws.Rows("2:1000").EntireRow.Hidden = False      ' まず全行を表示状態にし、そこから選んで隠す
Dim i As Long
For i = 2 To 1000
    ws.Rows(i).Hidden = (ws.Cells(i, "Status").Value = "Done")
Next i

非表示は 3 つの操作の中でいちばん簡単そうで、仕組みの上では実際そうです — たった 1 つの Boolean プロパティです。それでも記事にする価値があるのは考え方のためです。 「非表示」は、多くの人が思うのとは静かに違う意味を持つからです。人はデータを除外する ために — 表示から、合計から、コピーから — これに手を伸ばしますが、非表示がやるのは そのうち最初の 1 つだけです。そこを正すのが戦いのすべてで、構文は 1 行ほどで済みます。

この記事で学べること

  • 考え方の軸 — 非表示はサイズをゼロにする。データを取り除いたり除外したりはしない
  • なぜ .Hidden.EntireColumn.EntireRow に属するのか
  • 誰もがはまる罠 — 非表示のセルも数式やコピーでは数えられる
  • 再表示 — 忘れられがちな片割れと、動かないシートを救う 1 行
  • ループ時、手動で隠した行と AutoFilter で隠れた行の違い

考え方の軸:非表示は幅ゼロであって、消えたのではない

削除は行を取り除き、挿入は行を足します。非表示はそのどちらでもありません — 既存の行や 列を取り、その高さや幅をゼロにして画面に描かれないようにするだけです。ほかはすべて 変わりません。データはあった場所に、まったく同じアドレスのまま座っています。 Range("B2") は非表示の B 列の値を何事もなく読み書きします。非表示の行は変装した 削除済みの行ではありません — 完全に存在する行に、ただ「描かないで」と Excel に伝えた だけです。

だから非表示は構造的な構造変更なのです。変えるのは表示であって、グリッドでは ありません。6 行目は非表示でも 6 行目のまま。何も上へ詰まらず、何も下へずれないので、 ここにはループの向きの罠はありません — 普通の上から下へのループで一日中でも 非表示・再表示できます。難しさはどう隠すかにあるのではなく、データがどこかへ行ったと 信じてしまうことにあります。行ってなどいません。

構文のルール:.Hidden は列全体・行全体に属する

Hidden は列全体または行全体のプロパティで — 任意のセルやブロックのものでは ありません。B2:B10 は非表示にできません。そのセルが属する列や行を非表示にするのです。 ですから列/行全体を直接指すか、.EntireColumn.EntireRow でセル範囲を昇格させます。

ws.Columns("B").Hidden = True                 ' B 列を隠す
ws.Columns("B:D").Hidden = True               ' B・C・D を隠す
ws.Rows("10:20").Hidden = True                ' 10 行目から 20 行目までを隠す
ws.Range("B2:D2").EntireColumn.Hidden = True  ' セル範囲をその列全体に昇格させる

部分範囲に .Hidden を設定しようとすると、エラーになるか、意図より多くを隠すかの どちらかです。このプロパティはそもそもセル単位では定義されていないからです。 .EntireColumn.EntireRow は、削除や挿入で使うのと同じ昇格です — 「これらのセル」 から「それが属する列/行全体」へ連れていく、あの繰り返し出てくる一手です。

誰もがはまる罠:非表示のセルも数えられる

これが本物のバグを生む思い込みです。列を非表示にすれば合計から外れる。外れません。 非表示は表示の設定であって、計算には何の影響もありません。=SUM(B:B) は非表示の B 列を 含みます。=SUM(A2:A100) はその範囲の非表示の行をすべて含みます。非表示の列をまたぐ 範囲をコピーすれば、非表示の値も貼り付けに付いてきます。非表示の系列をグラフにすると — 指示しない限り — 消えるかもしれないし、消えないかもしれません。非表示が変えるのは人間が 見るもので、数式やコピーがすることはほとんど変えません。

ですから本当の目的が「これらの値を合計から外す」なら、非表示は間違った道具で、これに 手を伸ばすと、数字が見えている行と合わないレポートができます。正しい道具はこちらです。

  • SUBTOTAL(109, ...) または AGGREGATE — これらはフィルターで隠れた行を本当に 無視します(SUBTOTAL(109) は手動で隠した行も無視します)。だからフィルターするたびに 集計が更新されます。
  • AutoFilter — 隠し、かつ SUBTOTAL から除外します。「一致する行だけを見せて合計 する」正直なやり方です。
  • 削除 — データが本当に存在すべきでないなら、取り除きます (VBA 行の削除を参照)。

.Hidden は、データが残るべきで、計算にも残るべきで、ただ視界を散らかしたくないときに 使いましょう — ダッシュボードの裏の補助列、印刷サマリーの脇の作業行など。それが非表示の 本来の用途です。

再表示:忘れられがちな片割れと、救いの 1 行

すべての非表示には対になる再表示が必要で、バグはより広い選択が再表示を担うべきだと 忘れることです。B 列が非表示で、あなたが Columns("B") しか触らないなら、あなたのマクロを 一度も実行しないユーザーは手作業では簡単に戻せません — 隙間をまたいで選択しなければ なりません。コードでの確実な救いは、広めの範囲、あるいはシート全体にわたって再表示する ことです。

ws.Columns("A:Z").Hidden = False   ' A:Z の中で隠れている列をすべて再表示する
ws.Rows("1:1000").Hidden = False   ' その範囲で隠れている行をすべて再表示する
ws.Cells.EntireColumn.Hidden = False   ' 最終手段。シート上のすべての列を再表示する
ws.Cells.EntireRow.Hidden = False       ' …そしてすべての行も

ws.Cells.EntireColumn.Hidden = False が覚えておくべき 1 行です — どの列が誰に隠されて いようと、すべてを再表示します。もう 1 つ知っておく価値のある区別。 Columns("B").ColumnWidth = 0 に設定しても列は見えなくなりますが、それは .Hidden = True同じではありません.Hidden が本物のプロパティで、往復しても きれいに残り、UI の「再表示」が切り替えるのもこれです。.Hidden を使いましょう。幅ゼロの べた書きは、テクニックではなく直すべきバグとして扱いましょう。

非表示の行とフィルターの行:同じフラグ、ループでは別物

手動で隠した行も AutoFilter で隠れた行も、どちらも .Hidden = True を返します。だから If ws.Rows(i).Hidden をテストするループには両者の区別がつきません — 「ユーザーに 見えている行だけ」を対象にしたいときに、これが効いてきます。可視セルをきれいにつかむ 方法は SpecialCells です。

' 現在表示されている行だけをループする(手動で隠した行もフィルターで隠れた行も飛ばす)。
Dim rng As Range, area As Range
On Error Resume Next
Set rng = ws.Range("A2:A1000").SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If Not rng Is Nothing Then
    For Each area In rng.Areas          ' 可視セルは複数のブロックに分かれて返る
        ' … area を処理する …
    Next area
End If

体に叩き込むことが 2 つ。第一に、SpecialCells(xlCellTypeVisible) は可視セルを 複数の領域として返します(途切れない可視行のひと続きが 1 領域)。だから単一の連続 ブロックではなく .Areas を反復します。第二に、素の For i = 2 To 1000 ループは、 ほかのどの行とも同じように非表示・フィルターの行も訪れます — 非表示は行を反復から外す のではなく、視界から外すだけです。「画面上の行」を意味したいなら、可視セルを明示的に 求めましょう。ループが非表示の行を飛ばすと当てにしてはいけません。

ExcelMaster の活用

非表示が人をつまずかせるのは構文ではなく思い込みです。頑として非表示の列を含む合計、 再表示の範囲が狭すぎて誰も動かせなくなったシート、.Hidden が思ったとおりの意味で なかったせいでフィルター除外された行を処理するループ。直し方はどれも小さく、どれも 見落としやすいのです。

ExcelMaster なら、 意図を説明するだけです — 「補助列の B から D を隠して」「Done の付いた行をすべて隠して」 「合計は表示されている行だけで」。.EntireColumn.Hidden.EntireRow.Hidden を正しく 書き、単に「隠す」ではなく本当に「計算から外す」を意味するときは SUBTOTALSpecialCells(xlCellTypeVisible) に手を伸ばし、どのシートも詰まらないよう「すべて再表示」 の道を用意します。ブックもコードもあなたの手元に残り、目に見えているものを無視する合計、 という驚きを飛ばせます。

よくある質問

VBA で列を非表示にするには?

列全体に .Hidden = True を設定します。ws.Columns("B").Hidden = True、複数なら ws.Columns("B:D").Hidden = True。セル範囲からは、まず昇格させます。 ws.Range("B2:D2").EntireColumn.Hidden = True.Hidden は列全体または行全体のプロパティ なので、部分範囲には適用できません。

Excel で列を非表示にすると SUM から外れる?

いいえ。非表示は表示を変えるだけです — =SUM(B:B) は非表示の B 列を含み、範囲をコピー すれば非表示の値もコピーされます。セルを合計から外すには、SUBTOTAL(109, ...)AGGREGATE(フィルターで隠れた行を、109 なら手動で隠した行も無視します)を使うか、 AutoFilter をかけるか、データを削除します。非表示は表示であって計算ではありません。

VBA ですべての列と行を再表示するには?

ws.Cells.EntireColumn.Hidden = False ですべての列を、ws.Cells.EntireRow.Hidden = False ですべての行を再表示します。シート全体を対象にするので、どの列や行が隠されていようと 効きます — 隠れたものを手作業で見つけられないシートの、確実な救いです。

セルの値に応じて行を非表示にするには?

行をループし、テストから .Hidden を設定します。 ws.Rows(i).Hidden = (ws.Cells(i, "C").Value = "Done")。非表示はグリッドをずらさないので、 普通の上から下へのループで大丈夫です — 削除のときのように逆順にする必要はありません。 以前に隠した行がリセットされるよう、全表示の状態から始めましょう。

ループがまだ非表示の行を処理するのはなぜ?

行を非表示にしても反復からは外れないからです — For i = 2 To 1000 ループは、 非表示・フィルターの行も可視行と同じように訪れます。画面上のものだけを対象にするには、 Range(...).SpecialCells(xlCellTypeVisible) で可視セルを取得し、その .Areas を反復 します。手動の .Hidden テストでは、フィルターで隠れた行と手動で隠した行を区別できません。

検証環境

動作確認: Excel 365 (Windows 11), VBA 7.1 — 最終確認 2026-08-07。

関連ガイド: VBA Delete Rows · VBA Insert Rows and Columns · VBA Range · VBA For Loop · VBA Last Row