【テクニカル・上級編】【初心者向け】AcadDocument.NameとPathを組み合わせた「自動バックアップ」:保存実行時に別フォルダへタイムスタンプ付きコピーを作成する – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD VBAを掌握する極限の知見:保存連動型タイムスタンプ・バックアップ機構の実装

AutoCAD VBAの基礎として語られる `AcadDocument.Name` と `AcadDocument.Path`。この極めてプリミティブなプロパティの組み合わせは、単なる文字列結合のオモチャではない。実務の現場において、数千万円規模の設計データを守る防波堤となり得る、極めて重要なシステム連携のフックポイントである。

今回は、標準の「上書き保存」にフックし、一瞬にしてタイムスタンプ付きの別フォルダへ版管理バックアップを生成する、実務直結型の自動バックアップアーキテクチャを解説する。

1. なぜ「標準の自動保存(SAVEBAK)」では不十分なのか

AutoCADには標準で `BAK` ファイルを生成する機能がある。しかし、シニアエンジニアやインフラ管理者であれば誰もが知っている通り、標準の `.bak` には致命的な欠点がある。

  • 上書きの不可避性: 保存を行うたびに、直前の `.bak` が最新の `.bak` に上書きされるため、「昨日の朝の状態」に戻すといった中長期的なバージョン管理ができない。
  • 保存先の固定: 図面と同じディレクトリに生成されるため、ファイルサーバの容量圧迫や、フォルダ内の視認性低下を招く。

我々が求めるべきは、「保存の瞬間に、日時(タイムスタンプ)を刻んだ独立したバックアップファイルを、専用の安全なアーカイブ領域へ退避させる仕組み」である。これをAutoCAD VBAと `FileSystemObject (FSO)` の連携によって実現する。

2. アーキテクチャ設計の要諦

今回の実装における技術的な要所は以下の3点だ。

1. 未保存図面(新規図面)のハンドリング: `Path` が空文字列である状態(一度も保存されていない図面)のエラーハンドリング。
2. FSOによる堅牢なファイル操作: `VBA.FileζCopy` よりも、例外処理やフォルダ存在確認が強固な `Scripting.FileSystemObject` の採用。
3. ファイル競合と文字列構築の最適化: 1秒間に複数回の保存が行われた場合を考慮したタイムスタンプの粒度設計。

3. 実装コード:`ThisDrawing` モジュールへの統合

以下のコードを、対象図面またはテンプレートの `ThisDrawing` モジュールに配置する。
AutoCAD VBAでは、`AcadDocument` のイベント(`Saves` や `SaveComplete`)を利用することで、保存アクションを検知できる。

Option Explicit

‘ =================================================================================
‘ 圧倒的な堅牢性を持つ保存連動型バックアップシステム
‘ Architecture: AutoCAD VBA + FileSystemObject (FSO)
‘ =================================================================================

‘ バックアップを格納するルートディレクトリ(環境に合わせて変更すること)
Private Const BACKUP_ROOT_DIR As String = “C:\AutoCAD_Archive_Storage\”

Private Sub Document_SaveComplete(ByVal FileName As String)
‘ —————————————————————————–
‘ イベント: SaveComplete
‘ 解説: 図面の物理的な保存が完全に完了したタイミングで発火する。
‘ Savesイベントと異なり、保存失敗時のゴミファイル生成リスクがない。
‘ —————————————————————————–

On Error GoTo ErrorHandler

‘ FSOの遅延バインディング(参照設定の依存関係を排除し、他環境への移植性を担保)
Dim fso As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)

‘ 1. パスとファイル名の整合性チェック
Dim currentPath As String
Dim currentName As String
currentPath = Me.Path
currentName = Me.Name

‘ 新規図面(未保存)の場合はPathが空になるため処理をスキップ
If currentPath = “” Then Exit Sub

‘ 2. バックアップ先ディレクトリの動的生成(存在しない場合はツリーごと作成)
‘ 図面ごとのサブフォルダを切ることで、プロジェクト単位の管理を容易にする
Dim drawingTitle As String
drawingTitle = fso.GetBaseName(currentName)

Dim targetDir As String
targetDir = BACKUP_ROOT_DIR & drawingTitle & “\”

If Not fso.FolderExists(targetDir) Then
Call CreateDirectoryRecursive(fso, targetDir)
End If

‘ 3. タイムスタンプ付きファイル名の生成 (Format: 20231024_153022_DrawingName.dwg)
Dim timeStamp As String
timeStamp = Format(Now, “YYYYMMDD_HHNNSS”)

Dim backupFileName As String
backupFileName = timeStamp & “_” & currentName

Dim destinationFullPath As String
destinationFullPath = targetDir & backupFileName

‘ 4. ファイルの複製実行(Overwrite = True)
fso.CopyFile FileName, destinationFullPath, True

‘ クリーンアップ
Set fso = Nothing
Exit Sub

ErrorHandler:
‘ 実務環境ではログ出力やイベントビューアへの書き込みを推奨
MsgBox “自動バックアップの作成中に予期せぬエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“説明: ” & Err.Description, vbCritical, “CADバックアップ機構”

If Not fso Is Nothing Then Set fso = Nothing
End Sub

Private Sub CreateDirectoryRecursive(ByRef fso As Object, ByVal dirPath As String)
‘ —————————————————————————–
‘ 階層化されたディレクトリを再帰的に構築する堅牢なプロシージャ
‘ —————————————————————————–
Dim parentPath As String
parentPath = fso.GetParentFolderName(dirPath)

If Not fso.FolderExists(parentPath) Then
Call CreateDirectoryRecursive(fso, parentPath)
End If

If Not fso.FolderExists(dirPath) Then
fso.CreateFolder dirPath
End If
End Sub

4. チーフアーキテクトによるコード解説と深掘り知見

オブジェクトのライフサイクルとメモリ最適化

上記のコードでは、`CreateObject(“Scripting.FileSystemObject”)` を用いたレイトバインディング(遅延バインディング)を採用している。
VBAのプロジェクトウィンドウで「Microsoft Scripting Runtime」の参照設定を追加する手間を省き、他のPCへこのコード(またはアドイン)を配布した際の「参照切れ(Missing Reference)」エラーを完全に根絶するためだ。

また、プロシージャの終了時には `Set fso = Nothing` を明示的に実行し、COMコンポーネントが保持するメモリ参照を確実に解放している。AutoCADの長時間の連続稼働において、こうした細部でのメモリリーク対策が、CAD本体のクラッシュを防ぐ生命線となる。

`Saves` イベント vs `SaveComplete` イベント

初心者向けのサンプルでは `Document_Saves` が使われることが多いが、シニアエンジニアの視点ではこれは悪手である。`Saves` は「保存プロセスが開始された瞬間」に発火するため、ディスク容量不足やファイルロックによって保存が失敗した場合でも、バックアップ処理が走ってしまう矛盾が生じる。
そのため、本実装では「保存が完全に成功したこと」を保証する `SaveComplete` イベントをフックしている。

5. 現場への展開とさらなる拡張

この仕組みを組織全体に展開する場合、個別の図面に上記コードを書き込むのではなく、「acaddoc.lsp」または「AutoCADのアドイン(.NET/VBAのグローバルロード)」を通じて全ドキュメントのイベントを監視する構造に昇華させるべきである。

ファイル名とパスを操作する基本機能の裏側に、堅牢なエラーハンドリングとストレージ設計を組み合わせること。それこそが、レガシーと言われるVBA環境であっても、モダンで信頼性の高いエンジニアリングシステムを構築する唯一の道である。

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