【テクニカル・上級編】【実務中級者向け】図面を開く際の「フォント置換」ダイアログを自動回避するフォントマップ制御 – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD VBAを掌握する極限の知見:フォント置換ダイアログの完全制圧とフォントマップ(FMP)動的制御

AutoCADのバッチ処理、あるいは外部システム連携による図面の自動オープン処理において、最も忌むべき現象は何か。
それは、存在しない「SHXフォント」や「TrueTypeフォント」に直面した瞬間、AutoCADが無慈悲に処理を中断し、画面の向こう側で「フォント置換」ダイアログが鎮座してユーザーの入力を待ち構える事態である。

バックグラウンドで稼働すべき自動化スクリプトが、たった一つのフォント欠落エラーによって完全に沈黙する。このアーキテクチャ上の脆弱性を根絶するためには、AutoCADの内部ライフサイクルと、その外殻を支配するフォントマッピング機構の深層を理解しなければならない。

本稿では、シニアエンジニアおよび社内システム管理者に向けて、VBAからフォントマップファイル(FMP)を動的に制御し、ダイアログの介入を許さずに図面をオープンする極限の実務テクニックを解説する。

—

1. フォント置換のメカニズムとアーキテクチャの急所

AutoCADは、図面(DWG/DXF)のロード時に定義されたフォント(`.shx` またはシステムフォント)がカレント環境に存在しない場合、以下のフォント解決シーケンスを実行する。

1. 同名フォントの探索: 検索パス(Support Path)から該当ファイルを探索。
2. フォントマップファイル(FMP)の参照: マッピングルールに基づく代替フォントへの置換。
3. 代替フォント(`FONTALT`システム変数)へのフォールバック: 上記がいずれも失敗した場合、デフォルトの代替フォント(通常は `txt.shx` や `simplex.shx`)へ強制置換。

このプロセスにおいて、FMPによる解決に失敗するか、あるいはAutoCADのセキュリティ/設定ポリシーによって「ユーザーに確認を求める」フラグが立っている場合、モーダルなダイアログが描画スレッドに割り込む。VBAの実行コンテキストは、このダイアログが人間の手によって閉じられるまで、永遠にブロックされることになる。

根本的な解決アプローチ

レガシーな図面資産を大量に扱う環境において、すべての図面に対して完全なフォントセットを強制することは、メンテナンスコストの観点から非現実的である。
したがって、「開こうとする図面の依存関係動的解析」と、「一時的なフォントマップ(FMP)の書き換え・適用」をプログラムのライフサイクルに組み込むのが、プロフェッショナルなエンジニアの選択となる。

—

2. フォントマップファイル(FMP)の仕様と制御戦略

AutoCADのフォントマップは、通常 `acad.fmp`(または製品に応じたカスタムFMP)として存在し、タブ区切りのプレーンテキスト形式で記述されている。

構文例: 存在しないフォント名;置換後のフォント名
JISX0208;txt.shx
HOGEFONT;simplex.shx
;.shx

このファイルをVBAから動的に操作するための戦略は以下の通りである。

1. 専用の一時FMPファイルの生成: 処理対象の図面群に必要なマッピングを追加した一時的な `.fmp` ファイルをOSのテンポラリ領域に動的生成する。
2. システム変数 `FONTMAP` の動的書き換え: AutoCADのセッション中、またはオープン処理の直前に `FONTMAP` 変数を対象のFMPファイルパスに向ける。
3. エラーハンドリングと復元: 処理完了後、あるいは例外発生時であっても、必ず元のFMP設定を復元する安全なライフサイクル管理を行う。

—

3. 実装コード:動的FMP制御による安全な図面オープン基盤

以下のコードは、フォント置換ダイアログの介入を完全にブロックし、安全に図面を開くための堅牢なVBAモジュールである。エラー発生時や異常終了時にもシステム変数が汚染されないよう、厳格なクリーンアップ処理を内包している。

Option Explicit

‘ Windows API: 一時ファイルパスの取得用(必要に応じて使用)
If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
Else
Private Declare Sub Sleep Lib “kernel32″ (ByVal dwMilliseconds As Long)
End If

”’

”’ フォントマップ(FMP)を一時的に書き換え、ダイアログを表示せずに図面を開くメインプロシージャ
”’

Public Sub OpenDrawingWithoutFontDialog(ByVal targetDwgPath As String)
Dim originalFontMap As String
Dim tempFmpPath As String
Dim fso As Object
Dim doc As Object

‘ オブジェクトのライフサイクル管理のための初期化
Set fso = CreateObject(“Scripting.FileSystemObject”)

On Error GoTo ErrorHandler

‘ 1. 現在の FONTMAP システム変数を退避
originalFontMap = ThisDrawing.GetVariable(“FONTMAP”)

‘ 2. 一時的なフォントマップファイル(.fmp)を生成
‘ ここでは「見つからないすべてのSHXを代換フォントに強制置換するワイルドカード()`を動的に付与する
tempFmpPath = fso.GetSpecialFolder(2) & “\autocad_temp_” & Format(Now, “yyyymmddhhmmss”) & “.fmp”
Call CreateDynamicFmpFile(tempFmpPath, originalFontMap, fso)

‘ 3. FONTMAPシステム変数を一時ファイルに向ける
ThisDrawing.SetVariable “FONTMAP”, tempFmpPath

‘ 4. バックグラウンド / アクティブでの図面オープン実行
‘ DOCUMENTSコレクション経由で開くことで、UIの割り込みを最小化
Set doc = Application.Documents.Open(targetDwgPath)

‘ 正常終了時のクリーンアップ
GoTo Finally

ErrorHandler:
‘ 異常発生時のログ出力およびリカバリ
MsgBox “図面のオープン中にエラーが発生しました: ” & Err.Description, vbCritical, “フォントマップ制御エラー”

Finally:
‘ 5. システム変数の原状復帰(極めて重要:これを怠ると後続の処理に致命的な影響を与える)
On Error Resume Next
ThisDrawing.SetVariable “FONTMAP”, originalFontMap

‘ 6. 一時ファイルの物理削除(メモリおよびストレージの最適化)
If fso.FileExists(tempFmpPath) Then
fso.DeleteFile tempFmpPath, True
End If

‘ 7. オブジェクト参照の明示的解放(VBA固有のCOMメモリリーク防止)
Set doc = Nothing
Set fso = Nothing

On Error GoTo 0
End Sub

”’

”’ 動的FMPファイルを生成するヘルパー関数
”’

Private Sub CreateDynamicFmpFile(ByVal fmpPath As String, ByVal baseFmpPath As String, ByRef fso As Object)
icum stream As Object
Dim fileContent As String

fileContent = “”

‘ 既存のFMPがあれば内容を引き継ぐ
If fso.FileExists(baseFmpPath) Then
Dim tsRead As Object
Set tsRead = fso.OpenTextFile(baseFmpPath, 1, False)
If Not tsRead.AtEndOfStream Then
fileContent = tsRead.ReadAll
End If
tsRead.Close
Set tsRead = Nothing
End If

‘ ワイルドカードマッピングを追加:解決できないフォントはすべて無視・置換させるルールを強制注入
‘ ;txt.shx または ;simplex.shx を用いる
fileContent = fileContent & vbCrLf & “;simplex.shx” & vbCrLf

‘ 一時ファイルへの書き出し
Dim tsWrite As Object
Set tsWrite = fso.CreateTextFile(fmpPath, True, False)
tsWrite.Write fileContent
tsWrite.Close
Set tsWrite = Nothing
End Sub

—

4. シニアエンジニアが押さえるべき実装上の極意と罠

上記のコードベースは実務の現場ですぐに機能するが、AutoCAD VBAの深淵を覗く者であれば、以下の「見えない制約」に留意しなければならない。

① COMオブジェクトのライフサイクルとメモリリーク

VBAにおける `CreateObject` や `Application.Documents.Open` によって生成されるCOMラッパーは、ガベージコレクションの挙動が極めて曖昧である。特に図面間をまたぐ処理(`ThisDrawing` から別ドキュメントへの移行)を行う際、参照を適切に破棄(`Set doc = Nothing`)しないと、AutoCADのプロセス(`acad.exe`)がバックグラウンドにゾンビプロセスとして残り続け、次回のバッチ処理で致命的なファイルロックを引き起こす。

② システム変数のスコープ

`FONTMAP` は図面データベース固有(DWG単位)ではなく、アプリケーションセッション全体(Profile単位)で共有されるグローバルなシステム変数である。そのため、処理途中で予期せぬエラー落ちが発生した場合、次から開くすべての図面で不正なFMPファイルが参照され続けるという深刻な副作用が生じる。
本コードの `ErrorHandler` および `Finally` ブロックにおける徹底した原状復帰(Try-Finally パターンのVBA的模倣)は、実務システムにおいて絶対に省略してはならない防壁である。

③ ネットワークドライブ上のFMPレイテンシ

もし `FONTMAP` に指定するFMPファイルがネットワーク共有フォルダ上に存在する場合、ファイルアクセスの遅延やロック競合によってオープン処理がタイムアウトすることがある。本稿のコードが、OSのローカルテンポラリ領域(`GetSpecialFolder(2)`)に動的に一時FMPを生成・破棄するアーキテクチャを採用しているのは、こうしたインフラストラクチャ起因のボトルネックを完全に排除するためである。

—

総括

AutoCAD VBAによる自動化の成否は、APIのメソッドを知ることではなく、「CADエンジンが引き起こすあらゆるダイアログの割り込みと例外状態を、コードの統制下にあらかじめ置くこと」に尽きる。

フォント置換ダイアログという、一見些細なUIの壁。これをFMPの動的制御と堅牢なライフサイクル管理によって完全に無力化できた時、あなたの自動化システムは真に「完全無人稼働」を達成する。レガシーとモダンが混在する極限の現場において、この知見がシステムの信頼性を極限まで高める羅針盤となることを確信する。

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