【AutoCAD VBA極限チューニング】ISAVEBAK制御による大量図面処理の高速化とストレージ負荷最適化
業務自動化の現場において、数千枚単位のDWGファイルを一括処理・上書き保存するバッチ処理を設計したことがある者なら、誰もが一度はストレージのI/Oボトルネックと`.bak`ファイルの海原に絶望した経験を持つはずだ。
AutoCADはデフォルトで、図面を上書き保存する際に既存のファイルを`.bak`へとリネームし、新しいファイルを新規作成する挙動をとる。この設計は単体操作においては安全性の担保として機能するが、「VBAから数百・数千の図面を連続バッチ処理する」というシチュエーションにおいては、百害あって一利なしの最悪のオーバーヘッドとなる。
今回は、システム変数 `ISAVEBAK` をプログラムから完全に掌握し、バックアップ生成の抑止と、それに伴うI/O劇的改善、そして実務で絶対に避けて通れない「異常終了時のステート復旧(例外安全)」を担保する極限のアーキテクチャを提示する。
—
1. なぜ `ISAVEBAK` なのか?ストレージI/Oの本質的課題
大規模なCAD図面(例えば、複雑な外部参照や膨大なハッチング、プロキシオブジェクトを含む数十MBのDWG)をVBAの `ThisDrawing.Save` や `SendCommand` で連続保存すると仮定する。
バックアップ有効時(`ISAVEBAK = 1`)の内部処理:
1. 既存の `drawing.dwg` を `drawing.bak` にファイルシステム上でリネーム(またはコピー)。
2. メモリ上のドキュメントデータを新しい `drawing.dwg` としてストレージへフラッシュ。
この「リネーム + フル書き込み」のプロセスが、ネットワークドライブ(NAS)や低速なSSD上で数千回繰り返されると、OSのファイルハンドル競合やディスクシーク時間の増大により、処理時間が数倍から数十倍に膨れ上がる。さらに、不要な`.bak`ファイルがサーバー容量を圧迫し、ストレージ管理者を激怒させる原因となる。
システム変数 `ISAVEBAK` を `0` に設定することで、古いバックアップの作成プロセスそのものをバイパスし、「現在のDWGファイルへの上書き」のみにI/Oリソースを集中させることが可能となる。
—
2. 【実装コード】安全かつ高速なバッチ処理フレームワーク
シニアエンジニアが書くべきコードの絶対条件は、「途中でマクロがクラッシュしても、CADの環境が汚染されないこと」である。エラーハンドリングを怠り、`ISAVEBAK = 0` のままVBAが異常終了した場合、ユーザーは二度と自動バックアップが取られない恐怖のCAD環境で作業を続けることになる。
以下のコードは、RAII(Resource Acquisition Is Initialization)の概念をVBAの `On Error` 構文で模倣し、いかなる例外が発生しようとも確実にシステム変数を元の状態に復元する堅牢な構造を持っている。
Option Explicit
‘ =========================================================================
‘ módulo名: modBatchSaveOptimizer
‘ 概要: ISAVEBAKを制御し、図面の一括保存処理を極限まで高速化するモジュール
‘ ターゲット: AutoCAD VBA (2013 – 2024+)
‘ =========================================================================
Public Sub ExecuteHighSpeedBatchSave()
Dim originalIsavebak As Integer
Dim targetFolder As String
Dim fso As Object
Dim targetFile As Object
Dim doc As AcadDocument
Dim startTime As Double
Dim processedCount As Long
startTime = Timer
processedCount = 0
‘ 1. エラーハンドリングの有効化(環境汚染の防止)
On Error GoTo ErrorHandler
‘ 2. 処理対象フォルダの指定(実務ではUIや設定ファイルから取得)
targetFolder = “C:\AutoCAD_WorkSpace\TargetDrawings\”
Set fso = CreateObject(“Scripting.FileSystemObject”)
If Not fso.FolderExists(targetFolder) Then
MsgBox “指定されたフォルダが存在しません: ” & targetFolder, vbCritical, “致命的エラー”
Exit Sub
End If
‘ 3. 現在の ISAVEBAK の状態を退避(極めて重要)
originalIsavebak = ThisDrawing.GetVariable(“ISAVEBAK”)
‘ 4. バックアップ作成を禁止 (0) に設定
ThisDrawing.SetVariable “ISAVEBAK”, 0
‘ ついでにバックグラウンド保存 (SAVETHORIZ) も最適化する場合はここで制御可能
‘ ※環境によっては SAVETHORIZ を 0 にして同期書き込みを強制する方が安全な場合もある
‘ 5. 対象フォルダ内のDWGファイルをループ処理
For Each targetFile In fso.GetFolder(targetFolder).Files
If LCase(fso.GetExtensionName(targetFile.Name)) = “dwg” Then
‘ ドキュメントを開く(Visible = False でバックグラウンド処理も可能だが、
‘ 安定性を重視しアクティブドキュメントの切り替え、または Documents.Open を使用)
Set doc = Documents.Open(targetFile.Path, True) ‘ ReadOnly = False
‘ — ここに図面に対する一括処理(画層整理、属性変更など)を記述 —
‘ 例: Call ProcessDrawing(doc)
‘ 最適化された状態で上書き保存(.bakは生成されない)
doc.Save
‘ メモリ解放の徹底(COMオブジェクトの参照リークを防ぐ)
doc.Close False
Set doc = Nothing
processedCount = processedCount + 1
End If
Next targetFile
‘ 6. 正常終了時のクリーンアップ
ThisDrawing.SetVariable “ISAVEBAK”, originalIsavebak
Set fso = Nothing
MsgBox “一括処理が完了しました。” & vbCrLf & _
“処理ファイル数: ” & processedCount & ” 件” & vbCrLf & _
“実行時間: ” & Format(Timer – startTime, “0.00”) & ” 秒”, _
vbInformation, “最適化バッチ完了”
Exit Sub
ErrorHandler:
‘ 7. 例外発生時の安全装置(確実に変数を復元する)
On Error Resume Next
‘ 変数の復元
ThisDrawing.SetVariable “ISAVEBAK”, originalIsavebak
‘ オブジェクトの強制解放
If Not doc Is Nothing Then
doc.Close False
Set doc = Nothing
End If
Set fso = Nothing
MsgBox “エラーが発生したため処理を中断しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“エラー内容: ” & Err.Description & vbCrLf & _
“※システム変数 ISAVEBAK は安全に復元されました。”, _
vbCritical, “異常終了”
End Sub
—
3. チーフアーキテクトが教える、さらなるメモリ・I/O最適化の極意
上記のコードだけでも十分なパフォーマンス向上が得られるが、真のプロフェッショナルを目指すのであれば、以下の「隠れた罠」と「追加の最適化手法」を理解しておく必要がある。
① `Documents.Open` とメモリリークの呪縛
VBAから `Documents.Open` を多用すると、AutoCADの内部COMプロキシカウンタが肥大化し、ガベージコレクションが追いつかずにメモリリークを引き起こすことがある。
ループ内では必ず `Set doc = Nothing` を行い、さらに大規模な処理(例: 500ファイル以上)の場合は、一定数処理するごとにAutoCADを再起動するような外側からのプロセス制御(VBScriptやC#外形ランナーからの制御)を組み合わせるのが、レガシー環境を生き抜くシニアの知恵である。
② レジストリとドキュメントスコープの混同に注意
`ISAVEBAK` は図面データベース(DWGファイル内)に保存されるプロパティではなく、AutoCADアプリケーション全体の環境設定(レジストリ)に保存されるシステム変数である。
そのため、一度 `0` に変更すると、VBAが終了した後も、ユーザーが手動で開く図面にその設定が引き継がれる。これが「バックアップが急に出なくなった」というユーザーからの不具合報告の温床となる。
だからこそ、前述のコードのように必ず `On Error` を網羅し、処理終了時(または異常終了時)に元の値(通常は `1`)へ確実に巻き戻すコードデザインが絶対条件となるのだ。
—
総括
システム変数 `ISAVEBAK` の制御は、一見すると地味なテクニックに思えるかもしれない。しかし、数千枚の図面を扱うインフラ・プラント・建築の巨大プロジェクトにおいて、この最適化は「業務が夜間に終わるか、翌朝までサーバーを焼き続けるか」を分ける決定的な差異を生む。
小手先のコード記述に終始せず、「環境のライフサイクル管理」と「例外安全」を網羅したコードベースこそが、現場を救う唯一の武器となる。妥協なきアーキテクチャで、君のAutoCAD環境を極限まで研ぎ澄ませたまえ。
