概要
Excel VBA を用いて帳票印刷やレポート作成を行う際、印刷レイアウトの調整は非常に重要です。特に「ページ設定」は、印刷範囲、用紙サイズ、余白、ヘッダー・フッター、そして改ページといった、印刷結果を左右する多くの要素を制御します。本稿では、Excel VBA の `PageSetup` オブジェクトと `PageBreak` オブジェクトに焦点を当て、これらのオブジェクトがどのように印刷レイアウトを自動化し、業務効率を劇的に向上させるのかを、初心者にも分かりやすく、しかしながら実践的なレベルで解説します。
`PageSetup` オブジェクトは、シート単位で適用される印刷設定を管理するための強力なツールです。用紙の向き(縦または横)、用紙サイズ、印刷品質、ヘッダーやフッターに表示するテキストやページ番号、そしてセルの内容をシート全体にどのように配置するかといった、多岐にわたる設定をプログラムから操作できます。
一方、`PageBreak` オブジェクトは、ワークシート上での改ページ位置を明示的に指定するために使用されます。手動で改ページを挿入する操作を自動化することで、長大なデータを複数のページにきれいに分割し、可読性の高い印刷物を作成することが可能になります。
これらのオブジェクトを VBE (Visual Basic Editor) で自在に操ることで、定型的な帳票の印刷処理を自動化したり、条件に応じて柔軟にレイアウトを変更したりといった、従来手作業では煩雑であった作業を効率化できます。本稿では、これらの基本的な概念から、具体的なプロパティ、メソッド、そして実務で役立つサンプルコードまでを網羅的に解説し、読者の皆様が VBA を用いたページ設定マスターとなることを目指します。
詳細解説
PageSetup オブジェクトの理解
`PageSetup` オブジェクトは、`Worksheet` オブジェクトのプロパティとしてアクセスできます。つまり、特定のシートのページ設定を変更したい場合は、まずそのシートオブジェクトを取得し、`.PageSetup` プロパティを通じてアクセスします。
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(“Sheet1”) ‘ 対象シートを指定
‘ Sheet1 のページ設定にアクセス
With ws.PageSetup
‘ ここで様々なページ設定プロパティを変更します
End With
`With…End With` ステートメントを使用することで、同じ `PageSetup` オブジェクトに対する複数のプロパティ設定を簡潔に記述できます。
主要な PageSetup プロパティ
* **`Orientation`**: 用紙の向きを指定します。`xlPortrait`(縦)または `xlLandscape`(横)を指定します。
.Orientation = xlLandscape ‘ 横向きに設定
* **`PaperSize`**: 用紙サイズを指定します。`xlPaperA4`、`xlPaperLetter` など、多数の定数が用意されています。
.PaperSize = xlPaperA4 ‘ A4 サイズに設定
* **`Zoom`**: 印刷時の拡大縮小率を指定します。`True` または `False` で、シート全体を1ページに収めるか、または特定の倍率を指定します。
.Zoom = False ‘ 自動調整しない場合
.Zoom = 90 ‘ 90%に拡大縮小する場合
* **`FitToPagesWide` / `FitToPagesTall`**: シートを印刷する際に、横方向または縦方向に何ページに収めるかを指定します。`Zoom` プロパティと組み合わせて使用されることが多いです。
.FitToPagesWide = 1 ‘ 横方向を1ページに収める
.FitToPagesTall = False ‘ 縦方向は自動調整
* **`LeftMargin`, `RightMargin`, `TopMargin`, `BottomMargin`**: 各余白のサイズをポイント単位で指定します。
.LeftMargin = Application.InchesToPoints(1) ‘ 左余白を1インチに設定
`Application.InchesToPoints` メソッドは、インチ単位の値をポイント単位に変換するのに便利です。
* **`HeaderMargin`, `FooterMargin`**: ヘッダーおよびフッター領域の余白をポイント単位で指定します。
* **`CenterHorizontally`, `CenterVertically`**: 印刷内容をページの中央に配置するかどうかを指定します。`True` または `False` を指定します。
.CenterHorizontally = True ‘ 水平方向中央揃え
* **`PrintTitleRows`, `PrintTitleColumns`**: 印刷時に各ページに繰り返し表示したい行または列を指定します。特定のセル範囲を指定します。
.PrintTitleRows = “$1:$2” ‘ 1行目と2行目を各ページに繰り返す
ヘッダー・フッターの設定
ヘッダー・フッターは、`LeftHeader`, `CenterHeader`, `RightHeader`, `LeftFooter`, `CenterFooter`, `RightFooter` プロパティで設定します。これらのプロパティには、テキストだけでなく、特殊なコード(エスケープシーケンス)を用いて、ページ番号、日付、時刻、ファイル名などを挿入できます。
| コード | 説明 |
| —— | —————— |
| `&P` | 現在のページ番号 |
| `&N` | 総ページ数 |
| `&D` | 現在の日付 |
| `&T` | 現在の時刻 |
| `&F` | ファイル名 |
| `&`& | “&”記号自体 |
| `&L` | 左揃え |
| `&C` | 中央揃え |
| `&R` | 右揃え |
| `&G` | 画像挿入(高度) |
例:
With ws.PageSetup
.CenterHeader = “&F – &D” ‘ ファイル名と日付を中央に表示
.RightFooter = “Page &P of &N” ‘ ページ番号を右に表示
End With
PageBreak オブジェクトの理解
ワークシート上の改ページは、`Worksheet` オブジェクトの `HPageBreaks` コレクション(水平方向の改ページ)と `VPageBreaks` コレクション(垂直方向の改ページ)を通じて操作します。
* **`HPageBreaks`**: 水平方向の改ページを表す `HPageBreak` オブジェクトのコレクションです。
* **`VPageBreaks`**: 垂直方向の改ページを表す `VPageBreak` オブジェクトのコレクションです。
各 `HPageBreak` オブジェクトは、`Location` プロパティ(改ページが挿入される行)を持ちます。同様に、各 `VPageBreak` オブジェクトは `Location` プロパティ(改ページが挿入される列)を持ちます。
改ページの挿入・削除
改ページをプログラムで挿入するには、`HPageBreaks.Add` メソッドや `VPageBreaks.Add` メソッドを使用します。引数には、改ページを挿入したいセルの位置を指定します。
‘ 行 5 の直下に水平改ページを挿入
ws.HPageBreaks.Add ws.Cells(5, 1)
‘ 列 C の右側に垂直改ページを挿入
ws.VPageBreaks.Add ws.Cells(1, “C”)
既存の改ページを削除するには、コレクションから該当する `HPageBreak` または `VPageBreak` オブジェクトを削除します。
‘ すべての水平改ページを削除
Dim hpb As HPageBreak
For Each hpb In ws.HPageBreaks
hpb.Delete
Next hpb
‘ すべての垂直改ページを削除
Dim vpb As VPageBreak
For Each vpb In ws.VPageBreaks
vpb.Delete
Next vpb
改ページの種類
Excel VBA では、改ページの種類を明示的に指定することはできませんが、手動操作では「改ページプレビュー」で「改ページを挿入」する際に、「改ページを削除」や「すべての改ページを削除」といったオプションがあります。VBA で `HPageBreaks.Add` や `VPageBreaks.Add` を使用して挿入される改ページは、通常「自動」または「手動」の改ページとして扱われます。
自動改ページは、Excel が印刷範囲やシートのサイズに基づいて自動的に挿入する改ページです。手動改ページは、ユーザーが明示的に挿入した改ページです。VBA で `Add` メソッドを使うと、通常は手動改ページとして扱われます。
改ページを解除するには、`PageBreak` プロパティを `xlPageBreakNone` に設定します。
‘ セル A1 から Z100 の範囲の改ページを解除
ws.Cells.Range(“A1:Z100”).PageBreak = xlPageBreakNone
ただし、これは特定の範囲の改ページを解除するもので、シート全体の自動改ページを完全に無効にするには、`FitToPagesWide` や `FitToPagesTall` を適切に設定するか、`Zoom` を調整する必要があります。
サンプルコード
以下に、`PageSetup` と `PageBreak` を使用した実践的な VBA サンプルコードを示します。
サンプル 1:帳票の基本ページ設定と改ページ挿入
このコードは、指定したシートのページ設定を行い、データ量に応じて自動的に改ページを挿入します。
Sub SetupReportPage()
Dim ws As Worksheet
Dim lastRow As Long
Dim dataRange As Range
‘ 対象シートを設定
On Error Resume Next
Set ws = ThisWorkbook.Sheets(“ReportData”)
On Error GoTo 0
If ws Is Nothing Then
MsgBox “シート ‘ReportData’ が見つかりません。”, vbExclamation
Exit Sub
End If
‘ 既存の改ページをクリア
ws.ResetAllPageBreaks
‘ ページ設定を初期化
With ws.PageSetup
.Orientation = xlLandscape ‘ 横向き
.PaperSize = xlPaperA4 ‘ A4 サイズ
.Zoom = False ‘ 自動調整しない
.FitToPagesWide = 1 ‘ 横方向を1ページに収める
.FitToPagesTall = False ‘ 縦方向は自動調整
.LeftMargin = Application.InchesToPoints(0.5)
.RightMargin = Application.InchesToPoints(0.5)
.TopMargin = Application.InchesToPoints(0.5)
.BottomMargin = Application.InchesToPoints(0.5)
.CenterHorizontally = True ‘ 水平方向中央揃え
.CenterVertically = False
.HeaderMargin = Application.InchesToPoints(0.3)
.FooterMargin = Application.InchesToPoints(0.3)
‘ ヘッダー・フッター設定
.LeftHeader = “”
.CenterHeader = “月次売上レポート”
.RightHeader = “”
.LeftFooter = “”
.CenterFooter = “作成日: &D”
.RightFooter = “Page &P of &N”
End With
‘ データ範囲の最終行を取得(A列を基準)
lastRow = ws.Cells(ws.Rows.Count, “A”).End(xlUp).Row
‘ データ範囲がヘッダー行を含まない場合(例:1行目がヘッダー)
If lastRow > 1 Then
Set dataRange = ws.Range(“A2:Z” & lastRow) ‘ 実際にはデータ範囲に合わせて調整
Else
Set dataRange = ws.Range(“A1:Z1”) ‘ データがない、またはヘッダーのみの場合
End If
‘ データ量に応じて改ページを挿入(例:50行ごとに改ページ)
If lastRow > 50 Then ‘ データが50行以上ある場合のみ改ページを挿入
Dim i As Long
For i = 51 To lastRow Step 50
‘ 行 i の直下に水平改ページを挿入
ws.HPageBreaks.Add ws.Cells(i, “A”)
Next i
End If
MsgBox “ページ設定と改ページ挿入が完了しました。”, vbInformation
End Sub
サンプル 2:印刷範囲の動的な設定と改ページ管理
このコードは、特定の条件(例:特定列の値が空白でない行)を満たす行のみを印刷範囲とし、それに基づいて改ページを挿入します。
Sub DynamicPrintRangeAndPageBreaks()
Dim ws As Worksheet
Dim printAreaRange As Range
Dim lastRow As Long
Dim currentRow As Long
Dim isFirstRow As Boolean
‘ 対象シートを設定
On Error Resume Next
Set ws = ThisWorkbook.Sheets(“DynamicReport”)
On Error GoTo 0
If ws Is Nothing Then
MsgBox “シート ‘DynamicReport’ が見つかりません。”, vbExclamation
Exit Sub
End If
‘ 既存の改ページをクリア
ws.ResetAllPageBreaks
‘ 印刷範囲の初期化
Set printAreaRange = Nothing
isFirstRow = True
‘ 印刷範囲を動的に設定(例:B列に値がある行のみを対象)
lastRow = ws.Cells(ws.Rows.Count, “B”).End(xlUp).Row
For currentRow = 1 To lastRow
If Not IsEmpty(ws.Cells(currentRow, “B”).Value) Then
If isFirstRow Then
Set printAreaRange = ws.Cells(currentRow, “A”) ‘ 開始セル
isFirstRow = False
Else
‘ 印刷範囲を拡張
Set printAreaRange = Union(printAreaRange, ws.Cells(currentRow, “A”))
End If
End If
Next currentRow
‘ 印刷範囲が設定できた場合
If Not printAreaRange Is Nothing Then
‘ 印刷範囲の最終列までを考慮して設定
Dim printAreaFinalCol As Long
printAreaFinalCol = ws.Cells(printAreaRange.Row, ws.Columns.Count).End(xlToLeft).Column
Set printAreaRange = ws.Range(ws.Cells(printAreaRange.Row, “A”), ws.Cells(printAreaRange.Rows.Count + printAreaRange.Row – 1, printAreaFinalCol))
‘ 印刷範囲を設定
ws.PageSetup.PrintArea = printAreaRange.Address
‘ ページ設定(例:縦向き、A4、余白標準)
With ws.PageSetup
.Orientation = xlPortrait
.PaperSize = xlPaperA4
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = False
.LeftMargin = Application.InchesToPoints(0.7)
.RightMargin = Application.InchesToPoints(0.7)
.TopMargin = Application.InchesToPoints(0.75)
.BottomMargin = Application.InchesToPoints(0.75)
.CenterHorizontally = False
.CenterVertically = False
.HeaderMargin = Application.InchesToPoints(0.4)
.FooterMargin = Application.InchesToPoints(0.4)
.LeftHeader = “部門: XXX”
.CenterHeader = “動的レポート”
.RightHeader = “期間: YYYY/MM/DD”
.LeftFooter = “”
.CenterFooter = “Page &P”
.RightFooter = “”
End With
‘ データ量に応じて改ページを挿入(例:100行ごと)
Dim numRows As Long
numRows = printAreaRange.Rows.Count
If numRows > 100 Then
Dim i As Long
For i = 101 To numRows Step 100
‘ printAreaRange の i 行目の直下に水平改ページを挿入
ws.HPageBreaks.Add ws.Cells(printAreaRange.Row + i – 1, “A”)
Next i
End If
MsgBox “動的な印刷範囲設定と改ページ挿入が完了しました。”, vbInformation
Else
MsgBox “印刷対象となるデータが見つかりませんでした。”, vbInformation
End If
End Sub
実務アドバイス
1. **`ResetAllPageBreaks` の活用**: VBA で改ページを操作する前に、`ws.ResetAllPageBreaks` を実行して既存の改ページをすべてクリアすることをお勧めします。これにより、予期しない改ページによるレイアウト崩れを防ぐことができます。
2. **単位の理解**: `PageSetup` の余白関連プロパティ(`LeftMargin` など)は、デフォルトではポイント単位です。インチやセンチメートルで指定したい場合は、`Application.InchesToPoints()` や `Application.CentimetersToPoints()` メソッドを適切に使用してください。
3. **`PrintArea` の動的な設定**: 印刷するデータ範囲が毎回異なる場合、`ws.PageSetup.PrintArea` プロパティを動的に設定すると便利です。`Find` メソッドやループ処理を用いて、実際のデータ範囲を特定し、
