【VBA】ウィンドウ枠の固定・解除をVBAで自動化する方法(コピペOK)

VBA
スポンサーリンク

記事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
スポンサーリンク

この記事でわかること

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.ActivateFreezePanes = False(解除)→ Range("A2").SelectFreezePanes = 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().SelectRange().Select で位置を指定する
3 「実行時エラー ‘1004’」が出る 既にウィンドウ枠が固定されている状態で、FreezePanesを再設定しようとした。環境によってはエラーになることがある FreezePanes = True の前に、必ず FreezePanes = False で既存の固定を解除する。いずれにせよ、事前に解除しておくのが確実
4 全シート処理で一部のシートだけ固定されない ws.Activate を忘れた、または非表示シートをActivateしようとしてエラーになった。FreezePanesActiveWindow に対する操作なので、対象シートをアクティブにする必要がある 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").SelectFreezePanes = True
  • 解除は FreezePanes = False の1行だけ
  • 設定前に既存の固定を解除するのがお約束
  • 全シートに一括適用するには For Each ws In ThisWorkbook.Worksheets でループ

表の見た目を整える罫線の設定は記事068、セルの書式変更全般は記事023、印刷時のタイトル行設定は記事051も参考になります。


次にやりたくなること

関連記事

コメント

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