【VBAリファレンス】VBA技術解説印刷範囲の設定・印刷範囲のクリア

スポンサーリンク

はい、承知いたしました。VBAにおける印刷範囲の設定とクリアについて、ベテランExcel VBA講師の視点から、技術的な詳細と実務的なアドバイスを盛り込んだ、高品質なブログ記事を作成します。2500文字以上のボリュームで、読者の理解を深め、実務で活用できる情報を提供します。

### VBA技術解説:印刷範囲の設定とクリアでExcel出力を自在に操る

Excelのレポート作成やデータ集計において、意図した範囲だけを綺麗に印刷したい場面は非常に多いものです。しかし、手動で印刷範囲を設定するのは手間がかかり、繰り返し行う作業では非効率的になりがちです。そこで本記事では、Excel VBAを活用して印刷範囲を動的に設定・クリアする方法を、ベテランVBA講師の視点から徹底解説します。コードの書き方から実務で役立つ応用テクニックまで、余すことなくお伝えします。

#### 概要:なぜ印刷範囲をVBAで制御する必要があるのか?

Excelで印刷を行う際、`ファイル` > `印刷` メニューから印刷プレビューを確認し、印刷したい範囲を手動で選択して設定するのが一般的です。しかし、以下のような状況では、この手動操作は非効率的、あるいは不可能になります。

* **動的なデータ範囲:** 毎日のようにデータ量が増減し、印刷範囲が常に変わる場合。
* **条件付き印刷:** 特定の条件を満たす行や列のみを抽出して印刷したい場合。
* **複数シートの特定範囲印刷:** 複数のシートにまたがるデータのうち、各シートの特定の範囲だけをまとめて印刷したい場合。
* **自動化されたレポート作成:** VBAマクロによって自動生成されたレポートを、毎回決まった範囲で出力したい場合。

このような場合にVBAを活用することで、印刷範囲の設定・クリアを自動化し、作業効率を劇的に向上させることができます。さらに、印刷プレビューの表示や、PDFファイルへの出力など、より高度な自動化も可能になります。

#### 詳細解説:印刷範囲設定の基本と応用

Excel VBAで印刷範囲を操作するための主要なプロパティとメソッドは以下の通りです。

1. **`PageSetup.PrintArea` プロパティ:**
指定したシートの印刷範囲を設定します。このプロパティに、設定したいセルのアドレス(例: “A1:D10″)を文字列として代入することで、印刷範囲が確定します。

2. **`PageSetup.ClearPrintingAreas` メソッド:**
指定したシートの印刷範囲設定をすべてクリアします。これにより、印刷範囲が解除され、デフォルトの状態(シート全体など)に戻ります。

これらの基本を理解した上で、具体的なコードを見ていきましょう。

##### 1. 特定のセル範囲を印刷範囲に設定する

最も基本的なのは、固定のセル範囲を印刷範囲に設定する方法です。

Sub SetFixedPrintArea()
‘ アクティブシートの印刷範囲をA1からE20に設定
ActiveSheet.PageSetup.PrintArea = “A1:E20”
MsgBox “印刷範囲をA1:E20に設定しました。”, vbInformation
End Sub

このコードは、現在アクティブになっているシートの印刷範囲を、セルA1からE20までに設定します。`ActiveSheet` の代わりに、特定のシート名を指定することも可能です。

Sub SetSpecificSheetPrintArea()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(“Sheet1”) ‘ Sheet1という名前のシートを指定

‘ Sheet1の印刷範囲をB2からF30に設定
ws.PageSetup.PrintArea = “B2:F30″
MsgBox ws.Name & ” の印刷範囲をB2:F30に設定しました。”, vbInformation
End Sub

##### 2. データ範囲に合わせて印刷範囲を動的に設定する

実務で最も役立つのは、データが存在する範囲に合わせて印刷範囲を自動設定するテクニックです。これには、データの最終行や最終列を特定する必要があります。

* **最終行の取得:** `Cells(Rows.Count, 列番号).End(xlUp).Row`
* **最終列の取得:** `Cells(行番号, Columns.Count).End(xlToLeft).Column`

これらの方法を組み合わせることで、データ範囲全体を印刷範囲に設定できます。

Sub SetDynamicPrintArea()
Dim ws As Worksheet
Dim lastRow As Long
Dim lastCol As Long
Dim printAreaAddress As String

‘ アクティブシートを対象とする
Set ws = ActiveSheet

‘ データが存在する最終行をA列を基準に取得
lastRow = ws.Cells(ws.Rows.Count, “A”).End(xlUp).Row

‘ データが存在する最終列を1行目を基準に取得
lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column

‘ 印刷範囲の文字列を作成 (例: A1から最終行・最終列まで)
‘ データが1行目から始まっていると仮定
printAreaAddress = “A1:” & ws.Cells(lastRow, lastCol).Address

‘ 印刷範囲を設定
ws.PageSetup.PrintArea = printAreaAddress
MsgBox ws.Name & ” の印刷範囲を ” & printAreaAddress & ” に設定しました。”, vbInformation
End Sub

**注意点:**
* このコードは、A列にデータがあればその最終行を、1行目にデータがあればその最終列を基準としています。データが他の列に飛び飛びで存在する場合や、特定の列にしかデータがない場合は、基準となる列を適切に変更する必要があります。
* ヘッダー行(見出し)がある場合、`lastRow` に1を足す、あるいは印刷範囲の開始セルを “A2” などに変更するなどの調整が必要になることもあります。

##### 3. 複数シートの印刷範囲をまとめて設定する

複数のシートにまたがるレポートを生成する場合、各シートの印刷範囲を個別に設定する必要があります。ループ処理を活用するのが一般的です。

Sub SetMultiSheetPrintArea()
Dim ws As Worksheet
Dim lastRow As Long
Dim lastCol As Long
Dim printAreaAddress As String

‘ このブックのすべてのシートをループ処理
For Each ws In ThisWorkbook.Worksheets
‘ 各シートでデータ範囲を特定し、印刷範囲を設定
‘ ここでは、各シートでA列の最終行と1列目の最終列を基準とする例
If ws.Cells(ws.Rows.Count, “A”).End(xlUp).Row > 0 Then ‘ データがある場合のみ処理
lastRow = ws.Cells(ws.Rows.Count, “A”).End(xlUp).Row
lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
printAreaAddress = “A1:” & ws.Cells(lastRow, lastCol).Address
ws.PageSetup.PrintArea = printAreaAddress
Else
‘ データがないシートの印刷範囲はクリアするなどの処理
ws.PageSetup.PrintArea = “” ‘ 印刷範囲をクリア
End If
Next ws

MsgBox “すべてのシートの印刷範囲を設定しました。”, vbInformation
End Sub

このコードでは、ブック内のすべてのシートを巡回し、各シートにデータが存在する場合にのみ、そのデータ範囲を印刷範囲として設定しています。データがないシートについては、印刷範囲をクリアしています。

##### 4. 印刷範囲をクリアする

設定した印刷範囲を解除するには、`PageSetup.PrintArea` プロパティに空文字列 `””` を代入するか、`PageSetup.ClearPrintingAreas` メソッドを使用します。

Sub ClearPrintArea()
‘ アクティブシートの印刷範囲をクリア
ActiveSheet.PageSetup.PrintArea = “”
MsgBox “アクティブシートの印刷範囲をクリアしました。”, vbInformation
End Sub

Sub ClearAllPrintAreas()
‘ ブック内のすべてのシートの印刷範囲をクリア
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
ws.PageSetup.PrintArea = “”
‘ または ws.PageSetup.ClearPrintingAreas ‘ こちらでも同様の効果
Next ws
MsgBox “すべてのシートの印刷範囲をクリアしました。”, vbInformation
End Sub

`PageSetup.ClearPrintingAreas` メソッドは、シート全体に設定されているすべての印刷範囲(複数の範囲が設定されている場合)をクリアする、より包括的なメソッドと言えます。しかし、通常は `PrintArea = “”` で十分な場合が多いです。

#### サンプルコード:印刷範囲の設定とクリアを組み合わせたマクロ

ここでは、特定の条件(例: 特定の列に値がある行)を印刷範囲に含める、より実践的なサンプルコードを紹介します。

**シナリオ:**
“DataSheet” という名前のシートにデータがあり、”Status” 列(ここではE列と仮定)に “完了” と入力されている行のみを印刷したい。

Sub PrintSpecificRows()
Dim ws As Worksheet
Dim lastRow As Long
Dim printRange As Range
Dim cell As Range
Dim firstAddress As String
Dim lastAddress As String
Dim foundRange As Range

‘ 対象シートを指定
On Error Resume Next ‘ シートが存在しない場合のエラーを無視
Set ws = ThisWorkbook.Sheets(“DataSheet”)
On Error GoTo 0 ‘ エラーハンドリングを元に戻す

If ws Is Nothing Then
MsgBox “シート ‘DataSheet’ が見つかりません。”, vbCritical
Exit Sub
End If

‘ 印刷範囲を一旦クリア
ws.PageSetup.PrintArea = “”

‘ ステータス列(E列)の最終行を取得
lastRow = ws.Cells(ws.Rows.Count, “E”).End(xlUp).Row

‘ ステータス列(E列)で “完了” という値を持つセルを検索
Set foundRange = ws.Range(“E1:E” & lastRow).Find(What:=”完了”, LookIn:=xlValues, LookAt:=xlWhole)

If foundRange Is Nothing Then
MsgBox “条件に合うデータが見つかりませんでした。”, vbInformation
Exit Sub
End If

‘ 最初の検索結果を起点に、条件に合うすべてのセルを範囲として取得
Set printRange = foundRange
firstAddress = foundRange.Address

Do
Set foundRange = ws.Range(“E1:E” & lastRow).FindNext(After:=foundRange)
If Not foundRange Is Nothing Then
If foundRange.Address = firstAddress Then Exit Do ‘ 最初に見つかったセルに戻ったら終了
Set printRange = Union(printRange, foundRange) ‘ 範囲を結合
Else
Exit Do
End If
Loop

‘ 取得したセル範囲の行全体を印刷範囲として設定
‘ printRange は条件に合うセルのみなので、その行全体を取得する
Dim fullRowsRange As Range
Dim rowNum As Long
Dim lastCol As Long
lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column ‘ データ全体の最終列を取得

For rowNum = 1 To ws.Rows.Count
‘ printRange のいずれかのセルが現在の行にあるかチェック
If Not Intersect(ws.Rows(rowNum), printRange) Is Nothing Then
If fullRowsRange Is Nothing Then
Set fullRowsRange = ws.Rows(rowNum).Resize(1, lastCol) ‘ 最初の行を設定
Else
Set fullRowsRange = Union(fullRowsRange, ws.Rows(rowNum).Resize(1, lastCol)) ‘ 行を追加
End If
End If
Next rowNum

If Not fullRowsRange Is Nothing Then
ws.PageSetup.PrintArea = fullRowsRange.Address
MsgBox “条件に合う行を印刷範囲に設定しました。”, vbInformation

‘ 印刷プレビューを表示 (オプション)
‘ ActiveSheet.PrintPreview
Else
MsgBox “条件に合う行が見つかりませんでした。”, vbInformation
End If

End Sub

**コード解説:**
1. `DataSheet` シートを対象とします。
2. まず、既存の印刷範囲をクリアします。
3. E列(ステータス列)の最終行を特定します。
4. `Range.Find` メソッドと `Range.FindNext` メソッドを組み合わせて、E列に “完了” と入力されているすべてのセルを検索します。
5. 見つかったセルを `Union` メソッドで結合し、条件に合うセルの集合 `printRange` を作成します。
6. `printRange` に含まれるセルがある行全体を、データ全体の最終列までを範囲として `fullRowsRange` に集約します。
7. `fullRowsRange` を印刷範囲として設定します。
8. 必要であれば、印刷プレビューを表示します。

このコードは、条件付きで印刷範囲を設定する強力な例です。`Find` メソッドの引数を変更することで、より複雑な条件にも対応できます。

#### 実務アドバイス:印刷範囲設定を成功させるためのヒント

* **シート名の固定:** `ActiveSheet` ではなく、`ThisWorkbook.Sheets(“シート名”)` のように、シート名を明示的に指定することで、意図しないシートの印刷範囲が変更されるリスクを減らせます。
* **エラーハンドリング:** シートが存在しない場合や、データが見つからない場合などに備えて、`On Error Resume Next` や `If … Is Nothing Then` を適切に使用し、エラーメッセージを表示したり、処理を中断したりするようにしましょう。
* **データ範囲の定義:** 印刷範囲を設定する際の基準となる列(例: A列、ID列など、必ずデータが入る列)を明確に定義してください。データが不規則に配置されている場合は、複数の列をチェックするロジックが必要になることもあります。
* **ヘッダー行/フッター行の考慮:** データ範囲の特定や印刷範囲の設定において、ヘッダー行(見出し)やフッター行(合計行など)をどこまで含めるかを明確に定義し、コードに反映させてください。例えば、ヘッダーが1行目にあるなら、印刷範囲は `A1:最終列最終行` となります。
* **印刷プレビューの活用:** VBAで印刷範囲を設定した後、実際に印刷する前に `ActiveSheet.PrintPreview` を実行して、意図した通りに表示されるか確認することを強くお勧めします。
* **印刷範囲のクリア:** マクロ実行後に意図せず印刷範囲が固定されたままにならないよう、マクロの最後や、次の処理の開始時に `PageSetup.PrintArea = “”` でクリアする習慣をつけましょう。
* **パフォーマンス:** 非常に大量のデータを扱う場合、`Union` メソッドを多用するとパフォーマンスが低下する可能性があります。その場合は、範囲を直接指定するのではなく、条件に合う行番号のリストを作成し、それを使って最終的な印刷範囲を構築するなど、別の手法を検討する必要があるかもしれません。

#### まとめ:VBAで印刷管理を効率化しよう

Excel VBAを使えば、印刷範囲の設定とクリアを自動化し、レポート作成やデータ出力の効率を飛躍的に向上させることができます。本記事で解説した `PageSetup.PrintArea` プロパティと `PageSetup.ClearPrintingAreas` メソッドを理解し、データ範囲の特定方法や、条件付きでの設定方法を習得することで、より高度で実用的なマクロを作成できるようになります。

今回ご紹介したサンプルコードはあくまで一例です。皆様が抱える具体的な課題に合わせて、コードをカスタマイズし、Excel作業の自動化をさらに推進していきましょう。印刷管理の効率化は、日々の業務改善に直結する重要なスキルです。ぜひ、この機会にVBAでの印刷範囲制御をマスターしてください。

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