【上級】AcadApplication.Preferences.Files.PrinterConfigPathを動的に変更し、プロジェクト毎に異なるPC3/PMPファイルを自動ロードする
大規模なプラント設計、あるいは複数のゼネコン案件を並行して走らせる組織において、出力エラーは致命的な遅延を生む。A社向けの線種設定やペテーブル、特殊なカスタム用紙サイズを含んだPC3(プリンター設定ファイル)およびPMP(プリンターモデルパラメータ)ファイルが、B社の図面出力時に誤って適用される――。このヒューマンエラーは、図面管理の厳格化だけでは防げない。物理的な仕組みとして、図面(プロジェクト)を開いた瞬間に、CADの環境パスを動的にねじ曲げるアプローチが必要だ。
本稿では、AutoCAD VBAの心臓部である `AcadApplication.Preferences.Files` を掌握し、プロジェクト固有のプリンター環境を自動構築する極限の知見を解説する。
—
1. AutoCADプロファイル管理の深層と「Files」オブジェクトの罠
AutoCADの環境設定(オプション画面の「ファイル」タブ)は、レジストリまたは現在のプロファイルに深く結びついている。特に `PrinterConfigPath`(印刷設定ファイル検索パス)は、通常はグローバルな設定として保持されるため、図面ごとに動的な切り替えを行うにはイベント駆動型のパス書き換えが必須となる。
ここで、多くの初学者が陥る罠がある。
`ThisDrawing.Preferences` と `AcadApplication.Preferences` の混同だ。ファイルの検索パスやプリンター環境はアプリケーション全体のスコープに属すため、必ず `AcadApplication.Preferences.Files` を叩く必要がある。さらに、VBAからこのパスを書き換えた際、AutoCAD内部のキャッシュやファイルローダーが即座に追従しないケースがある。これを強制的に同期させるための作法も盛り込まなければならない。
—
2. 実装アーキテクチャ:DocumentOpenイベントによる動的スイッチング
プロジェクトごとのパス切り替えを完全に自動化するためには、図面オープンイベント (`DocumentOpen`) をフックする。しかし、通常の `ThisDrawing` モジュールでは、まだ図面が完全に開かれていない状態での競合が発生する。そのため、クラスモジュールによる `AcadAppEvents` の監視が必須となる。
以下に、実務の現場で即座に稼働する、堅牢性を極めた実装コードを示す。
① アプリケーションイベントを監視するクラスモジュール (`CAppEvents.cls`)
Option Explicit
‘ AutoCADアプリケーションイベントをフックするための宣言
Public WithEvents AppEvents As AcadApplication
Private Sub AppEvents_DocumentOpen(ByVal Document As AcadDocument)
On Error GoTo ErrorHandler
Dim targetDir As String
targetDir = ResolveProjectPrinterPath(Document.FullName)
If targetDir <> “” Then
‘ 印刷設定ファイルの検索パスを動的に書き換える
AcadApplication.Preferences.Files.PrinterConfigPath = targetDir
‘ デバッグおよび監査ログ用(必要に応じてファイル出力に変更可能)
Debug.Print “PrinterConfigPath successfully updated to: ” & targetDir
End If
Exit Sub
ErrorHandler:
MsgBox “PrinterConfigPathの動的切り替え中に致命的なエラーが発生しました: ” & Err.Description, vbCritical, “AutoCAD VBA Architect”
End Sub
Private Function ResolveProjectPrinterPath(ByVal drawingPath As String) As String
‘ 図面パスのルート(例: サーバー上のプロジェクトフォルダ)を解析し、
‘ 対応するPC3/PMP格納ディレクトリを動的に解決するアルゴリズム
If drawingPath = “” Then
ResolveProjectPrinterPath = “”
Exit Function
End If
Dim fso As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)
Dim rootDrive As String
rootDrive = fso.GetDriveName(drawingPath)
‘ 例として、プロジェクトコード(例: “PRJ-001″)をパスから抽出してフォルダーを決定する場合
‘ ここでは簡略化のため、図面と同じ階層にある “PrinterConfig” フォルダを動的探索する
Dim parentDir As String
parentDir = fso.GetParentFolderName(drawingPath)
Dim candidatePath As String
candidatePath = parentDir & “\PrinterConfig”
If fso.FolderExists(candidatePath) Then
ResolveProjectPrinterPath = candidatePath
Else
‘ フォールバック:デフォルトの共有パスを返す
ResolveProjectPrinterPath = “C:\AutoCAD_Standard\Plot Configs”
End If
Set fso = Nothing
End Function
② グローバル初期化モジュール (`mInit.bas`)
Option Explicit
‘ シングルトンとしてイベント監視クラスを保持
Public AppListener As CAppEvents
Public Sub InitializeAutoCADEnvironment()
Set AppListener = New CAppEvents
Set AppListener.AppEvents = AcadApplication
MsgBox “プロジェクト環境自動制御システムが正常にロードされました。”, vbInformation, “Architect System”
End Sub
Public Sub TerminateAutoCADEnvironment()
‘ メモリリークおよびイベントのデタッチ
Set AppListener.AppEvents = Nothing
Set AppListener = Nothing
End Sub
—
3. チーフアーキテクトが教える、現場の運用とパフォーマンス最適化
上記のコードをそのまま導入するだけでは、真のプロフェッショナルとは言えない。以下の制約事項とパフォーマンスへの配慮を必ず押さえておくこと。
ネットワーク遅延とファイルシステム(FSO)のオーバーヘッド
`DocumentOpen` イベントのトリガー時、巨大なCAD図面が開かれると同時に `Scripting.FileSystemObject` がネットワークドライブへアクセスすると、I/Oブロックが発生し、AutoCADのUIが数秒間フリーズすることがある。
これを防ぐため、パスの解決ロジックは極力軽量に保ち、必要であれば文字列操作関数(`InStr`, `Mid` など)を用いてファイルシステムへのアクセス回数を最小限に抑えよ。
メモリの明示的解放とCOMのライフサイクル
VBAにおけるCOMオブジェクト(特に `Scripting.FileSystemObject` や AutoCADの内部コレクション)は、スコープを抜けただけでは即座にメモリから解放されないことがある。ガベージコレクションの挙動に依存せず、上記コードのように `Set fso = Nothing` を明示的に記述し、COMサーバーへの参照カウントを確実にデクリメントすることが、長時間稼働する設計環境におけるクラッシュを防ぐ唯一の道である。
プロファイルとレジストリの保護
`PrinterConfigPath` の書き換えは、実行中のAutoCADセッションのメモリ上(および場合によっては現在のプロファイル)に書き込まれる。もしユーザーが手動でオプションを変更した後にマクロが上書きする競合を防ぎたい場合は、図面のカスタムプロパティ(`SummaryInfo`)やXrecordに紐づけた制御を組み合わせることで、より堅牢なシステムへと昇華させることができる。
—
結語
AutoCAD VBAは単なる「定型作業の自動化ツール」ではない。API仕様とオブジェクトライフサイクルを完全に理解した者にとって、CADの挙動そのものを自在に支配するための強力なミドルウェアである。今回解説した `PrinterConfigPath` の動的制御を導入することで、組織全体の出力ミスを根絶し、真にエンジニアリングに集中できる環境を構築してほしい。
