記事ID: 071
タイトル: 【VBA】ウィンドウ枠の固定・解除をVBAで自動化する方法(コピペOK)
カテゴリ: シート操作
一次キーワード: VBA ウィンドウ枠 固定 解除
想定読者: シートが多いブックで毎回手作業でウィンドウ枠を固定している人
検索意図: VBAでウィンドウ枠の固定・解除を自動化する方法を知りたい
読者の悩み(1文): 20枚以上のシートで見出し行を固定したいのに、1枚ずつ手作業でやるのが地味に時間がかかる
読了後にできること(1文): VBAでウィンドウ枠の固定・解除をコピペで自動化でき、全シートへの一括適用もボタン1つでできる
前提条件:
- Excel版: Excel 2016以降 / Microsoft 365
- OS: Windows 10/11
- 保存形式: .xlsm(マクロ有効ブック)
- 貼り付け場所: 標準モジュール
- 実行方法: マクロ実行(F5)またはボタン割り当て
更新日: 2026-03-11
Contents
この記事でわかること
VBAでウィンドウ枠の固定・解除を自動化する方法を、コピペで動くコード付きで解説します。
- 対象:シートが多いブックで毎回手作業でウィンドウ枠を固定している人
- 所要時間:コピペ → 実行まで3分
完成イメージ
実行前:
| A | B | C | D |
---+--------+--------+----------+----------+
1 | 日付 | 担当者 | 商品名 | 売上 | ← 見出し行
2 | 4/1 | 田中 | 商品A | 150,000 |
3 | 4/2 | 鈴木 | 商品B | 80,000 |
4 | 4/3 | 佐藤 | 商品A | 200,000 |
...
50 | 5/20 | 高橋 | 商品C | 50,000 |
下にスクロールすると見出し行が見えなくなり、「この列は何のデータだっけ?」と上に戻る羽目に。
実行後:
| A | B | C | D |
===+========+========+==========+==========+ ← ウィンドウ枠の固定ライン
1 | 日付 | 担当者 | 商品名 | 売上 | ← 見出し行(常に表示)
---+--------+--------+----------+----------+
30 | 4/30 | 伊藤 | 商品B | 120,000 |
31 | 5/1 | 田中 | 商品A | 90,000 |
32 | 5/2 | 鈴木 | 商品C | 60,000 |
どこまでスクロールしても見出し行が画面上部に固定され、データの内容がひと目でわかる。
さらに実務版では、ブック内の全シートにウィンドウ枠の固定を一括適用します。
自分もシートが20枚以上あるブックで、全シートの見出し行を固定したいときに、1枚ずつ「表示→ウィンドウ枠の固定」を繰り返していました。地味に時間がかかるし、たまに固定し忘れたシートがあって、あとから気づいてまたやり直し。
VBAで全シートに一括適用するマクロを書いてからは、ボタン1つで全シートの見出し行が固定されるようになりました。固定忘れもなくなって、地味にストレスだった作業がゼロになりました。
同じようにウィンドウ枠の固定を手作業でやっている人が、この記事で一括自動化できるようになればうれしいです。
基本:見出し行(1行目)を固定する
まずは最もシンプルな例。1行目(見出し行)をウィンドウ枠で固定します。
Sub 見出し行を固定する()
' --- 既存の固定を解除 ---
ActiveWindow.FreezePanes = False
' --- A2を選択(1行目の「次の行」) ---
Range("A2").Select
' --- ウィンドウ枠を固定 ---
ActiveWindow.FreezePanes = True
End Sub
ポイント:
FreezePanes = Trueは、アクティブセルの上の行と左の列を固定します- A2を選択すると、A2の「上」=1行目が固定されます
- 設定前に
FreezePanes = Falseで既存の固定を解除するのがお約束です(解除せずに再設定すると、環境によってはエラーになることがあります。いずれにせよ、事前に解除しておくのが確実です) - このコードはアクティブシート(今表示しているシート)に対して動作します
なぜA2? ウィンドウ枠の固定位置は「今選択しているセルの上と左」で決まります。1行目を固定したいなら、2行目のセル(A2)を選択してからFreezePanesを実行します。
セルの書式変更全般についてはセルの書式を一括変更する方法(記事023)も参考になります。
特定の行・列で固定する(行のみ/列のみ/行列両方)
特定の行で固定する(行のみ)
「3行目まで固定したい」など、固定する行数を変えたい場合です。
Sub 指定行で固定する()
Dim fixRow As Long
fixRow = 3 ' ← 固定したい行数(3行目まで固定)
' --- 既存の固定を解除 ---
ActiveWindow.FreezePanes = False
' --- 固定したい行の「次の行」のA列を選択 ---
Cells(fixRow + 1, 1).Select
' --- ウィンドウ枠を固定 ---
ActiveWindow.FreezePanes = True
End Sub
ポイント:
fixRow = 3なら、4行目のA列(Cells(4, 1))を選択 → 1〜3行目が固定されますfixRowの値を変えるだけで、何行目まで固定するかを自由に変更できます
特定の列で固定する(列のみ)
「A列だけ固定して、横スクロールしても見えるようにしたい」場合です。
Sub 指定列で固定する()
Dim fixCol As Long
fixCol = 1 ' ← 固定したい列数(A列まで固定)
' --- 既存の固定を解除 ---
ActiveWindow.FreezePanes = False
' --- 1行目の「固定したい列の次の列」を選択 ---
Cells(1, fixCol + 1).Select
' --- ウィンドウ枠を固定 ---
ActiveWindow.FreezePanes = True
End Sub
ポイント:
fixCol = 1なら、1行目のB列(Cells(1, 2))を選択 → A列が固定されますfixCol = 2にすれば、A〜B列が固定されます
行と列の両方を固定する
「1行目+A列を固定して、縦横どちらにスクロールしても見出しが見える」ようにする場合です。
Sub 行列両方を固定する()
Dim fixRow As Long
Dim fixCol As Long
fixRow = 1 ' ← 固定したい行数(1行目まで)
fixCol = 1 ' ← 固定したい列数(A列まで)
' --- 既存の固定を解除 ---
ActiveWindow.FreezePanes = False
' --- 固定したい行+1、列+1のセルを選択 ---
Cells(fixRow + 1, fixCol + 1).Select
' --- ウィンドウ枠を固定 ---
ActiveWindow.FreezePanes = True
End Sub
ポイント:
- B2を選択すると、B2の「上」=1行目、B2の「左」=A列が固定されます
- 行と列の両方が固定されるので、大きな表で縦横にスクロールしても見出しが消えません
固定位置の考え方をまとめるとこうなります:
| やりたいこと | fixRowの値 | fixColの値 | 選択するセル |
|---|---|---|---|
| 1行目を固定 | 1 | — | A2 |
| 3行目まで固定 | 3 | — | A4 |
| A列を固定 | — | 1 | B1 |
| A〜B列を固定 | — | 2 | C1 |
| 1行目+A列を固定 | 1 | 1 | B2 |
| 2行目まで+B列まで固定 | 2 | 2 | C3 |
ウィンドウ枠の固定を解除する
ウィンドウ枠の固定を解除するのは1行だけです。
Sub ウィンドウ枠を解除する()
ActiveWindow.FreezePanes = False
End Sub
ポイント:
FreezePanes = Falseで固定が解除されます- ウィンドウの分割(Split)が有効な場合も、
FreezePanes = Falseで同時に解除されます - 固定されていない状態で実行してもエラーにはなりません(何も起きないだけ)
固定を「設定し直す」場合も、まずこの解除を実行してから新しい位置で固定します。基本コード・実務版コードではすべてこの手順を組み込んでいます。
実務版:全シートのウィンドウ枠を一括設定する
ブック内の全シートに対して、見出し行(1行目)のウィンドウ枠固定を一括で適用するマクロです。
Sub 全シートのウィンドウ枠を固定する()
Dim ws As Worksheet
Dim currentSheet As Worksheet
' --- 現在のシートを記憶 ---
Set currentSheet = ActiveSheet
' --- 画面更新を停止(シートが多い場合に処理が速くなります) ---
Application.ScreenUpdating = False
' --- 全シートをループ ---
For Each ws In ThisWorkbook.Worksheets
' --- 非表示シートはスキップ ---
If ws.Visible = xlSheetVisible Then
ws.Activate
' --- 既存の固定を解除 ---
ActiveWindow.FreezePanes = False
' --- A2を選択して1行目を固定 ---
ws.Range("A2").Select
ActiveWindow.FreezePanes = True
End If
Next ws
' --- 元のシートに戻る ---
currentSheet.Activate
' --- 画面更新を再開 ---
Application.ScreenUpdating = True
MsgBox "全シートのウィンドウ枠を固定しました。", vbInformation
End Sub
ポイント:
For Each ws In ThisWorkbook.Worksheetsで全シートをループします(全シートに処理を適用する基本は記事015を参照)- 各シートで
ws.Activate→FreezePanes = False(解除)→Range("A2").Select→FreezePanes = True(固定)の手順を実行します ws.Visible = xlSheetVisibleで非表示シートをスキップします(非表示シートをActivateしようとするとエラーになるため)Application.ScreenUpdating = Falseでシート切り替え時の画面のちらつきを防ぎ、処理を高速化します- 処理後は元のシートに戻るので、実行前の作業位置が変わりません
MsgBoxで処理完了を通知します
このマクロをボタンに割り当てておけば、新しいシートを追加したときもボタン1つで全シートの見出し行を固定できます。ボタンの作り方は記事013を参照してください。
固定する行を変更したい場合
1行目ではなく「2行目まで固定」したい場合は、Range("A2") を Range("A3") に変えるだけです。
' 2行目まで固定する場合
ws.Range("A3").Select ' A3の「上」=1〜2行目が固定される
データの最終行を動的に取得して処理範囲を確認したい場合は、最終行取得の方法(記事032)が参考になります。
落とし穴
| # | 症状 | 原因 | 対策 |
|---|---|---|---|
| 1 | ウィンドウ枠が固定されない(何も起きない) | セルA1を選択した状態で FreezePanes = True を実行した。A1の「上」と「左」には行・列がないため固定されない |
固定したい行の次の行のセルを選択する(例: 1行目を固定するならA2を選択) |
| 2 | 意図しない位置で固定された | FreezePanes = True の前にセルを明示的に選択していなかった。アクティブセルがどこにあるかわからない状態で実行した |
FreezePanes = True の直前に、必ず Cells().Select や Range().Select で位置を指定する |
| 3 | 「実行時エラー ‘1004’」が出る | 既にウィンドウ枠が固定されている状態で、FreezePanesを再設定しようとした。環境によってはエラーになることがある | FreezePanes = True の前に、必ず FreezePanes = False で既存の固定を解除する。いずれにせよ、事前に解除しておくのが確実 |
| 4 | 全シート処理で一部のシートだけ固定されない | ws.Activate を忘れた、または非表示シートをActivateしようとしてエラーになった。FreezePanes は ActiveWindow に対する操作なので、対象シートをアクティブにする必要がある |
For Each ループ内で ws.Activate してから設定する。非表示シートは If ws.Visible = xlSheetVisible Then でスキップ |
| 5 | FreezePanesを設定したのに画面が分割表示になった | Split(ウィンドウの分割)が有効な状態で FreezePanes を操作した。SplitとFreezePanesは排他的 |
FreezePanes = False で解除すればSplitも解除される。心配なら ActiveWindow.Split = False も追加する |
FAQ
Q1: FreezePanesとSplit(ウィンドウ分割)の違いは?
FreezePanesは指定位置で行・列を固定し、スクロールしても見出しが常に見えるようにします。Splitはウィンドウを分割して、それぞれ独立にスクロールできます。両者は排他的で、同時に使うことはできません。
Q2: 見出し行が2行ある場合はどうする?
2行目まで固定したい場合は、A3を選択してから FreezePanes = True にします。考え方は「固定したい行数 + 1」行目のA列を選択するだけです。
Q3: 特定のシートだけウィンドウ枠を固定するには?
For Each ループの中で If ws.Name = "売上一覧" Then のようにシート名を判定すればOKです。または Worksheets("売上一覧").Activate で直接指定もできます。
Q4: ウィンドウ枠が固定されているかどうかをVBAで判定できる?
ActiveWindow.FreezePanes はBoolean型なので、If ActiveWindow.FreezePanes = True Then で判定できます。固定されていればTrue、されていなければFalseが返ります。
Q5: 印刷時にも見出し行を繰り返したい場合は?
FreezePanesは画面表示でのスクロール時に行・列を固定する機能です。印刷時に各ページの先頭に見出し行を繰り返すには PageSetup.PrintTitleRows を使います。FreezePanes=画面用、PrintTitleRows=印刷用と覚えておくと便利です。両方設定しておくと画面でも印刷でも見出しが見えます。詳しくは印刷設定の方法(記事051)を参照してください。
まとめ
ActiveWindow.FreezePanes = Trueでウィンドウ枠を固定できる- 固定位置はアクティブセルの「上の行」と「左の列」
- 1行目を固定するなら
Range("A2").Select→FreezePanes = True - 解除は
FreezePanes = Falseの1行だけ - 設定前に既存の固定を解除するのがお約束
- 全シートに一括適用するには
For Each ws In ThisWorkbook.Worksheetsでループ
表の見た目を整える罫線の設定は記事068、セルの書式変更全般は記事023、印刷時のタイトル行設定は記事051も参考になります。
次にやりたくなること
- 全シートに他の処理も一括適用したい → 複数シートを一括処理する方法(記事015)
- 印刷時にも見出し行を繰り返したい → 印刷設定の方法(記事051)


コメント