【AutoCAD VBAを掌握する極限の知見】AcadDocument.SaveAsで失敗しない!ファイル形式とバージョン指定の極意
開発プロジェクトの現場で、自動化スクリプトを組んでいて最も頭を抱える瞬間の一つが、「ファイルの保存処理で突然ダイアログが立ち上がり、プロセスが完全にハングアップする(止まる)」という現象だ。
特に、`AcadDocument.SaveAs`メソッドを用いたバージョン互換保存や、DXF形式へのコンバージョンにおいて、仕様の裏側を知らずにコードを書くことは、時限爆弾を抱えるようなものである。
今回は、AutoCAD VBAの根幹をなすオブジェクトモデルと、`AcSaveAsType`列挙型の正確な操り方、そして実務の現場で絶対に避けて通れない「警告ダイアログの完全ハック」について、チーフアーキテクトである私がロジカルかつシャープに伝授しよう。
—
1. なぜ初心者は `SaveAs` でつまずくのか?
AutoCADのファイル保存は、単なるOSのファイルI/Oではない。背後で強固なデータベースエンジンが稼働しており、図面(Database)のバージョン、現在の図面状態、そしてアプリケーションのUIロック状態が複雑に絡み合っている。
初心者がやりがちな典型的なアンチパターンはこうだ:
‘ 【悪手】エラーを生む危険なコード
Sub BadSaveExample()
Dim acadDoc As AcadDocument
Set acadDoc = ThisDrawing
‘ パラメータを省略、または不適切な形式を指定
acadDoc.SaveAs “C:\Work\Output.dwg”
End Sub
このコードの何が問題か?
1. バージョン不整合: 実行しているAutoCADのネイティブバージョンで保存されるため、古いAutoCADを使っている取引先へ渡した際、ファイルが開けなくなる。
2. ダイアログの暴発: 同名のファイルが既に存在する場合や、特定のオブジェクト制約に引っかかった場合、裏でCADがダイアログを出してユーザーのクリックを待ち、VBAの処理が永久にフリーズする。
プロの業務自動化エンジニアであれば、どのような環境であっても「無人(ヘッドレス)で確実に、意図したバージョンのファイルを吐き出す」設計にしなければならない。
—
2. `AcSaveAsType` 列挙型とバージョン指定の全貌
古いバージョンのDWGやDXFを出力するには、`SaveAs` メソッドの第2引数である `vFileType` に、適切な `AcSaveAsType` を渡す必要がある。
しかし、ここにはAutoCAD特有の歴史的背景(バージョンごとのフォーマット変更)が影を落としている。実務で頻繁に使う主要な定数を以下に整理する。
| パラメータ(AcSaveAsType) | 意味・対象バージョン |
| :— | :— |
| `acR12DXF` | AutoCAD R12/LT2 DXF |
| `ac2000_DWG` / `ac2000_DXF` | AutoCAD 2000 形式 |
| `ac2004_DWG` / `ac2004_DXF` | AutoCAD 2004 形式 |
| `ac2007_DWG` / `ac2007_DXF` | AutoCAD 2007 形式 |
| `ac2010_DWG` / `ac2010_DXF` | AutoCAD 2010 形式 |
| `ac2013_DWG` / `ac2013_DXF` | AutoCAD 2013 形式 |
| `ac2018_DWG` / `ac2018_DXF` | AutoCAD 2018 以降の形式 |
※環境(参照設定しているAutoCADのタイプライブラリ)によっては、最新のバージョン定数が定義されていない場合がある。その場合は、数値リテラル(内部値)で渡すか、適切な早期バインディングを行うこと。
—
3. 警告ダイアログをねじ伏せる!実務向けプロダクションコード
ここからが本記事の核心だ。
「既存ファイルを上書きするときの警告」や「プロキシ図形に関する警告」を完全にシャットアウトし、バッチ処理や大規模な図面変換スクリプトとして耐えうる堅牢なコードを提供する。
AutoCADでダイアログを抑制するには、システム変数 `FILEDIA` を一時的に `0`(オフ)に設定するのが鉄則である。
【コピペ推奨】堅牢なセーブ・アズ・エンジン
Option Explicit
Public Sub ProductionSaveAs()
Dim targetDoc As AcadDocument
Set targetDoc = ThisDrawing ‘ もしくは外部から開いたAcadDocument
Dim filePath As String
filePath = “C:\AutoCAD_Output\Converted_Drawing_2013.dwg”
‘ 1. エラーハンドリングの準備
On Error GoTo ErrorHandler
‘ 2. アプリケーションの画面描画とダイアログを抑制(爆速化&フリーズ防止)
Dim originalFileDia As Integer
Dim originalEcho As Integer
With ThisDrawing.Application
originalFileDia = .GetSystemVariable(“FILEDIA”)
originalEcho = .GetSystemVariable(“CMDECHO”)
‘ ダイアログ無効化
.SetSystemVariable “FILEDIA”, 0
‘ コマンドラインのエコーバック無効化
.SetSystemVariable “CMDECHO”, 0
.ScreenUpdating = False
End With
‘ 3. 既存ファイルの事前削除(上書き時のトラブルを防ぐ防衛策)
If Dir(filePath) <> “” Then
Kill filePath
End If
‘ 4. バージョンを指定して保存執行
‘ 例:AutoCAD 2013 形式のDWGとして保存する場合
targetDoc.SaveAs filePath, ac2013_DWG
‘ 5. 正常終了時のクリーンアップ
Call RestoreEnvironment(originalFileDia, originalEcho)
MsgBox “図面の保存が正常に完了しました。”, vbInformation, “自動化システム”
Exit Sub
ErrorHandler:
‘ 異常終了時も必ずシステム環境を元に戻す(戻し忘れるとユーザーが地獄を見る)
Call RestoreEnvironment(originalFileDia, originalEcho)
MsgBox “致命的なエラーが発生しました: ” & Err.Description, vbCritical, “エラー”
‘ 必要に応じてログ出力処理をここに記述
End Sub
‘ 環境変数を安全に復元するプライベートプロシージャ
Private Sub RestoreEnvironment(ByVal fileDia As Integer, ByVal cmdEcho As Integer)
On Error Resume Next
With ThisDrawing.Application
.SetSystemVariable “FILEDIA”, fileDia
.SetSystemVariable “CMDECHO”, cmdEcho
.ScreenUpdating = True
End With
On Error GoTo 0
End Sub
—
4. チーフアーキテクトからの実践的アドバイス
上記のコードを見ればわかる通り、プロのVBAコードには「単に動く」以上の思想がある。現場で運用する上で、以下の3点を心に刻んでおいてほしい。
① `On Error` を使う時は必ず環境変数の復元を保証する
`FILEDIA` を `0` にしたままエラーでマクロが落ちると、その後の手動操作でダイアログ一切出なくなるという、エンドユーザーにとって大迷惑なバグを残すことになる。必ずエラーハンドラや終了直前で `RestoreEnvironment` を通す設計にすること。
② 大量処理(バッチ処理)でのメモリリーク対策
複数枚の図面を次々に `Open` して `SaveAs` し、`Close` するようなバッチ処理を書く場合、VBAのオブジェクト参照がメモリリークを起こしやすい。
ループ内では必ず `Set targetDoc = Nothing` を明示し、定期的にガベージコレクションを意識したコード構造にすることが、何千枚もの図面変換を完遂させるための極意である。
総括
`AcadDocument.SaveAs` は、ただメソッドを呼び出すだけでは実務の荒波を乗り越えることはできない。
ファイル形式の選定(`AcSaveAsType`)、システム変数 `FILEDIA` によるダイアログの制御、そして鉄壁のエラーハンドリング。これらを網羅したコードこそが、あなたの業務を真に自動化し、エンジニアとしての信頼を勝ち取る武器となる。
次の自動化開発から、ぜひこの設計を取り入れてほしい。
