【実務・中級編】【実務中級者向け】ISAVEBAKシステム変数の制御:VBA処理中のバックアップファイル(.bak)生成を抑制し高速化 – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD VBAを掌握する極限の知見:ISAVEBAK制御による大量図面処理の高速化とストレージ最適化

開発プロジェクトの現場において、VBAによる図面の一括処理(バッチ処理)は避けて通れない要件の一つだ。何百枚、何千枚というDWGファイルをループさせ、プロパティを書き換えたり、レイアウトを整えたりして上書き保存していく――。

君は、そのルーチンワークの裏で何が起きているか意識したことがあるか?

AutoCADはデフォルトで、図面を上書き保存する際、既存のファイルを `.bak`(バックアップ)ファイルとしてリネームし、新しい状態を新しい `.dwg` として書き出す。つまり、「1回のセーブにつき、OSレベルでのファイル削除・コピー・新規作成という重たいI/O(入出力)が強制的に発生している」のだ。

ネットワークドライブ上で数千枚の図面を処理したとき、処理が終わらない最大の原因はCPUパワー不足ではない。ストレージのI/Oボトルネックと、無意味な `.bak` 生成の嵐だ。

今回は、実務中級者に向けて、システム変数 `ISAVEBAK` を完全掌握し、堅牢かつ爆速な図面一括処理を実現するアーキテクチャを伝授する。

—

なぜ `ISAVEBAK` の制御が必要なのか?

1. `.bak` 生成のメカニズムとコスト

AutoCADの標準動作では、`ISAVEBAK` は `1` に設定されている。この状態では、`Save` や `SaveAs` を実行するたびに以下のプロセスが走る。
1. 既存の `filename.bak` を削除
2. 現在の `filename.dwg` を `filename.bak` にリネーム
3. 内存上のデータを新しい `filename.dwg` として書き出し

これを数百枚単位のループ内で実行すれば、ストレージ(特にHDDや、負荷の高い共有NAS)へのアクセスはパンクする。

2. コード内で完結させるべき理由

手動で `ISAVEBAK` を `0` に変更させる運用は、ヒューマンエラーの温床となる。処理が途中でクラッシュした際、バックアップが無効化されたまま放置されるリスクもある。
だからこそ、VBAのコード内で「実行前の状態を退避」し、「処理中は無効化」、「異常終了時も含めて確実に元の状態へ復元」する堅牢なライフサイクル管理が必要なのだ。

—

堅牢な設計:エラーハンドリングと状態の保証

実務で使えるコードとは、正常系だけでなく「異常系」を完璧に支配しているコードを指す。
VBAでシステム変数を操作する場合、途中でエラー(ファイルロック、不正な図面データなど)が発生してコードが中断すると、システム変数が書き換わったままになり、ユーザーのその後の通常業務に悪影響を及ぼす。

これを防ぐためには、`On Error Goto` を用いた確実なクリーンアップ処理(トランザクション的な発想)が不可欠だ。

—

プロダクションコード例

以下のコードは、指定フォルダ内のすべてのDWGファイルに対して、バックアップ生成を停止した状態で高速一括保存(またはデータ処理)を行うプロシージャだ。そのままコピペしてプロジェクトに組み込めるクオリティに仕上げている。

Option Explicit

‘ =================================================================================
‘ módulo名: modBatchOptimization
‘ 概要: ISAVEBAKを制御し、大量DWGファイルの保存処理を極限まで高速化するモジュール
‘ =================================================================================

Public Sub BatchProcessDrawings()
Dim targetFolder As String
targetFolder = “C:\MyWork\TargetDrawings\” ‘ ※実務環境に合わせて変更してください

If targetFolder = “” Then Exit Sub

‘ 1. 実行前のシステム変数を退避
Dim originalIsavebak As Integer
Dim originalDbmod As Integer

On Error GoTo ErrorHandler

‘ AutoCADの画面描画をロックし、さらに速度を上げる(オプション)
‘ Application.ScreenUpdating = False ‘ 必要に応じて有効化

‘ 2. ISAVEBAKの現在値を保持し、0(バックアップ作成なし)に設定
originalIsavebak = ThisDrawing.GetVariable(“ISAVEBAK”)
ThisDrawing.SetVariable “ISAVEBAK”, 0

Debug.Print “【最適化開始】ISAVEBAK を 0 に設定しました。(旧設定: ” & originalIsavebak & “)”

‘ 3. フォルダ内のファイル走査と処理
Dim fileName As String
fileName = Dir(targetFolder & “.dwg”)

Dim fileCount As Long
fileCount = 0

Do While fileName <> “”
Dim fullPath As String
fullPath = targetFolder & fileName

‘ —————————————————————–
‘ 【重要】すでに開いている図面や、読み取り専用ファイルのハンドリング
‘ —————————————————————–
If Not IsFileOpen(fullPath) Then
‘ ドキュメントコレクションを開く(バックグラウンドまたは通常オープン)
Dim doc As AcadDocument
Set doc = Documents.Open(fullPath, True) ‘ ReadOnly = False

‘ — ここに図面に対する実務処理を記述 —
‘ 例: 画層の整理、特定の文字置換、属性の更新など
Call ExecuteCustomProcessing(doc)

‘ 保存(ISAVEBAK=0 の恩恵を受ける高速セーブ)
doc.Save

‘ 閉じる
doc.Close False ‘ 変更は保存済みなので破棄しながら閉じる
Set doc = Nothing

fileCount = fileCount + 1
Else
Debug.Print “スキップ(使用中): ” & fileName
End If

fileName = Dir()
Loop

‘ 4. 正常終了時のクリーンアップへ
GoTo CleanUp

ErrorHandler:
‘ 異常発生時のログ出力とユーザー通知
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical, “バッチ処理エラー”

CleanUp:
‘ 5. 【最重要】どのような結果であれ、必ずシステム変数を元の値に復元する
On Error Resume Next
ThisDrawing.SetVariable “ISAVEBAK”, originalIsavebak
‘ Application.ScreenUpdating = True
On Error GoTo 0

Debug.Print “【最適化終了】処理ファイル数: ” & fileCount & ” / ISAVEBAK を元の値(” & originalIsavebak & “)に復元しました。”
MsgBox “一括処理が完了しました。処理ファイル数: ” & fileCount, vbInformation, “完了”
End Sub

‘ =================================================================================
‘ 補助関数: 指定ファイルがすでに排他制御されていないか簡易チェック
‘ =================================================================================
Private Function IsFileOpen(ByVal filePath As String) As Boolean
Dim fileNum As Integer
fileNum = FreeFile

On Error Resume Next
Open filePath For Binary Access Read Write Lock Read Write As #fileNum
Close #fileNum

If Err.Number <> 0 Then
IsFileOpen = True ‘ 開かれている(ロックされている)
Else
IsFileOpen = False
InfoEnd:
End If
On Error GoTo 0
End Function

‘ =================================================================================
‘ 補助プロシージャ: 図面に対する個別処理をカプセル化
‘ =================================================================================
Private Sub ExecuteCustomProcessing(ByRef targetDoc As AcadDocument)
‘ ここに実際の業務ロジックを書く
‘ 例: すべてのレイアウトのページ設定を更新する、特定文字を探すなど
‘ targetDoc.ModelSpace …
End Sub

—

現場で役立つチーフアーキテクトからの実践アドバイス

1. トランザクション的思考の徹底
VBAにおいて `On Error Resume Next` の乱用は悪だが、「システム変数や環境設定の復元プロセス」に限っては、エラーを無視してでも確実に実行ラインを通すべきだ。上記のコードにある `CleanUp` ラベルへのジャンプ構造は、実務で絶対に落としてはならない定石である。

2. ストレージ特性の理解
SSD環境であれば `.bak` の有無による差は体感しにくいかもしれないが、大規模組織のファイルサーバー(NAS / SMB接続)上で数千ファイルを扱う場合、I/Oの往復回数が半分になる `ISAVEBAK = 0` の効果は、処理時間を数十分単位で短縮するほどのインパクトを持つ。

3. セキュリティとバックアップの代替え案
「バックアップを作らない」ということは、万が一スクリプトのバグで図面が破壊されたときに元に戻せないリスクを孕む。そのため、バッチ処理を実行する前には、必ず大元のプロジェクトフォルダ全体のスナップショット(ZIP圧縮や別フォルダへの退避コピー)をプログラム実行前に自動作成するラッパー処理を一段上に噛ませるのが、真のプロフェッショナルエンジニアの設計思想だ。

技術は単に動くだけでは不十分だ。リソースを理解し、リスクをコントロールし、保守性を担保して初めて「プロダクション品質」と名乗れる。この知見を君の現場の自動化スクリプトに組み込み、圧倒的なパフォーマンスを手に入れてほしい。

タイトルとURLをコピーしました