Excel VBA|印刷プレビューと自動印刷をユーザーが選べるようにする方法

スポンサーリンク
この記事は約15分で読めます。

Excel VBAで複数のシートを印刷するとき、いきなり印刷するのではなく、印刷プレビューで確認してから印刷したい場合があります。

この記事では、マクロ実行時に「自動印刷するか」「印刷プレビューで確認するか」をユーザーが選べるようにする方法を紹介します。

前回作成した「条件に合う複数シートを2種類の書式で印刷するマクロ」に、印刷方法の選択ダイアログを追加する応用編です。

このマクロでできること

  • 複数シートを印刷するときに、印刷方法を選択できる。
  • 「はい」を選ぶと、自動印刷する。
  • 「いいえ」を選ぶと、印刷プレビューを表示する。
  • 「キャンセル」を選ぶと、印刷処理を中止する。
  • すべての対象シートに同じ印刷方法を適用する。

印刷プレビューと自動印刷の違い

方法 内容 向いているケース
印刷プレビュー 印刷前に画面で確認する。 レイアウトを確認してから印刷したい場合。
自動印刷 確認画面を出さずに印刷する。 毎回同じ形式でまとめて印刷したい場合。
処理中止 印刷処理を行わずに終了する。 間違えて実行した場合。

Excel VBAでは、PrintPreview を使うと印刷時のイメージを表示できます。PrintOut を使うと、対象のワークシートを印刷できます。

このマクロで行う処理

  1. マクロ実行時に、印刷方法の選択ダイアログを表示する。
  2. 「はい」が選ばれたら、自動印刷にする。
  3. 「いいえ」が選ばれたら、印刷プレビューを表示する。
  4. 「キャンセル」が選ばれたら、処理を中止する。
  5. データシートから対象となる店番コードを取得する。
  6. 条件に合う各シートへ、選択された印刷方法を適用する。

印刷方法を選択するコード

まず、マクロの最初で印刷方法を選択するダイアログを表示します。

Dim confirmPrint As VbMsgBoxResult

confirmPrint = MsgBox( _
    "印刷方法を選択してください。" & vbCrLf & _
    "はい:自動印刷" & vbCrLf & _
    "いいえ:印刷プレビュー" & vbCrLf & _
    "キャンセル:処理中止", _
    vbYesNoCancel + vbQuestion, _
    "印刷方法の選択" _
)

If confirmPrint = vbCancel Then
    MsgBox "印刷処理を中止しました。", vbInformation
    Exit Sub
End If

この形にすると、ボタンの意味が分かりやすくなります。

選択 処理
はい 自動印刷する。
いいえ 印刷プレビューを表示する。
キャンセル 処理を中止する。

VBAコード

以下が、印刷プレビューと自動印刷をユーザーが選べるようにしたマクロです。

Sub PrintSheetsWithFukuokaShops_SelectPrintMode()

    Dim ws As Worksheet
    Dim dataSheet As Worksheet
    Dim fukuokaShops As Object
    Dim cell As Range
    
    Dim password As String
    Dim shopCode As Variant
    Dim printRange As Range
    Dim confirmPrint As VbMsgBoxResult
    
    On Error GoTo ErrHandler
    
    '=== 印刷方法を選択 ===
    confirmPrint = MsgBox( _
        "印刷方法を選択してください。" & vbCrLf & _
        "はい:自動印刷" & vbCrLf & _
        "いいえ:印刷プレビュー" & vbCrLf & _
        "キャンセル:処理中止", _
        vbYesNoCancel + vbQuestion, _
        "印刷方法の選択" _
    )
    
    If confirmPrint = vbCancel Then
        MsgBox "印刷処理を中止しました。", vbInformation
        Exit Sub
    End If
    
    '=== データシートを指定 ===
    Set dataSheet = ThisWorkbook.Sheets("データシート")
    
    '=== 福岡の店番コードを格納するDictionary ===
    Set fukuokaShops = CreateObject("Scripting.Dictionary")
    
    '=== シート保護解除用パスワード ===
    password = "1234"
    
    '=== データシートのC列を確認し、「福岡」の店番コードを取得 ===
    For Each cell In dataSheet.Range("C1:C" & dataSheet.Cells(dataSheet.Rows.Count, 3).End(xlUp).Row)
    
        If cell.Value = "福岡" Then
        
            shopCode = cell.Offset(0, -2).Value
            
            If Len(Trim(CStr(shopCode))) > 0 Then
                If Not fukuokaShops.Exists(CStr(shopCode)) Then
                    fukuokaShops.Add CStr(shopCode), True
                End If
            End If
        
        End If
    
    Next cell
    
    '=== 各シートを確認 ===
    For Each ws In ThisWorkbook.Worksheets
    
        If ws.Name <> dataSheet.Name Then
        
            Set printRange = Nothing
            
            ' シート保護がある場合は解除
            If ws.ProtectContents Then
                On Error Resume Next
                ws.Unprotect Password:=password
                
                If Err.Number <> 0 Then
                    MsgBox "シート '" & ws.Name & "' の保護を解除できませんでした。", vbExclamation
                    Err.Clear
                    On Error GoTo ErrHandler
                    GoTo NextSheet
                End If
                
                On Error GoTo ErrHandler
            End If
            
            ' B2に店番コードがある場合
            If Len(Trim(CStr(ws.Range("B2").Value))) > 0 Then
            
                shopCode = CStr(ws.Range("B2").Value)
                
                If fukuokaShops.Exists(shopCode) Then
                    Set printRange = ws.Range("A1:T60")
                    Call FormatAndPrintSheet_Type1(ws, printRange, confirmPrint)
                End If
            
            End If
            
            ' C4に店番コードがある場合
            If Len(Trim(CStr(ws.Range("C4").Value))) > 0 Then
            
                shopCode = CStr(ws.Range("C4").Value)
                
                If fukuokaShops.Exists(shopCode) Then
                    Set printRange = ws.Range("A1:M46")
                    Call FormatAndPrintSheet_Type2(ws, printRange, confirmPrint)
                End If
            
            End If
        
        End If
        
NextSheet:
    Next ws
    
    MsgBox "条件に合うシートの印刷処理が完了しました。", vbInformation
    Exit Sub

ErrHandler:
    MsgBox "エラーが発生しました:" & Err.Description, vbExclamation

End Sub


'----------------------------------------------------------
' 書式①:B2に店番コードがあるシート用
'----------------------------------------------------------
Sub FormatAndPrintSheet_Type1(ws As Worksheet, printRange As Range, confirmPrint As VbMsgBoxResult)

    With printRange
        .Font.Name = "Arial"
        .Font.Size = 12
        .Font.Bold = True
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
        .Interior.Color = RGB(200, 200, 255)
    End With
    
    With ws.PageSetup
        .PrintArea = printRange.Address
        .LeftMargin = Application.InchesToPoints(0.5)
        .RightMargin = Application.InchesToPoints(0.5)
        .TopMargin = Application.InchesToPoints(0.75)
        .BottomMargin = Application.InchesToPoints(0.75)
        .CenterHorizontally = True
        .CenterVertically = True
    End With
    
    Call ExecutePrintMode(ws, confirmPrint)

End Sub


'----------------------------------------------------------
' 書式②:C4に店番コードがあるシート用
'----------------------------------------------------------
Sub FormatAndPrintSheet_Type2(ws As Worksheet, printRange As Range, confirmPrint As VbMsgBoxResult)

    With printRange
        .Font.Name = "Calibri"
        .Font.Size = 10
        .Font.Italic = True
        .HorizontalAlignment = xlLeft
        .VerticalAlignment = xlTop
        .Interior.Color = RGB(255, 255, 200)
    End With
    
    With ws.PageSetup
        .PrintArea = printRange.Address
        .LeftMargin = Application.InchesToPoints(0.3)
        .RightMargin = Application.InchesToPoints(0.3)
        .TopMargin = Application.InchesToPoints(0.5)
        .BottomMargin = Application.InchesToPoints(0.5)
        .CenterHorizontally = False
        .CenterVertically = False
    End With
    
    Call ExecutePrintMode(ws, confirmPrint)

End Sub


'----------------------------------------------------------
' 印刷方法を実行する共通処理
'----------------------------------------------------------
Sub ExecutePrintMode(ws As Worksheet, confirmPrint As VbMsgBoxResult)

    If confirmPrint = vbYes Then
        ws.PrintOut
    ElseIf confirmPrint = vbNo Then
        ws.PrintPreview
    End If

End Sub

コードのポイント

vbYesNoCancelで選択肢を分かりやすくする

このコードでは、vbYesNoCancel を使って、3つの選択肢を表示しています。

vbYesNoCancel + vbQuestion

これにより、「はい」「いいえ」「キャンセル」の3つを使い分けられます。

印刷処理を共通化する

印刷方法の実行は、ExecutePrintMode にまとめています。

Sub ExecutePrintMode(ws As Worksheet, confirmPrint As VbMsgBoxResult)

    If confirmPrint = vbYes Then
        ws.PrintOut
    ElseIf confirmPrint = vbNo Then
        ws.PrintPreview
    End If

End Sub

こうしておくと、書式①・書式②の両方で同じ印刷処理を使えます。

キャンセル時は処理を中止する

ユーザーが「キャンセル」を選んだ場合は、何も印刷せずに処理を終了します。

If confirmPrint = vbCancel Then
    MsgBox "印刷処理を中止しました。", vbInformation
    Exit Sub
End If

カスタマイズのポイント

変更したい内容 修正する場所
自動印刷を初期選択にしたい メッセージ文で「はい:自動印刷」を先頭にしているため、そのままでOKです。
プレビューを優先したい メッセージ文の説明を「はい:印刷プレビュー」「いいえ:自動印刷」に変更し、分岐条件も入れ替えます。
対象地域を変更したい "福岡""大阪" などに変更します。
印刷範囲を変更したい A1:T60 または A1:M46 を変更します。
注意:
自動印刷を選ぶと、対象シートがすぐに印刷されます。
初めて実行する場合や、印刷範囲に不安がある場合は、まず印刷プレビューで確認するのがおすすめです。

このページと前後の記事の違い

このページでは、印刷プレビューと自動印刷をユーザーが選べるようにする方法を紹介しました。

前回の記事では、条件に合う複数シートを2種類の書式で印刷する基本形を紹介しています。
次の記事では、印刷したくないシートを除外する方法を紹介します。

記事 内容
前回の記事 条件に合う複数シートを2種類の書式で印刷する基本編。
この記事 印刷プレビューか自動印刷をユーザーが選べる応用編。
次の記事 印刷しないシートを指定して一括印刷する除外編。

まとめ

Excel VBAで複数シートを印刷するときは、PrintOut を使えば自動印刷でき、PrintPreview を使えば印刷前にレイアウトを確認できます。

今回のように vbYesNoCancel を使うと、マクロ実行時に「自動印刷」「印刷プレビュー」「処理中止」をユーザーが選べるようになります。

いきなり印刷するのが不安な場合は、まず印刷プレビューで確認し、問題がなければ自動印刷に切り替えると安心です。

コメント

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