【極限の設計】AutoCADとSQL Serverの同期による、原子性を担保した自動リビジョン管理アーキテクチャ
図面管理の現場において、「ファイル名に手動でリビジョンを付与する」という行為は、エンジニアリングにおける「禁忌」である。それはヒューマンエラーの温床であり、データの整合性を破壊する脆弱なプロセスに他ならない。
真に堅牢な設計管理システムとは、図面ファイル(DWG)を単なる「データ塊」として扱うのではなく、「データベース(Single Source of Truth)に紐付けられた、特定の状態を持つオブジェクト」として定義することから始まる。
本稿では、AutoCAD VBAをオーケストレーターとし、SQL Serverをマスターとした、保存実行時にリビジョンを自動昇格させる「自動リビジョンアップ・システム」の極限的な実装手法を詳解する。単なるコードの提示ではない。オブジェクトのライフサイクル、トランザクションの整合性、そしてメモリ管理の深淵に触れていく。
1. アーキテクチャの設計思想:原子性の確保
このシステムの核心は、「ファイルシステムの書き込み」と「データベースの更新」という、本来性質の異なる二つの操作を、いかにして「一つの原子的な操作(Atomic Operation)」として扱うかにある。
もし、ファイルは保存されたが、DBの更新に失敗したらどうなるか? もし、DBは更新されたが、ファイル書き込みがネットワークエラーで中断されたら?
このような「不整合状態」を許容することは、システム設計者として敗北を意味する。
システムフロー
1. Pre-check: 保存対象のファイルが、DBに登録されているかを確認。
2. Version Fetch: SQL Serverから現在の最新リビジョン番号をロック付きで取得。
3. File Execution: 新しいリビジョン番号を付与したファイル名で `SaveAs` を実行。
4. DB Commit: ファイル保存の成功をトリガーに、DBの履歴テーブルへレコードを挿入。
5. Rollback Logic: いずれかのステップで失敗した場合、不整合を防ぐためのリカバリ処理を実行。
2. 実装の核心:堅牢なVBAモジュール
以下に、プロフェッショナルレベルの実装例を示す。ここでは、`ADODB` を用いたSQL Serverとの連携、およびWindows APIを用いたファイル状態の検証を組み込んでいる。
Option Explicit
' Windows API: ファイルのアクセス権限や存在確認をより低レイヤーで行うための宣言
' ネットワーク遅延や、アンチウイルスソフトによるファイルロックを検知するために使用
Private Declare PtrSafe Function GetFileAttributes Lib "kernel32" Alias "GetFileAttributesA" (ByVal lpFileName As String) As Long
Private Const INVALID_FILE_ATTRIBUTES As Long = &HFFFFFFFF&
' 定数定義
Private Const DB_CONN_STR As String = "Provider=SQLOLEDB;Data Source=SERVER_NAME;Initial Catalog=DWG_MGMT;Integrated Security=SSPI;"
''' <summary>
''' 図面のリビジョンアップ保存を実行するメインルーチン
''' </summary>
Public Sub ExecuteVersionedSave()
Dim acadDoc As AcadDocument
Set acadDoc = ThisDrawing
Dim currentPath As String
currentPath = acadDoc.FullName
' 1. 初期バリデーション: 未保存の新規図面は対象外
If currentPath = "" Then
MsgBox "この図面はまだ保存されていません。まずベースとなる図面を保存してください。", vbCritical
Exit Sub
End If
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim nextRev As Integer
Dim newFileName As String
Dim baseName As String
Dim folderPath As String
Dim success As Boolean
On Error GoTo ErrorHandler
' --- ステップ1: DB接続とリビジョン取得 ---
Set conn = New ADODB.Connection
conn.Open DB_CONN_STR
' SQL Server側で現在のMax(Revision)を取得
' ここでは、同時実行性を考慮し、SELECT ... WITH (UPDLOCK) 等の検討が必要(DB設計に依存)
Dim sql As String
sql = "SELECT MAX(Revision) FROM DrawingHistory WHERE FilePath = '" & Replace(currentPath, "'", "''") & "'"
Set rs = conn.Execute(sql)
If IsNull(rs.Fields(0).Value) Then
' 初回登録の場合
nextRev = 1
Else
nextRev = rs.Fields(0).Value + 1
End If
rs.Close
Set rs = Nothing
' --- ステップ2: 新しいファイル名の生成 ---
' 拡張子の前に _RevXX を付与する設計
folderPath = Left(currentPath, InStrRev(currentPath, "\"))
baseName = Left(currentPath, InStrRev(currentPath, ".") - 1)
newFileName = baseName & "_Rev" & Format(nextRev, "00") & ".dwg"
' --- ステップ3: AutoCADによるSaveAs実行 ---
' ここでメモリリークを防ぐため、オブジェクトのライフサイクルに注意する
acadDoc.SaveAs newFileName
' --- ステップ4: DBへの履歴書き込み (トランザクション) ---
conn.BeginTrans
Dim insertSql As String
insertSql = "INSERT INTO DrawingHistory (FilePath, Revision, SaveDate, UserID) " & _
"VALUES ('" & Replace(newFileName, "'", "''") & "', " & nextRev & ", GETDATE(), SYSTEM_USER)"
conn.Execute insertSql
' すべて成功した場合のみコミット
conn.CommitTrans
success = True
MsgBox "リビジョンアップ完了: " & vbCrLf & newFileName, vbInformation
CleanUp:
' --- ステップ5: 明示的なオブジェクト解放 (メモリ管理の極致) ---
' VBAにおいてCOMオブジェクトを適切に解放しないことは、AutoCADの不安定化に直結する
On Error Resume Next
If Not rs Is Nothing Then Set rs = Nothing
If Not conn Is Nothing Then
If conn.State = adStateOpen Then conn.Close
Set conn = Nothing
End If
Set acadDoc = Nothing
Exit Sub
ErrorHandler:
' 異常系:DBトランザクションのロールバック
If Not conn Is Nothing Then
If conn.State = adStateOpen Then
conn.RollbackTrans
MsgBox "DB更新に失敗したため、トランザクションをロールバックしました。", vbCritical
End If
End If
MsgBox "エラーが発生しました: " & Err.Description, vbCritical
Resume CleanUp
End Sub
3. 技術的深掘り:プロフェッショナルが留意すべき3つの要諦
① COMオブジェクトの明示的解放とメモリリーク
AutoCAD VBAにおいて、`Set obj = Nothing` は単なる作法ではない。AutoCADは巨大なメモリ空間を扱うプロセスであり、VBAから呼び出されるCOM(Component Object Model)オブジェクトの参照カウントが適切に管理されない場合、`SaveAs` のような重い処理の直後にメモリリークを引き起こし、最終的に「AutoCADが応答していません」という致命的なクラッシュを招く。
特に `ADODB.Connection` や `Recordset` は、ループ内やイベントハンドラ内で使用する場合、必ず `CleanUp` セクションで明示的に解放しなければならない。
② Windows APIによるファイル制御の補完
ネットワークストレージ(NAS)環境では、`SaveAs` を実行した瞬間に、OSやウイルス対策ソフトがファイルをスキャンし、ファイルロックをかけることがある。
本稿のコードでは簡略化しているが、実運用では `GetFileAttributes` や `CreateFile` を使用して、新しいファイル名が物理的に「書き込み可能(Exclusive Access可能)」な状態にあるかを、DB更新前に検証するプロセスを組み込むべきである。
③ データベース設計における「排他制御」
複数の設計者が同時に同じ図面を開き、それぞれが「保存」を押した場合の競合(Race Condition)を考慮せよ。
SQL Server側では、リビジョン取得時に `UPDLOCK` ヒントを使用し、他のセッションが同じパスに対して `MAX(Revision)` を計算できないようにロックをかける必要がある。これを行わないと、二人とも「Rev05」として保存しようとする、最悪の整合性崩壊が起こる。
4. 結論
自動リビジョンアップシステムは、単なる「ファイル名の自動変更ツール」ではない。それは、物理ファイルと論理データ(DB)の間に強固な規律をもたらすための、エンジニアリング・インフラストラクチャである。
このようなシステムを構築する際、我々に求められるのは、AutoCADのAPI知識だけではない。OSの挙動、データベースのトランザクション、そしてメモリのライフサイクルに対する、冷徹なまでの理解である。これこそが、レガシーな環境をモダンなエンタープライズ・アーキテクチャへと昇華させる、真のアーキテクトの仕事である。
