AutoCAD VBAを掌握する極限の知見
【初心者向け】AcadDocument.SaveAsで失敗しない!ファイル形式(DWG/DXF)とバージョン指定のパラメータ解説
—
長年、製造業やプラントエンジニアリングの現場でAutoCADのカスタマイズに携わってきた者なら、誰もが一度は「バージョン不整合」の呪縛に苦しんだ経験があるはずだ。
最新のAutoCADで生成した図面を、協力会社やレガシーシステムが要求する古いバージョンのDWG、あるいはDXFとして書き出す――。この一見何気ないファイル保存処理が、VBAの自動化スクリプトにおいてどれほどの地雷原であるか。初心者だけでなく、中途半端な知識を持つエンジニアほど、この罠に足を取られる。
今回は、`AcadDocument.SaveAs` メソッドの本質を暴き、ファイル形式(DWG/DXF)とバージョン指定のパラメータ、そして実務で必ず直面する「上書き保存の警告ダイアログ(COM例外)」を完全にハックするための知見を授けよう。
—
1. `SaveAs` メソッドのアーキテクチャと致命的な誤解
まず、AutoCADのオブジェクトモデルにおける `Document.SaveAs` のシグネチャを正確に理解する必要がある。
RetVal = object.SaveAs(FileName [, Version] [, Provincia])
多くの開発者が犯す最大の過ちは、`Version` 引数にファイルの拡張子(”.dwg” や “.dxf”)を文字列で指定しようとする愚行だ。あるいは、最新のAutoCAD VBAだからといって、何も考えずにデフォルトで保存して「なぜか相手の古いAutoCADで開けない」と絶望する。
ここで使用すべきは、AutoCADの型ライブラリに定義されている `AcSaveAsType` 列挙型 である。これらを完全にコントロール下置くことが、プロとアマを分ける最初の分水嶺となる。
主要な `AcSaveAsType` 列挙体のマッピング
| 列挙体定数 (AcSaveAsType) | 値 | 実際のファイル形式・バージョン |
| :— | :—: | :— |
| `acR12_DXF` | 1 | AutoCAD R12/LT2 DXF |
| `ac2000_DWG` | 12 | AutoCAD 2000 DWG |
| `ac2000_DXF` | 13 | AutoCAD 2000 DXF |
| `ac2004_DWG` | 24 | AutoCAD 2004 DWG |
| `ac2004_DXF` | 25 | AutoCAD 2004 DXF |
| `ac2007_DWG` | 36 | AutoCAD 2007 DWG |
| `ac2007_DXF` | 37 | AutoCAD 2007 DXF |
| `ac2010_DWG` | 48 | AutoCAD 2010 DWG |
| `ac2010_DXF` | 49 | AutoCAD 2010 DXF |
| `ac2013_DWG` | 60 | AutoCAD 2013 DWG |
| `ac2013_DXF` | 61 | AutoCAD 2013 DXF |
| `ac2018_DWG` | 64 | AutoCAD 2018/2019/2020/2021/2022/2023/2024/2025 DWG |
※AutoCAD 2018以降、内部のDWGフォーマット構造は共通化されているが、明示的に互換性を担保するためには適切な列挙値を選択する胆力が求められる。
—
2. 実践:安全かつ確実にバージョン指定保存を行うVBAコード
現場で即座に使える、堅牢性(ロバストネス)を極限まで高めたプロシージャを提示する。単にメソッドを叩くだけではなく、ファイルが存在する場合のハンドリングも含めた実装だ。
Public Sub ExportToLegacyVersion()
Dim acadDoc As AcadDocument
Set acadDoc = ThisDrawing ‘ 現在アクティブな図面を対象とする
Dim targetPath As String
targetPath = “C:\Projects\Output\LegacyDrawing_R2004.dwg”
‘ 1. 既存ファイルの事前削除(上書きダイアログを抑制するための鉄則)
On Error GoTo ErrorHandler
If Dir(targetPath) <> “” Then
Kill targetPath ‘ ファイルが存在する場合は強制削除
End If
‘ 2. AutoCADの警告表示を一時的に無効化(スクリプトの無人化)
ThisDrawing.Application.Preferences.System.DisplayScreenMenu = False
‘ ※注意: 完全なダイアログ抑制にはシステム変数FILEDIAも絡むが、
‘ SaveAsメソッド自体のファイル競合はVBA側でのファイル削除で先手を打つのが最も確実。
‘ 3. AutoCAD 2004形式のDWGとして保存
‘ 第2引数に `ac2004_DWG` を明示的に渡す
acadDoc.SaveAs targetPath, ac2004_DWG
MsgBox “レガシー形式での保存が正常に完了しました。”, vbInformation, “システム通知”
Exit Sub
ErrorHandler:
MsgBox “致命的なエラーが発生しました: ” & Err.Description, vbCritical, “エラー”
‘ オブジェクトのライフサイクル管理:エラー時のクリーンアップ
Set acadDoc = Nothing
End Sub
—
3. システム間連携の地雷:「上書き保存の警告ダイアログ」完全ハック
夜間のバッチ処理や、PDM(製品データ管理)システムからの自動キックによってAutoCAD VBAを走らせたとき、「既存のファイルが存在します。上書きしますか?」というモーダルダイアログが出現し、処理が永遠にフリーズしたかのように停止した悪夢を見たことはないだろうか。
VBAの実行スレッドは、このAutoCADネイティブのダイアログが表示された瞬間からユーザーのクリックを待ち続け、システムは完全に沈黙する。完全自動化を目指すアーキテクトにとって、これは絶対に許されない致命傷である。
回避策の極意:UIに頼らない事前排他制御
AutoCADのCOMラッパーは、ファイルの競合に対して非常にナイーブだ。標準の `SaveAs` は、同名ファイルが存在すると内部でモーダルメッセージボックスを呼び出す仕様になっている。これを防ぐアプローチは以下の2つに集約される。
1. ファイルシステムの事前クレンジング(前述の `Kill` アプローチ)
COMに処理を渡す前に、VBAのファイルI/O関数を用いて物理ファイルを強制消去する。これにより、AutoCAD側で「新規保存」と同等のステートを作り出す。
2. システム変数 `FILEDIA` の制御
ファイル選択ダイアログの表示を強制的に無効化する。
‘ ダイアログを完全に抑制する高度な前処理
Dim originalFileDia As Integer
originalFileDia = ThisDrawing.GetVariable(“FILEDIA”)
‘ ダイアログを表示させない(コマンドライン入力強制モード)
ThisDrawing.SetVariable “FILEDIA”, 0
On Error GoTo SafeExit
‘ 保存処理
acadDoc.SaveAs targetPath, ac2013_DWG
SafeExit:
‘ 異常終了時も必ずシステム変数を元の状態に戻す(トランザクション的思考)
ThisDrawing.SetVariable “FILEDIA”, originalFileDia
If Err.Number <> 0 Then
MsgBox “エラー番号: ” & Err.Number & vbCrLf & Err.Description, vbExclamation
End If
この `FILEDIA = 0` のハックとファイル存在チェックの組み合わせこそが、何千回、何万回と回るバッチ処理を一度も止めずに完遂させるための唯一の防壁なのだ。
—
4. チーフアーキテクトからの提言:メモリ最適化とオブジェクト解放
最後に、VBAランタイムの脆弱性とAutoCADのCOMコンポーネントの重さに言及しておこう。
大量の図面をループ処理で次々と `Open` し、別形式で `SaveAs` して `Close` していくスクリプトを書く際、`Set acadDoc = Nothing` を怠ると、メモリリークの蓄積により必ずAutoCAD本体がクラッシュする。
- ローカル変数のオブジェクト参照は、処理の終了時に必ず `Nothing` を代入してメモリを解放せよ。
- ドキュメントを閉じる際は `acadDoc.Close False` (変更を保存せずに閉じる、すでにSaveAs済みなのだから)を明示し、COMサーバーへの参照カウンタを確実にデクリメントさせよ。
一歩進んだコードの血肉となり得るこの知見を、あなたの開発環境に今すぐ組み込んでほしい。妥協のないコードだけが、過酷なエンタープライズ環境を生き抜くことができるのだから。
