AutoCAD VBAを掌握する極限の知見:レガシーの壁を打ち破る「R12 DXF」自動エクスポートの全技術
レガシーシステムとのデータ連携は、いつの時代もエンジニアの頭痛の種だ。
現代のBIM/CIM全盛期においても、現場の片隅では数十年前の汎用CADや、独自開発された古の検査システムが稼働し続けている。それらのシステムが要求するのは、決まって「AutoCAD R12 DXF形式」という極めてプリミティブなデータだ。
最新のAutoCADが吐き出すDWGやモダンなDXFを、そのまま古いシステムに放り込んでも「Unknown File Format」という冷徹なエラーが返ってくるだけである。スプラインは爆発し、リージョンは消え、文字は化ける。この世代間断絶をプログラムで完全に調停し、手作業による変換地獄から解放することこそ、我々オートメーション・エンジニアの使命である。
今回は、AutoCAD VBAを用いて、図面を確実かつ高速にAutoCAD R12互換のDXF形式へコンバートする極限のテクニックを授ける。表面的なメソッドの呼び出しにとどまらず、裏で動くCOMのライフサイクル、メモリ管理、そして実務で必ず直面する例外処理のノウハウまで、一切の妥協を排して解説する。
—
1. R12 DXF保存におけるアーキテクチャ上の罠
AutoCADの `SaveAs` メソッドは、一見するとシンプルに見える。しかし、ファイルフォーマットに `acR12_DXF` を指定して保存する背後では、ObjectARXのコアエンジンが複雑なダウングレード処理を実行している。
R12形式は1992年にリリースされた極めて古い仕様であり、現在のオブジェクト指向的なAutoCADデータベース(レイアウト、動的ブロック、ソリッド、TrueColorなど)の概念が存在しない。
したがって、R12 DXFへの変換とは単なる「保存」ではなく、「モダンな図面要素の破壊的ダウングレードとフラット化(Flatten)」を意味する。
VBAからこれを制御する際、以下の3点を見落とすと、メモリリークや、サイレントエラーによる破損ファイルの生成を引き起こす。
1. アクティブドキュメントのコンテキスト制約: `SaveAs` は実行中のドキュメントの状態に強く依存する。
2. 文字列エンコーディングの崩壊: レガシーDXFはShift-JIS等のローカル文字コードに依存するため、環境依存文字のハンドリングが必須。
3. COMオブジェクトの参照解放漏れ: ループ内で図面をバッチ処理する際、明示的なオブジェクト解放を行わないと、AutoCADのプロセス(`acad.exe`)がメモリ上にゾンビとして残り続ける。
—
2. 実装コード:堅牢性を極めたR12 DXFエクスポートプロシージャ
以下に、実務のバッチ処理にそのまま耐えうる、堅牢なVBAコードを提示する。単に保存するだけでなく、エラーハンドリングとオブジェクトのライフサイクル管理を徹底した実装だ。
Option Explicit
‘ =================================================================================
‘ 概要: アクティブな図面を指定フォルダにAutoCAD R12 DXF形式で安全にエクスポートする
‘ 特徴: 拡張子の自動付与、既存ファイルの上書き確認回避、厳密なエラーハンドリング
‘ =================================================================================
Public Sub ExportToR12DXF_Pro()
Dim targetDoc As AcadDocument
Dim outputPath As String
Dim fso As Object
Dim baseName As String
‘ 1. エラーハンドリングの有効化(COM例外の捕捉)
On Error GoTo ErrorHandler
‘ 2. アクティブドキュメントの取得
Set targetDoc = ThisDrawing
‘ 3. 未保存図面のガード(未保存の場合はファイル名がないためSaveAsで失敗する)
If targetDoc.Path = “” Then
MsgBox “現在の図面が一度も保存されていません。先に名前を付けて保存してください。”, vbCritical, “致命的エラー”
Exit Sub
End If
‘ 4. 出力パスの動的生成(元の図面と同階層の “DXF_R12” フォルダに出力)
Set fso = CreateObject(“Scripting.FileSystemObject”)
Dim parentDir As String
parentDir = targetDoc.Path & “\DXF_R12”
If Not fso.FolderExists(parentDir) Then
fso.CreateFolder parentDir
End If
baseName = fso.GetBaseName(targetDoc.Name)
outputPath = parentDir & “\” & baseName & “.dxf”
‘ 5. 既存ファイルの強制上書き対策(アトリビュート変更含む)
If fso.FileExists(outputPath) Then
‘ 読み取り専用属性がついている場合の解除
SetAttr outputPath, vbNormal
Kill outputPath
End If
‘ 6. 【最重要】R12 DXF形式での保存実行
‘ 第2引数に acR12_DXF を指定する。これがレガシー互換の鍵となる。
targetDoc.SaveAs outputPath, acR12_DXF
‘ 7. 成功ログの出力(イミディエイトウィンドウ)
Debug.Print “Export Success: ” & outputPath
MsgBox “R12 DXFへの変換が完了しました。” & vbCrLf & outputPath, vbInformation, “完了”
CleanUp:
‘ 8. オブジェクトの明示的解放(メモリ最適化)
Set targetDoc = Nothing
Set fso = Nothing
Exit Sub
ErrorHandler:
‘ 予期せぬ例外の捕捉とプロセス保護
MsgBox “DXFエクスポート中に致命的なエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“説明: ” & Err.Description, vbCritical, “システムエラー”
Resume CleanUp
End Sub
—
3. チーフアーキテクトが教える「現場の知見」と最適化の極意
上記のコードは基本形だが、真にプロフェッショナルな自動化システムを構築するためには、さらに踏み込んだ知見が必要になる。
① バッチ処理における「ドキュメントの非表示(Background)」の限界
「複数のDWGを裏側で一括してR12 DXFに変換したい」という要望は多い。しかし、AutoCADのVBA(およびCOM API)において、完全にUIを隠したバックグラウンド処理(Headless Mode)は、図面要素のジオメトリ評価やダウングレード時に予期せぬクラッシュを引き起こすリスクがある。
大量のファイルを処理する場合は、`Documents.Open` を用いてドキュメントを順次開き、アクティブコンテキスト上で `SaveAs` を実行し、速やかに閉じる(`Close False`)パターンが最も安定する。
‘ バッチ処理の骨子例
Dim doc As AcadDocument
Set doc = Application.Documents.Open(“C:\Data\Drawing1.dwg”, True) ‘ 読み取り専用でオープン
doc.SaveAs “C:\Data\DXF\Drawing1.dxf”, acR12_DXF
doc.Close False ‘ 変更を破棄して閉じる
Set doc = Nothing
② R12形式に耐えられないエンティティの事前クレンジング
R12 DXF形式は、以下のモダン要素を一切理解できない。
- 3Dソリッド / サーフェス
- 恵まれたハッチングパターン(一部の単純なものを除き、爆発されるか消滅する)
- マルチリーダー(引出線注記)やアノレータティブオブジェクト
- 外部参照(XREF)
もし変換元の図面にこれらが含まれている場合、AutoCADは黙ってデータを削ぎ落とすか、最悪の場合、変換プロセス自体がハングアップする。
実務システムでは、`SaveAs` を実行する前に、コード側で `SelectionSet` を用いてこれらの危険なエンティティをスキャンし、必要に応じて事前に削除または分解(Explode)するサニタイジング処理を前段に挟むべきである。
③ COMメモリのガベージコレクションとCOMの呪縛
VBAのランタイムは、COMオブジェクトの参照カウントを厳密に管理している。
ループ処理の中で `ThisDrawing.ModelSpace.Item(i)` などを安易に変数に代入し、ループを抜けても解放しないコードを書き続けると、VBAの背後でCOMのヒープメモリが肥大化し、数千回の処理の果てに「メモリ不足(Error 7)」でAutoCADごと沈没する。
オブジェクト変数(`AcadEntity`, `AcadSelectionSet` など)を使ったら、必ずループの最後で `Set xxx = Nothing` を明記し、VBAのガベージコレクタに頼らない姿勢がシニアエンジニアには求められる。
—
総括
AutoCAD VBAによるR12 DXFのエクスポートは、一見するとレガシーな技術の延命に過ぎないように見えるかもしれない。しかし、新旧のシステムが混在する現代のエンジニアリングチェーンにおいて、こうした「泥臭いデータ変換の自動化」を完璧に遂行できるか否かが、エンジニアとしての真価を分ける。
ここに示したコードと知見をあなたのシステムに組み込み、レガシーの制約を鮮やかに突破してほしい。
