【AutoCAD VBAを掌握する極限の知見】実行環境のバージョンを自動判別し、最適なSaveAsTypeを動的に選択する堅牢なファイル保存アーキテクチャ
開発現場で最も恐れられる瞬間の一つ。それは、最新のAutoCAD 2024で開発・実行したマクロが、旧世代の環境(例えばAutoCAD 2018)で動作する他部署にファイルを配布した途端、「保存形式のミスマッチ(エラー番号: -2147467259 など)」によって容赦なくクラッシュするというトラブルだ。
「なぜこの書き方は非効率なのか」
素朴な開発者は、コード内に `ac2018` や `ac2023` といった列挙体(AcSaveAsType)をハードコーディングしがちだ。しかし、ホストアプリケーションのバージョンよりも新しい保存形式を指定して `SaveAs` メソッドを叩いた瞬間、容赦なくCOM例外が発生する。逆に、常に古い形式(例:R12 DXFや2000形式など)で保存し続ければ、最新のDWGが持つ高度なオブジェクト(カスタムオブジェクトやジオメトリの拡張データ)をスポイルしてしまう。
真にプロフェッショナルな業務自動化エンジニアであれば、実行環境のAutoCADバージョンを起動時に動的にプローブ(検出)し、「その環境が許容する最大の互換形式」を自動選択してセーブを実行するロジックを組み込むべきだ。
今回は、バージョン互換の泥沼から完全に抜け出すための、プロダクション品質の堅牢な設計と実装コードを伝授する。
—
1. アーキテクチャ設計の要諦:なぜ「動的解決」が必要なのか
AutoCAD VBAの `Application.Version` プロパティは、ホストのメジャーバージョンを文字列(例:”24.2″ や “25.0”)で返す。この数値を安全にパースし、対応する `AcSaveAsType` 列挙体に安全にマップするラッパー関数を構築する。
ここで重要なのは、「保存形式は、常にホスト自体のバージョン、あるいはそれ以下でなければならない」という大原則だ。
例えば、AutoCAD 2021(Ver.24.0)のエンジンは、AutoCAD 2018形式での保存をサポートしているが、AutoCAD 2024形式での保存はネイティブにはサポートしない(※SaveAsTypeの列挙体に存在しないか、実行時エラーになる)。
したがって、以下のロジックを実装する。
1. 現在のAutoCADのバージョン文字列を取得する。
2. バージョンに応じた「安全な最高保存形式」を決定する。
3. `ActiveDocument.SaveAs` を実行する。
—
2. プロダクションコード:動적バージョン判別・最適保存モジュール
以下のコードは、エラーハンドリングとライフサイクル管理を徹底した、そのまま実務で使えるクラス・標準モジュールの実装例である。
Option Explicit
‘ ==============================================================================
‘ モジュール名: MdlSaveController
‘ 概要: 実行環境のAutoCADバージョンを動的に判別し、最適なSaveAsTypeを返す
‘ ==============================================================================
‘ AutoCADの主要な保存形式列挙体(AcSaveAsTypeの主要なものを網羅)
‘ ※環境によって参照設定のバージョンが異なるため、明示的に数値でフォールバックも考慮する
Public Enum ESafeSaveType
sverUnknown = 0
sverR12DXF = 1
sver2000_DWG = 12
sver2004_DWG = 24
sver2007_DWG = 36
sver2010_DWG = 48
sver2013_DWG = 64
sver2018_DWG = 65
sver2025_DWG = 66 ‘ 将来拡張用
End Enum
”
‘ 現在実行中のAutoCAD環境に最適化された、安全な最高保存形式を取得する
‘ @return ESafeSaveType 最適な保存形式
‘
Public Function GetOptimalSaveAsType() As Long
On Error GoTo ErrorHandler
Dim rawVersion As String
Dim majorVersion As Integer
‘ Application.Version は “24.2” などの文字列を返す
rawVersion = ThisDrawing.Application.Version
majorVersion = Val(Split(rawVersion, “.”)(0))
‘ AutoCADのバージョン(メジャー番号)に基づく動的マッピング
‘ 24 = AutoCAD 2021, 25 = AutoCAD 2024, 26 = AutoCAD 2025 想定
Select Case majorVersion
Case Is >= 25 ‘ AutoCAD 2024以降
‘ 2018形式をデフォルトの安全策とする(社内標準や外部クライアントとの互換性を考慮)
‘ 必要に応じて ac2024 / Sver2025_DWG に引き上げることも可能
GetOptimalSaveAsType = ac2018_DWG
Case 24 ‘ AutoCAD 2021 ~ 2023
GetOptimalSaveAsType = ac2018_DWG
Case 23 ‘ AutoCAD 2019 ~ 2020
GetOptimalSaveAsType = ac2018_DWG
Case 22 ‘ AutoCAD 2018
GetOptimalSaveAsType = ac2018_DWG
Case Is <= 21 ' AutoCAD 2017以前 (2013/2014/2015/2016) ' 2013形式に安全にダウングレード GetOptimalSaveAsType = ac2013_DWG Case Else ' 想定外の旧バージョン、または未来のバージョンに対するフォールバック GetOptimalSaveAsType = ac2000_DWG End Select Exit Function ErrorHandler: ' 予期せぬ例外時は最も互換性の高い 2000形式 にフォールバック Debug.Print "【警告】バージョン判別失敗。デフォルト(2000形式)でフォールバックします。Error: " & Err.Description GetOptimalSaveAsType = ac2000_DWG End Function '' ' 指定されたファイルパスに対して、環境依存エラーを起こさない安全な保存を実行する ' @param targetDoc 対象のAcadDocument ' @param filePath 保存先のフルパス ' @return Boolean 成功時はTrue ' Public Function SafeSaveAs(ByRef targetDoc As AcadDocument, ByVal filePath As String) As Boolean On Error GoTo ErrorHandler SafeSaveAs = False If targetDoc Is Nothing Then Err.Raise 9999, "SafeSaveAs", "対象のドキュメントが取得できません。" End If ' ファイルパスのバリデーション If Trim(filePath) = "" Then Err.Raise 9998, "SafeSaveAs", "保存先のファイルパスが空です。" End If ' 実行環境に合わせた最適な保存形式を取得 Dim saveType As Long saveType = GetOptimalSaveAsType() ' デバッグ出力(運用時のトレーサビリティ確保) Debug.Print "INFO: ターゲットファイル [" & filePath & "] を形式 [" & saveType & "] で保存します。" ' 保存実行 targetDoc.SaveAs filePath, saveType SafeSaveAs = True Exit Function ErrorHandler: ' 致命的な保存エラーの捕捉 MsgBox "図面の保存中に致命的なエラーが発生しました。" & vbCrLf & _ "エラー番号: " & Err.Number & vbCrLf & _ "詳細: " & Err.Description, vbCritical, "AutoCAD VBA 自動保存エンジン" SafeSaveAs = False End Function ---
3. 実務運用における極意とデータベース連携の注意点
このモジュールを実際の業務自動化パイプライン(例えば、何百枚ものDWGを夜間に一括処理するバッチスクリプトなど)に組み込む際、以下のポイントを抑えておかないと予期せぬ手戻りが発生する。
① 参照設定の「遅延バインディング」と「定数」の扱い
異なるAutoCADバージョン間をまたぐ場合、VBAの「参照設定(Type Library)」のバージョン差異が原因でコンパイルエラーになることがある。
コード中の `ac2018_DWG` などの列挙体は、AutoCADのタイプライブラリに依存している。もし参照設定の不整合が怖い場合は、列挙体の代わりに直接数値(例:`ac2018_DWG` なら `65`)をハードコードするか、上記のように独自Enumでラップしてバインディングの安全性を高めるのがプロの技だ。
② データベース(外部連携)とのトランザクション整合性
大量の図面をバッチ処理で `SaveAs` する場合、図面データベース(`AcDbDatabase`)のメモリリークや、オブジェクトのオープン・クローズの不整合が蓄積し、後半の処理でAutoCAD自体がフリーズすることがある。
- 処理の最後には必ず `ThisDrawing.Close False` (変更を破棄して閉じる、または保存済みなのを確認して閉じる)を明示的に挟む。
- `ActiveDocument` への過度な依存を避け、極力オブジェクト変数をローカルスコープで完結させ、ガベージコレクション(VBAの場合はNothing代入による参照解放)を徹底する。
—
4. チーフアーキテクトからの総括
「動くコードを書くこと」と「壊れないシステムを構築すること」の間には、途方もなく深い溝がある。
今回紹介した「環境適応型の保存形式選択ロジック」は、単なるバージョンチェックのコードに留まらない。それは、「クライアントの環境差異という、コントロール不能なリスクをコードの柔軟性でねじ伏せる」という、エンジニアリングの美学そのものだ。
現場のバラバラなAutoCAD環境に頭を悩ませる日々は、今日で終わりにしよう。このモジュールをあなたの自動化ライブラリのコアに組み込み、圧倒的な堅牢性を手に入れてほしい。
