Excel VBAでウィンドウ枠の固定をする方法をお探しですね。
広告
Excelのウィンドウ枠固定をVBAで自動化する方法
Excelで行数や列数の多い一覧表を扱っていると、下にスクロールした途端に見出し行が見えなくなって、「あれ、この列って何の情報だっけ?」と困ることってありますよね。
手作業なら「表示」タブからウィンドウ枠を固定できますが、毎回同じ表示状態に整えるならVBAで自動化したほうが断然ラクです。
この記事では、Excel VBAでウィンドウ枠の固定・解除を自動化する方法を、基本から実務で使えるサンプルコードまで分かりやすく解説します。
VBAでウィンドウ枠を固定・解除する基本
Excel VBAでウィンドウ枠の固定を行うときは、`ActiveWindow.FreezePanes`というプロパティを使います。
これは、今開いているExcelウィンドウに対して、ウィンドウ枠の固定をオン・オフするためのものです。
値を`True`にすると固定され、`False`にすると解除されます。
ここで大事なのは、ワークシート自体の設定ではなく、表示中のウィンドウに対する設定だという点です。
ウィンドウ枠の固定は、データの中身を変更する処理ではなく、見やすく作業できるようにするための表示の工夫です。
たとえば、売上一覧や在庫表、顧客リスト、仕訳明細のように行数が多い表では、見出し行を常に表示しておくことで確認ミスを減らせます。
また、左端の管理番号や商品コードなどを固定しておけば、横方向にスクロールしても「今どのデータを見ているんだっけ?」と迷わずに済みます。
マクロで帳票や一覧表を作成するときは、データを出力するだけでなく、最後に見やすい表示状態まで整えてあげると、実務でぐっと使いやすくなります。
一番シンプルな固定と解除のコードは、こんな感じで書けます。
ただし、固定位置は後で説明する「アクティブセル」によって決まるので、`FreezePanes = True`だけ書けば常に思い通りになるわけではありません。
すでに別の位置で固定されている可能性もあるので、実務では一度解除してから、固定したい基準のセルを選択して、もう一度固定する流れが安全です。
“`vb
Sub FreezeBasic()
‘B2を基準にして、1行目とA列を固定する
Range(“B2”).Select
ActiveWindow.FreezePanes = True
End Sub
Sub UnfreezeBasic()
‘ウィンドウ枠の固定を解除する
ActiveWindow.FreezePanes = False
End Sub
“`
固定位置はアクティブセルで決まる
FreezePanesを使ううえで一番大切なのは、「固定位置はアクティブセル(選択中のセル)を基準に決まる」というルールです。
Excelでは、選択したセルより上にある行、選択したセルより左にある列が固定対象になります。
つまり、VBAでウィンドウ枠を固定する場合も、どのセルを選択してから`ActiveWindow.FreezePanes = True`を実行するかで結果が変わってきます。
たとえば、1行目だけを固定したいときは、2行目のセルである`A2`を選択してから固定します。
A2より上にある行は1行目だけで、A2より左にある列はないので、見出し行だけが固定されます。
先頭列だけを固定したいときは、`B1`を選択します。
B1より左にある列はA列だけで、B1より上にある行はないので、A列だけが固定されます。
1行目とA列の両方を固定したいときは、`B2`を選択してから固定します。
用途別に整理すると、代表的な指定はこんな感じです。
| 固定したい内容 | 選択するセル | 固定される範囲 |
|—|—:|—|
| 先頭行だけ固定 | A2 | 1行目 |
| 先頭列だけ固定 | B1 | A列 |
| 先頭行と先頭列を固定 | B2 | 1行目とA列 |
| 1〜3行目を固定 | A4 | 1〜3行目 |
| 1〜2行目とA〜C列を固定 | D3 | 1〜2行目とA〜C列 |
この考え方を覚えておけば、固定する行数や列数が変わっても迷わずに済みます。
たとえば、タイトル行が1行目、項目見出しが2行目にあって、データが3行目から始まる表なら、`A3`を選択して固定すれば1〜2行目を固定できます。
さらに、A列からC列までに重要な項目が並んでいる場合は、`D3`を選択すれば、1〜2行目とA〜C列を同時に固定できます。
FreezePanesは難しい命令ではありませんが、この「選択セルの上と左が固定される」という仕組みを理解しておくことが、思い通りに動かすコツです。
実務で使いやすい固定・解除マクロの書き方
実務で使うマクロでは、今どの位置で固定されているか、どのセルが選択されているか、どのシートがアクティブかが毎回同じとは限りません。
そのため、ウィンドウ枠を固定する処理は「対象シートをアクティブにする」→「既存の固定を解除する」→「基準セルを選択する」→「固定する」という順番で書くと安定します。
特に、複数シートを順番に処理するマクロでは、シートオブジェクトを変数に入れていても、そのシートが画面上でアクティブになっているとは限りません。
`Select`はアクティブなシートに対して行う必要があるので、先に`Activate`することが大切です。
次のコードは、指定したワークシートで1行目を固定する例です。
`Application.Goto`を使って一度A1へ移動してから、基準セルであるA2を選択しています。
これは必須ではありませんが、スクロール位置が大きくずれているブックや、直前の処理で別の場所を表示している場合でも、固定位置を確認しやすくするための実務的な工夫です。
マクロ実行後にシートを開いたとき、左上付近から表を確認できる点でも使いやすくなります。
“`vb
Sub FreezeTopRow()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(“一覧”)
ws.Activate
If ActiveWindow.FreezePanes Then
ActiveWindow.FreezePanes = False
End If
Application.Goto ws.Range(“A1”), True
ws.Range(“A2”).Select
ActiveWindow.FreezePanes = True
End Sub
“`
1行目とA列を固定したいときは、基準セルを`B2`に変更します。
解除だけを行うマクロも用意しておくと、表示状態をリセットしたいときに便利です。
固定と解除を別々のプロシージャにしておけば、ブックを開いたときに自動で固定する処理、ボタンを押したときに解除する処理など、目的に応じて使い分けられます。
“`vb
Sub FreezeTopRowAndFirstColumn()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(“一覧”)
ws.Activate
If ActiveWindow.FreezePanes Then
ActiveWindow.FreezePanes = False
End If
Application.Goto ws.Range(“A1”), True
ws.Range(“B2”).Select
ActiveWindow.FreezePanes = True
End Sub
Sub UnfreezePanes()
If Not ActiveWindow Is Nothing Then
ActiveWindow.FreezePanes = False
End If
End Sub
“`
もっと汎用的にしたいときは、固定の基準セルを引数で渡す形にすると便利です。
たとえば、シートごとに固定したい位置が違うブックでは、共通処理を1つ作っておいて、`A2`や`B2`、`D3`などを呼び出し側で指定できるようにします。
マクロを長く運用するほど、同じ処理を何度も書かない設計が保守しやすさにつながります。
“`vb
Sub SetFreezePanes(ByVal ws As Worksheet, ByVal baseCellAddress As String)
ws.Activate
If ActiveWindow.FreezePanes Then
ActiveWindow.FreezePanes = False
End If
Application.Goto ws.Range(“A1”), True
ws.Range(baseCellAddress).Select
ActiveWindow.FreezePanes = True
End Sub
Sub SampleUse()
Call SetFreezePanes(ThisWorkbook.Worksheets(“一覧”), “B2”)
End Sub
“`
思った位置に固定されないときの原因と注意点
FreezePanesでよくある失敗は、思っていた行や列とは違う場所で固定されてしまうことです。
ほとんどの場合、原因は`FreezePanes = True`を実行した瞬間のアクティブセルが想定と違っていることにあります。
直前の処理で別のセルを選択していたり、フィルターや書式設定の操作後にスクロール位置が変わっていたりすると、固定位置が意図しない場所になることがあります。
対策としては、固定する直前に必ず対象シートをアクティブにして、基準セルをはっきり選択することです。
もう一つの注意点は、`FreezePanes`がワークシートではなく`ActiveWindow`に対する設定だということです。
`ws.FreezePanes = True`みたいには書けません。
Excelを外部アプリケーション、たとえばAccess VBAから操作している場合も、対象のExcelアプリケーションのアクティブウィンドウに対して設定する必要があります。
対象ブックや対象シートを変数で持っているだけでは、画面上のアクティブ状態が保証されないので、`Workbook.Activate`や`Worksheet.Activate`を適切に使うことが大切です。
また、すでにウィンドウの分割やウィンドウ枠の固定が設定されているブックに対して再設定する場合は、一度リセットしてから固定し直すほうが安全です。
`SplitRow`や`SplitColumn`を使って固定位置を指定する方法もありますが、既存の分割状態が残っていると分かりにくい動きになることがあります。
シンプルな一覧表では、まず`FreezePanes = False`で解除して、必要に応じて`SplitRow`と`SplitColumn`を0に戻してから設定すると、意図しない表示状態を避けやすくなります。
“`vb
Sub FreezeBySplit()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(“一覧”)
ws.Activate
With ActiveWindow
.FreezePanes = False
.SplitRow = 1 ‘固定する行数
.SplitColumn = 1 ‘固定する列数
.FreezePanes = True
End With
End Sub
“`
ただし、初心者が最初に覚える方法としては、基準セルを選択してから`FreezePanes`を設定する書き方のほうが分かりやすいです。
`A2`なら先頭行、`B1`なら先頭列、`B2`なら先頭行と先頭列という対応が直感的で、後からコードを読む人にも意図が伝わりやすいからです。
表示制御のマクロは、処理結果の正しさだけでなく、利用者が開いた瞬間に迷わず作業できる状態を作ることが目的です。
Excel VBAでウィンドウ枠の固定・解除を自動化するときは、「ActiveWindow」「アクティブセル」「事前解除」の3点を押さえておくと、安定した使いやすいマクロになります。
ぜひ試してみてください。
広告
