Access VBAの深淵:プリンタ制御の「動的切り替え」を完全に掌握する
業務システム開発において、最も頭を悩ませるのが「環境依存の罠」だ。特に帳票出力において、「開発環境では動いたのに、現場のPCでは出力先がズレる」「プリンタ設定が変わるたびにソースコードを修正している」といった事態は、プロフェッショナルとしてあってはならない。
今日は、Accessの`Application.Printer`オブジェクトを使い、環境に左右されず、かつ堅牢にプリンタを制御する「極限の実装」を伝授する。
—
1. なぜ「デフォルトプリンタ」に依存してはいけないのか
多くの初心者は、Accessのデフォルトプリンタ設定をそのまま利用する。だが、これは「運任せ」の設計だ。
業務システムには、以下のような要件が必ず付随する。
- 帳票種別ごとの出し分け: 納品書はトレイA、請求書はトレイBへ。
- 環境の差異: PCのプリンタ一覧は、OSのアップデートやネットワークプリンタの接続状況で常に変化する。
これらを解決するには、「プリンタのプロパティをオブジェクトとして取得し、メモリ上で操作してから適用する」というライフサイクルを厳密に守る必要がある。
—
2. 本番環境で「落ちない」ための設計指針
プリンタ制御において最も避けるべきは、グローバルなデフォルトプリンタ設定を不用意に書き換えることだ。もし途中でエラーが発生すれば、そのPCのデフォルトプリンタが意図しない設定で固定されてしまう。
鉄則:
1. 退避: 設定変更前に現在のプリンタ状態を退避する。
2. 適用: 目的のプリンタ設定を一時的に適用する。
3. 復元: 処理終了後(例外発生時含む)に、必ず元の状態に戻す。
—
3. 実践:堅牢なプリンタ制御クラス(実装コード)
保守性を高めるため、プリンタ名と用紙サイズを引数で渡すモジュールを紹介する。これをそのまま `modPrinterUtility` として保存してほしい。
Option Compare Database
Option Explicit
‘ 目的のプリンタへ切り替えて帳票を出力する関数
Public Sub PrintReportControlled(ByVal reportName As String, ByVal printerName As String)
Dim originalPrinter As Printer
Dim targetPrinter As Printer
‘ 1. 現在のデフォルトプリンタを退避
Set originalPrinter = Application.Printer
On Error GoTo ErrorHandler
‘ 2. 指定したプリンタを検索し、オブジェクトをセット
Set Application.Printer = Application.Printers(printerName)
‘ 3. 帳票をプレビューなしで直接出力
DoCmd.OpenReport reportName, acViewNormal
CleanUp:
‘ 4. 処理終了後、必ず元のプリンタ設定に戻す
Set Application.Printer = originalPrinter
Exit Sub
ErrorHandler:
MsgBox “プリンタエラー: ” & Err.Description, vbCritical
Resume CleanUp
End Sub
さらに高度な制御(用紙サイズ・トレイ指定)が必要な場合
`Application.Printer` オブジェクトには `PaperSize` や `PaperBin` といったプロパティが存在する。これらは「列挙型」で定義されているため、以下のように動的に操作できる。
‘ 特定のプリンタの用紙サイズとトレイをセットする例
Public Sub ApplyPrintSettings(ByVal targetPrinterName As String)
Dim prt As Printer
Set prt = Application.Printers(targetPrinterName)
‘ 用紙サイズをA4に固定 (acPRPSA4)
prt.PaperSize = acPRPSA4
‘ 給紙トレイを自動選択 (acPRBNAuto)
prt.PaperBin = acPRBNAuto
‘ 横向きに設定
prt.Orientation = acPRORLandscape
‘ これをレポートのPrinterプロパティに適用するのが最も安全
‘ Reports(“YourReportName”).Printer = prt
End Sub
—
4. アーキテクトからの助言:現場での注意点
1. プリンタ名の完全一致: `Application.Printers(printerName)` を使う際は、コントロールパネル上の表示名と完全に一致させる必要がある。半角スペースの有無や改行コードに注意せよ。可能であれば、設定ファイル(INIやJSON)でプリンタ名を管理し、環境ごとに書き換え可能にしておけ。
2. エラーハンドリングの徹底: 上記コードで `On Error GoTo` を使っている理由は、プリンタがオフラインの場合に発生する「実行時エラー」をキャッチし、必ず `CleanUp` ラベルを通じてプリンタ設定を復元するためだ。これがないと、システムがプリンタを占有したままハングアップする。
3. CurrentDbとの連携: 帳票ごとの出力先をテーブルで管理し、`DLookup` でプリンタ名を取得する設計にすれば、ハードコーディングを排除できる。
結び
Accessのプリンタ制御は、一見すると単純な命令の羅列に見える。しかし、その裏側にある「デバイスの状態管理」を理解しているか否かで、システムの信頼性は天と地ほどの差が出る。
「動いた」で満足するな。「どのような異常系でも、元の状態を壊さずに終了できるか」。これこそが、真の業務自動化エンジニアの矜持である。
コードを実装したら、まずはプリンタがオフラインの状態でテストをしてみることだ。例外処理が正しく走り、他のアプリケーションの出力設定を破壊していないことを確認できれば、君のコードは本番環境で生き残る資格を得たと言える。
