設計の聖域を統治せよ:SQL Serverと連動したDWGライフサイクル制御の極致
図面管理における最大の敗北は、エンジニアが「ファイルを開く」という単純な動作に、システムの制御権を放棄することにある。
多くの現場では、図面(DWG)は単なる「ファイル」として扱われ、誰でも、いつでも、望む通りに上書きできる。しかし、PLM(Product Lifecycle Management)の概念が不可欠な現代の設計環境において、それは致命的なリスクだ。承認済みの図面が誤って修正され、履歴が上書きされる。この「意図しない変更」を防ぐには、CADの操作系を、設計者の意志ではなく、「Single Source of Truth(信頼できる唯一の情報源)」であるデータベースのステータスに直結させなければならない。
本稿では、SQL Server上の図面ステータスをADODB経由で参照し、AutoCADのドキュメント・オープン・プロセスを動的に制御する、プロフェッショナル向けのアーキテクチャを解説する。これは単なる自動化ではない。設計プロセスに対する「統治」の確立である。
1. アーキテクチャの設計思想:SSOTへの拘束
我々が構築すべきは、AutoCADという「描画エンジン」を、SQL Serverという「意思決定エンジン」の末端デバイスとして位置づけるシステムである。
制御フローの定義
1. 要求: ユーザーが図面を開こうとする。
2. 検証: システムは図面のファイルパスをキーとして、SQL Serverへステータスを照会する。
3. 判定:
- `Status = ‘WIP’` (Work In Progress) $\rightarrow$ 通常モードでオープン。
- `Status = ‘Released’` (承認済み) $\rightarrow$ 読み取り専用 (ReadOnly) でオープン。
- `Status = ‘Locked’` (他者編集中) $\rightarrow$ オープンを拒否。
4. 実行: 判定結果に基づき、AutoCADの `Documents.Open` メソッドを適切な引数で呼び出す。
2. 実装:堅牢なデータベース・インターフェース
まず、ADODBを利用したデータベース接続層を構築する。ここで重要なのは、接続のオープンとクローズを厳格に管理し、メモリリークを徹底的に排除することだ。
Class Module: `clsDBManager`
オブジェクトのライフサイクルをカプセル化し、呼び出し元にDB接続の細部を意識させない。
'------------------------------------------------------------------------------
' Class: clsDBManager
' Purpose: SQL Serverとのセキュアかつ高速な通信を管理する
'------------------------------------------------------------------------------
Option Explicit
Private m_Conn As ADODB.Connection
Private m_ConnectionString As String
' コンストラクタ: 接続文字列の初期化
Private Sub Class_Initialize()
' 環境変数や設定ファイルから取得するのがプロフェッショナルの作法
m_ConnectionString = "Provider=SQLOLEDB;Data Source=YOUR_SERVER;Initial Catalog=CAD_PLM;Integrated Security=SSPI;"
End Sub
' デストラクタ: オブジェクトの明示的な解放
Private Sub Class_Terminate()
Call CloseConnection
End Sub
' 接続の確立
Public Function Connect() As Boolean
On Error GoTo ErrHandler
Set m_Conn = New ADODB.Connection
m_Conn.ConnectionString = m_ConnectionString
m_Conn.CursorLocation = adUseClient ' クライアントサイドカーソルを選択し、高速な読み取りを実現
m_Conn.Open
Connect = True
Exit Function
ErrHandler:
MsgBox "DB Connection Error: " & Err.Description, vbCritical
Connect = False
End Function
' 図面ステータスの取得
' Returns: 0: Unknown, 1: WIP (Editable), 2: Released (ReadOnly), 3: Locked
Public Function GetDrawingStatus(ByVal filePath As String) As Integer
Dim rs As ADODB.Recordset
Dim sql As String
If m_Conn Is Nothing Then Exit Function
' SQLインジェクション対策を考慮したクエリ(本来はパラメータ化クエリを推奨)
sql = "SELECT StatusID FROM DrawingMaster WHERE FilePath = '" & Replace(filePath, "'", "''") & "'"
Set rs = New ADODB.Recordset
rs.Open sql, m_Conn, adOpenStatic, adLockReadOnly
If Not rs.EOF Then
GetDrawingStatus = CInt(rs.Fields("StatusID").Value)
Else
GetDrawingStatus = 0 ' 未登録
End If
' リソースの即時解放
rs.Close
Set rs = Nothing
End Function
' 接続のクローズ
Public Sub CloseConnection()
If Not m_Conn Is Nothing Then
If m_Conn.State = adStateOpen Then m_Conn.Close
Set m_Conn = Nothing
End If
End Sub
3. 実装:AutoCAD制御エンジン
次に、取得したステータスに基づき、AutoCADのドキュメント・オブジェクトを制御するメインロジックを実装する。ここで極めて重要なのは、`Documents.Open` の `ReadOnly` 引数の動的制御である。
Standard Module: `modCADController`
'------------------------------------------------------------------------------
' Module: modCADController
' Purpose: ステータスに基づいた図面オープニング制御
'------------------------------------------------------------------------------
Option Explicit
' Windows API: ダイアログ表示の制御(レガシー環境での安定動作のため)
Private Declare PtrSafe Function MessageBox Lib "user32" Alias "MessageBoxA" ( _
ByVal hwnd As LongPtr, ByVal lpText As String, ByVal lpCaption As String, _
ByVal uType As Long) As Long
Public Sub OpenControlledDrawing()
Dim dwgPath As String
Dim dbManager As clsDBManager
Dim status As Integer
Dim targetDoc As AcadDocument
Dim isReadOnly As Boolean
' 1. ファイル選択(実運用ではダイアログまたはリストから取得)
dwgPath = "C:\Projects\Design_A_001.dwg"
' 2. DB接続とステータス確認
Set dbManager = New clsDBManager
If Not dbManager.Connect() Then
Exit Sub
End If
status = dbManager.GetDrawingStatus(dwgPath)
' 3. ステータス判定ロジック
Select Case status
Case 1 ' WIP: 通常モード
isReadOnly = False
Case 2 ' Released: 読み取り専用
isReadOnly = True
Case 3 ' Locked: 拒否
MsgBox "この図面は現在ロックされています。管理者に連絡してください。", vbExclamation
GoTo CleanUp
Case Else ' Unknown
MsgBox "図面ステータスが不明です。データベースを確認してください。", vbCritical
GoTo CleanUp
End Select
' 4. AutoCADドキュメントのオープン
' 引数: Name, ReadOnly
On Error Resume Next
Set targetDoc = ThisDrawing.Application.Documents.Open(dwgPath, isReadOnly)
If Err.Number <> 0 Then
MsgBox "ファイルのオープンに失敗しました: " & Err.Description, vbCritical
Else
If isReadOnly Then
' 読み取り専用で開いた際のユーザーへの通知(UI/UXの配慮)
MsgBox "【READ-ONLY MODE】承認済み図面として開きました。", vbInformation
End If
End If
On Error GoTo 0
CleanUp:
' 5. 徹底したメモリ管理
' 参照カウントをゼロにするため、明示的にNothingを代入
Set dbManager = Nothing
' targetDoc は AutoCAD 側が管理するため、ここでは解放しない
End Sub
4. 極限の知見:プロフェッショナルが守るべき「三原則」
このシステムを実稼働環境(Production)に投入する際、シニアエンジニアが注視すべきは、コードの美しさではなく、「システムの堅牢性と予測可能性」である。
① COMオブジェクトのライフサイクル管理
VBAにおいて、`Set obj = Nothing` は単なる作法ではない。AutoCADのような巨大なアプリケーションと外部DBを連携させる場合、オブジェクトの参照が残っているだけで、AutoCADのプロセスがゾンビ化したり、DBのセッションがロックされ続けたりする。
特に `ADODB.Recordset` や `Connection` は、エラー発生時に `CleanUp` ラベルへジャンプする際、必ず明示的に `Close` と `Nothing` を行う設計にせよ。
② Race Condition(競合状態)への洞察
本システムでは、DBのステータスを見てからファイルを開くまでの間に、極めて短い「タイムラグ」が存在する。
- ユーザーが「WIP」として開こうとした瞬間に、他のユーザーが「Released」へステータスを変更した。
この僅かな隙間(Race Condition)を考慮し、可能であれば `Documents.Open` の後に、再度図面内のプロパティやDBを照合する「二重チェック」の概念を持つことが、極限の設計である。
③ Windows APIによるUIの制御
標準の `MsgBox` は、呼び出し元のスレッドをブロックする。大規模な自動化プロセスの中で、ユーザーの入力を待つ時間がシステム全体のパフォーマンスを低下させる。
高度なシステムでは、Windows APIを用いて、非同期的なメッセージングや、AutoCADのメインウィンドウを親としたモーダルダイアログを制御し、ユーザーの操作ミスを物理的に防ぐ設計が求められる。
結言
図面管理の自動化とは、単に「楽をする」ための技術ではない。
それは、「人間のミスが介在する余地を、システム的に抹殺する」ためのエンジニアリングである。SQL ServerとAutoCADを、単なるツールとしてではなく、一つの統合された「秩序」として結合せよ。それが、真のアーキテクトが進むべき道である。
