TL;DR —
Columns("B:D").Groupは B 列から D 列を、シート上部を横切る 水平のアウトライン の 裏に畳み込みます — 行のグループ化 を 90 度回転させただけの、同じ畳み方で す。列ならではのつまずきが二つあります。折りたたみボタンは既定ではグループの 右側 に付き (Outline.SummaryColumn)、そしてグループ化が効くのは 列全体 に対してだけで、部分的な範囲では 列はグループ化されません。
Sub GroupMonthColumns()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Report")
ws.Cells.ClearOutline ' フラットな状態から始め、再実行してもレベルが積み重ならないようにする
ws.Outline.SummaryColumn = xlSummaryOnLeft ' ボタンを左側にある合計列に付ける
ws.Columns("C:N").Group ' 12 か月分の列を B 列の合計の裏に畳み込む
ws.Outline.ShowLevels ColumnLevels:=1 ' 列だけを折りたたみ、行のグループはそのままにする
End Sub
列のグループ化は、行のグループ化を別の軸で行ったものです。同じ .Group という動詞、裏で動いている同じ
アウトラインオブジェクト、レベルで折りたたむという同じルール。列で変わるのは、
ボタンが既定でどちら側に付くかということと、「列」が 列全体 を意味するという点です — 構造編集におけ
る「部分的な範囲ではなく EntireColumn を挿入する」というルールと、まっ
たく同じ響きです。
この記事で学べること
- 考え方の軸 — 水平方向の畳み方で、行のアウトラインを 90 度回転させたもの
- 集計列の罠 — なぜボタンが右側に付くのか、そしてどうやって左に動かすか
- なぜグループ化には 列全体 が必要で、部分的な範囲を渡すと代わりに何が起きるのか
ShowLevelsが行のグループとは独立して、列だけをその軸で折りたたむ仕組み- 列をグループ化することが、隠すことや幅を変えることと同じではない理由
考え方の軸:水平方向の畳み方
Columns("B:D").Group は、シートの 上部を横切る アウトラインバーを作ります。− ボタンをクリックす
ると B 列から D 列が視界の外に畳まれ、+ で元に戻ります。これは行のアウトラインを 90 度回転させたもの
です — 行のブロックを左の余白に畳み込む代わりに、列のブロックを上部のバーに畳み込みます。
行のグループ化 について成り立つことは、ここでもすべて成り立ちます。列は
畳まれる だけで、.Hidden の意味で隠されるわけでも削除されるわけでもありません。アウトラインは最大
8 レベルまで列を整理し、.Hidden をいじるのではなくレベルで折りたたみます。この記事が扱うのは、軸が列
になったときに特有の、二つの違いです。
集計列の罠:ボタンは右側に付く
B 列から D 列をグループ化しても、折りたたみボタンはグループの上ではなく、その 右側 の E 列の上に
現れます。これは Worksheet.Outline.SummaryColumn の既定値が xlSummaryOnRight だからです。Excel は、
集計列や合計列が集計対象の詳細の 右 にあるものと決めてかかります。
これは集計行の既定値の鏡像であり、よくあるレイアウト — 月別の詳細が並ぶ前に 左側 に置かれた合計列 — では、まったく同じ理由で間違っています。
ws.Outline.SummaryColumn = xlSummaryOnLeft ' ボタンを左側にある合計列に付ける
ws.Columns("C:N").Group ' 合計は B 列、詳細は C 列から N 列
既定のままにしておくと、+ は最後の月の右側に浮いてしまい、読み手が見ている B 列の合計から切り離され
てしまいます。SummaryColumn は シート単位 の設定です — アウトラインを組み立てる前に一度だけ設定
し、合計がどちら側にあるかに合わせましょう。定数の綴りが行のバージョンとは違う点に注意してください。列
では xlSummaryOnLeft / xlSummaryOnRight、行では xlSummaryAbove / xlSummaryBelow を使います。
列全体をグループ化する、部分的な範囲では決して行わない
列のグループ化が意味を持つのは、列全体 を指定したときだけです。
ws.Columns("B:D").Group ' 三つの列全体を畳み込む
ws.Range("B:D").EntireColumn.Group ' 同じ意味を明示的に書いた形
.Group に部分的な範囲を渡すと、列は畳まれません。
ws.Range("B2:D2").Group ' B-D 列はグループ化されない
列全体でない範囲は列のグループにはなれません — シートの状態によっては実行時エラーになったり、意図しな
いグループ化になったりします。これは挿入や削除を支配しているのと同じルールです。列 に対して操作した
いなら 列 を指定する(Columns(...) か .EntireColumn)、EntireColumn を挿入する
のと同じ規律です。見出しセルがあってその列が必要なときは、先に列全体まで広げましょう。
ws.Rows(1).Find("Q1", LookAt:=xlWhole).EntireColumn.Group ' 見出しを見つけ、その列全体をグループ化する
ShowLevels は列をその軸だけで折りたたむ
アウトラインは行と列を二つの独立した軸として管理しています。だからこそ ShowLevels は二つの引数を取
ります。
ws.Outline.ShowLevels ColumnLevels:=1 ' 列のアウトラインをレベル 1 まで折りたたむ
ws.Outline.ShowLevels RowLevels:=2, ColumnLevels:=1 ' 一回の呼び出しで両方の軸を設定する
ColumnLevels だけを渡すと、行のグループがあった場所はそのままに、列だけが畳まれます — 二つのアウト
ラインは互いに干渉しません。これが、手作業で隠すのではなく アウトラインオブジェクト
を操作することの見返りです。一方の軸に手を加えても、もう一方の軸は乱れず、ボタンは嘘をつきません。
グループ化は隠すことでも、幅でもない
折りたたまれた列グループは隠された列のように 見える ので、三つの異なる道具を混同しやすくなります。 互いに置き換えられるものではありません。
- Group は、読み手がクリックできるボタンを備えた、可逆的でレベルを意識したアウトラインを作ります — 列が折りたたんでまた開き直したい詳細であるときに向いています。
- Hide(
.Hidden = True)は、アウトラインもボタンもない単純なオン/ オフの状態です — 単に列を視界から消したいだけのときに向いています。 - Width(
.ColumnWidth = 0)はサイズであって、表示状態ではありません — また別の意図です。
読み手が操作できる 折りたたみ可能な セクションが欲しいならグループ化を、単に列を邪魔にならないように したいなら隠すことを選びましょう。どちらか一方のつもりでもう一方を使ってしまうのがバグです — しっかり 隠したかったのに読み手が再び開ける列になってしまったり、欲しかったアウトライン構造のない、ただ隠れただ けの列になってしまったりします。
ExcelMaster の活用
列のグループ化は一行に見えて、三つの判断を隠しています — あなたの レイアウトにとって折りたたみボタ
ンをどちら側に置くべきか、渡したのが列全体なのか何も起きない部分的な範囲なのか、そしてそもそも単純な非
表示ではなく折りたたみ可能なグループにしたかったのか、です。どれか一つでも間違えると、エラーも出さずに
失敗します。左側の合計から右に離れて浮いたボタン、何もグループ化しなかった .Group の呼び出し、あるい
は隠したかった列を読み手が再び開いてしまう、といった具合です。
ExcelMaster には、望むことを
そのまま伝えられます — 「12 か月分の列を合計列の裏に畳んで、ボタンは左側に、折りたたんだ状態で」 — す
ると、それに合わせて SummaryColumn を設定し、列全体をグループ化し(部分的な範囲では決して行わず)、
ColumnLevels で折りたたんで行のグループはそのままにし、本当に望んでいたのが非表示だった場合はそちら
を選びます。ブックとコードはあなたの手元に残ります。
よくある質問
VBA で列をグループ化するには?
列全体に対して .Group を呼びます。Columns("B:D").Group は B 列から D 列を水平のアウトラインバーの
裏に畳み込み、上部に折りたたみボタンが付きます。ThisWorkbook.Worksheets("Report").Columns("B:D").Group
のように修飾して、アクティブなシートに依存しないようにしましょう。列は畳まれるだけで、隠されたり削除さ
れたりするわけではありません。
なぜグループ化した列の折りたたみボタンは右側に付くのですか?
Worksheet.Outline.SummaryColumn の既定値が xlSummaryOnRight で、合計列が詳細の右にあるものと決めて
かかっているからです。合計列が左側にある場合は、グループ化する前に ws.Outline.SummaryColumn = xlSummaryOnLeft
を設定し、ボタンをそちらに付けましょう。
B2:D2 のような範囲を渡すと、なぜグループ化が何も起こさないのですか?
部分的な範囲は列全体ではなく、列のグループになれるのは列全体だけだからです。Columns("B:D").Group か
Range("B:D").EntireColumn.Group を使いましょう。見出しがある列をグループ化したいときは、見出しを見つ
けて列全体まで広げます。Rows(1).Find("Q1", LookAt:=xlWhole).EntireColumn.Group。
グループ化した行に影響を与えずに、グループ化した列だけを折りたたむには?
ShowLevels に列の軸だけを渡します。ws.Outline.ShowLevels ColumnLevels:=1 は、行のグループには手を
付けずに列のアウトラインだけを折りたたみます。アウトラインは行と列を独立した軸として管理しているので、
一方を設定してももう一方は乱れません。
列をグループ化することは、隠すことと同じですか?
いいえ。グループ化は、読み手が列を畳んだり開いたりするためにクリックできるボタンを備えた、可逆的なアウ
トラインを作ります。隠す(.Hidden = True)ことは、アウトラインもボタンもない単純なオン/オフの状態で
す。読み手が操作する折りたたみ可能なセクションにはグループ化を、単に列を視界から消したいだけなら
隠す ことを使いましょう。
検証環境
検証環境: Excel 365 (Windows 11), VBA 7.1 — 最終確認 2026-09-16。
関連ガイド: VBA 行のグループ化 · VBA アウトライン · VBA 列の非表示 · VBA 列の幅 · VBA 列の挿入
