AutoCAD VBAを掌握する極限の知見:ページ設定の呪縛を断ち切る『PlotToDevice』強制印刷の全技術
こんにちは。開発プロジェクトの現場で幾千ものAutoCADマクロの荒波を乗り越えてきたチーフアーキテクトの私だ。
日々の業務でこんな絶望を味わったことはないか?
「大量の図面をPDF化、あるいは特定の大型プロッターに出力したいのに、図面ごとにバラバラのページ設定(不適切な用紙サイズ、余白、モノクロ/カラーの混在)が保存されているせいで、バッチ処理が途中で止まる、あるいはゴミのような印刷物が量産される……」
一般の参考書やネットのQ&Aでは、「図面を開いてページ設定管理 (PAGESETUP) を手動で直せ」とか「レイアウトの `ConfigName` を変更しろ」といった、お遊戯レベルの解決策しか提示されない。だが、実務で100枚、1000枚の図面を扱うエンジニアにとって、そんな泥臭い手作業は「自動化の放棄」と同義だ。
今回は、AutoCAD VBAのオブジェクトモデルの深淵に踏み込み、「図面側のページ設定を完全に無視し、VBAから出力先デバイス、用紙サイズ、印刷スタイルを強制アサインして物理プリンタ(または仮想プリンタ)へ撃ち込む」ための極限のテクニックを伝授する。
—
1. なぜ「通常のページ設定変更」では実務で破綻するのか?
まず、アマチュアが陥る罠を共有しておこう。
AutoCADの `AcadLayout` オブジェクトには、`ConfigName`(プロッタ名)や `CanonicalMediaName`(用紙サイズ名)というプロパティが存在する。これらを書き換えてから印刷すればいい、と考えるのが初心者だ。
しかし、実務の現場では以下の致命的な壁に阻まれる。
1. トランザクションとドキュメントの同期ズレ
レイアウトのプロパティを書き換えて即座に `PlotToDevice` を叩くと、AutoCADの内部レンダリングエンジンが設定変更を処理しきれず、「直前の図面の設定」で誤爆印刷されるという恐怖のバグが起きる。
2. 存在しない用紙サイズの例外(ランタイムエラー)
A3対応のプリンタに対して、別図面から引き継いだ「A1」の用紙サイズ文字列をそのまま流し込むと、容赦なく「指定された用紙サイズはこのデバイスでサポートされていません」という実行時エラーでマクロがクラッシュする。
3. CIM(Cals / PDF / 物理機)ごとの印刷スタイルの混線
モノクロ2値で出すべき図面に、前任者が設定した色モリモリのCTBファイルがアサインされていて、インクを無駄にする。
これらを完全にねじ伏せるためには、「レイアウト自体の永続的な設定変更」を行わず、印刷プロセスのメモリ上で動的にパラメータをねじ込むアプローチが必要となる。
—
2. 堅牢な印刷自動化を支えるアーキテクチャ設計
今回提供するプロダクションコードは、以下の要件を満たす堅牢な設計(Production-Ready)となっている。
- レイアウト・アクティブ化の鉄則: 印刷対象は必ず `ActiveLayout` に明示的に設定し、ビューポートの状態を安定させる。
- エラーハンドリング: 万が一プリンタが見つからない場合や、デバイスがオフラインの場合でも、全体がクラッシュせず次の図面へ処理を継続する(Error Resume Nextの正しい使用法)。
- 遅延処理の排除と確実な同期: AutoCADのCOMラッパーが持つ非同期性の癖を考慮し、ドキュメントのロードとプロット実行の間に適切なステート管理を行う。
—
3. 【コピペ即実戦】最強の強制印刷モジュール
以下のコードを、あなたのAutoCAD VBAプロジェクト(標準モジュール)にそのまま貼り付けてほしい。
実務で即座に使えるよう、出力先プリンタ名や用紙サイズを変数として外部からコントロールできるように設計してある。
Option Explicit
‘ ==============================================================================
‘ 処理名: 物理プリンタ/仮想プリンタへの強制一括印刷エンジン
‘ 概要 : 図面のページ設定を無視し、指定デバイス・用紙サイズで強制出力する
‘ ==============================================================================
Public Sub ForcePlotActiveLayout()
On Error GoTo ErrorHandler
‘ — 1. 実行パラメータの定義(実務環境に合わせて変更してください) —
‘ 例: “Microsoft Print to PDF” または ネットワーク上のプロッタ名
Const TARGET_PRINTER As String = “Microsoft Print to PDF”
‘ 例: “A3” や “A4” (※対象プリンタがサポートしている正確な名前を指定)
Const TARGET_MEDIA As String = “A3”
‘ 例: モノクロ出力なら “monochrome.ctb”, カラーなら “” (なし)
Const TARGET_CTB As String = “monochrome.ctb”
Dim acadDoc As AcadDocument
Set acadDoc = ThisDrawing
‘ 現在のドキュメントのレイアウトを取得
Dim targetLayout As AcadLayout
Set targetLayout = acadDoc.ActiveLayout
‘ — 2. 印刷設定の動的オーバーライド(永続化させない一時設定) —
‘ 用紙の向きを強制的に横 (Landscape) に設定
targetLayout.PlotType = acExtents ‘ 図面範囲全体を対象
targetLayout.StandardScale = acScaleToFit ‘ 画面に合わせる(縮尺調整)
targetLayout.PlotRotation = ac90_degrees ‘ 横長へ回転
‘ プロッタ名(出力先)の強制割り当て
‘ ※注意: 指定したプリンタ名がPCにインストールされている必要があります
If Not IsPrinterAvailable(targetLayout, TARGET_PRINTER) Then
MsgBox “エラー: 指定されたプリンタ [” & TARGET_PRINTER & “] が見つかりません。”, vbCritical, “印刷エンジニアリング”
Exit Sub
End If
targetLayout.ConfigName = TARGET_PRINTER
‘ 用紙サイズの強制割り当て
‘ 注:プリンタがサポートする用紙名リストと完全一致させる必要があります
On Error Resume Next
targetLayout.CanonicalMediaName = TARGET_MEDIA
If Err.Number <> 0 Then
MsgBox “警告: 用紙サイズ [” & TARGET_MEDIA & “] はプリンタでサポートされていない可能性があります。デフォルト用紙で続行します。”, vbExclamation
End If
On Error GoTo ErrorHandler
‘ 印刷スタイル(CTB)の適用
If TARGET_CTB <> “” Then
targetLayout.RefreshPlotDevice
targetLayout.StyleSheet = TARGET_CTB
End If
‘ — 3. プロット実行フェーズ —
Dim acadPlot As AcadPlot
Set acadPlot = acadDoc.Plot
‘ バックグラウンド印刷(バックグラウンド処理)の有効化
‘ 大量処理時は True、エラー監視を厳密に行いたい場合は False
acadDoc.SetVariable “BACKGROUNDPLOT”, 0
‘ 物理出力の実行 (第1引数: プレビュー有無, 第2引数: 部数)
‘ 複数枚印刷やファイル出力(PDF等)の確実な同期を取るため、モーダルで実行
Dim isSuccess As Boolean
isSuccess = acadPlot.PlotToDevice(TARGET_PRINTER)
If isSuccess Then
Debug.Print “Success: ” & acadDoc.Name & ” の出力に成功しました。”
Else
Debug.Print “Warning: ” & acadDoc.Name & ” の出力処理で何らかの問題が発生しました。”
End If
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“Error No: ” & Err.Number & vbCrLf & _
“Description: ” & Err.Description, vbCritical, “致命的エラー”
End Sub
‘ ==============================================================================
‘ 補助関数: 指定されたプリンタがレイアウトの利用可能リストに存在するか検証
‘ ==============================================================================
Private Function IsPrinterAvailable(layoutObj As AcadLayout, printerName As String) As Boolean
Dim printers As Variant
Dim i As Long
IsPrinterAvailable = False
printers = layoutObj.GetPlotDeviceNames()
For i = LBound(printers) To UBound(printers)
If UCase(printers(i)) = UCase(printerName) Then
IsPrinterAvailable = True
Exit Function
End If
Next i
End Function
—
4. チーフアーキテクトからの実務アドバイス:ここが現場の分かれ道だ
このコードをただコピペして終わりにするな。実際の「大規模図面の一括処理(ディレクトリ内の全DWG走査など)」に組み込む際には、以下の鉄則を忘れるな。
1. `BACKGROUNDPLOT`(バックグラウンドプロット)の制御
VBAから連続して `PlotToDevice` を叩く場合、バックグラウンド印刷(`BACKGROUNDPLOT = 1`)が有効だと、AutoCADは印刷キューにジョブを投げた瞬間に「次の図面の処理」へ進んでしまう。結果として、複数ファイルが同時にメモリを食い潰し、AutoCADが強制終了(クラッシュ)する。大量処理を行うなら、必ずコード内で `BACKGROUNDPLOT = 0`(フォアグラウンド処理)に固定し、1枚の印刷が完全に完了するのを待たせるべきだ。
2. 仮想プリンタ(PDF等)出力時のファイル名ハレーション対策
Microsoft Print to PDFやAdobe PDFを使用する場合、出力先が「ファイルダイアログのポップアップ」で止まってしまうと自動化が完全にフリーズする。レジストリやプリンタの環境設定側で「出力先を固定のファイルパス・名にする」か、AutoCADのプロット設定でサイレント出力が可能なドライバ(DWG To PDF.pc3など)を選ぶこと。
3. `DWG To PDF.pc3` の活用
もし目的が「PDF化」であれば、物理プリンタ指定(`PlotToDevice`)ではなく、AutoCAD標準の高品質PDFドライバと組み合わせることで、上記のコードをそのまま「最強のPDF一括変換機」に昇華させることができる。
—
総括
ページ設定という「図面ごとの呪縛」にいつまでも振り回されるな。
AutoCAD VBAのオブジェクトモデルを正しく理解し、メモリ上でレイアウトパラメータを動的にねじ伏せる手法を手に入れたあなたなら、今日の午後からでも、手作業で何時間もかかっていた印刷地獄を「ワンクリックの全自動」へと変貌させられるはずだ。
妥協のないコードと強固なアーキテクチャで、君の現場の生産性を限界突破させてくれ。健闘を祈る。
