【実務・中級編】【上級プロフェッショナル向け】SQL Server上の「図面ステータス」と連動した、編集権限チェック付きオープンシステム – AutoCAD VBA解析バイブル

スポンサーリンク
スポンサーリンク

【設計思想】SQL Serverと連動した「権限制御型」図面オープンシステムの構築術

業務自動化の現場において、多くの開発者が陥る「罠」がある。それは、「AutoCADの操作」と「データの整合性」を切り離して考えてしまうことだ。

単に `Documents.Open` を実行して図面を開く。それは「スクリプト」であって「システム」ではない。真のプロフェッショナルが構築すべきは、図面ファイルそのものではなく、「図面がどのような状態にあるべきか」というビジネスルールを強制する制御レイヤーである。

本記事では、SQL Server上の図面ステータス(承認済み/編集可)と連動し、ADODBを用いて動的に読み取り専用モードを切り替える、堅牢なPLM(Product Lifecycle Management)連携システムの設計と実装について解説する。

1. なぜ「ファイル操作」ではなく「ステータス管理」なのか

設計者やエンジニアが誤ったステータスの図面を編集し、そのまま上書き保存してしまう。これは製造業における設計変更管理において致命的な事故だ。

「ファイルが書き込み可能だから開く」というロジックは、Windowsのファイルロックには対応できても、「組織としての承認プロセス」には対応できない。

理想的なアーキテクチャ

我々が目指すべきは、以下の3層構造である。

1. Data Layer (SQL Server): 図面の「真実(Single Source of Truth)」を保持する。パス、ステータス(Draft, Approved, Released)、最終更新者などを管理。
2. Logic Layer (VBA Class): DBからステータスを読み取り、AutoCADへ渡す「命令」を生成する。
3. Presentation Layer (AutoCAD): 命令に従い、`ReadOnly` フラグを制御して図面を展開する。

2. 陥りやすい設計上の落とし穴:リソースの管理

実装に入る前に、設計者が絶対に避けるべき2つの致命的なミスを伝えておく。

① ADODB接続の「開きっぱなし」

DBへの接続(Connection)は、クエリが終わるたびに即座に閉じる必要がある。VBAはメモリ管理が甘いため、接続を保持し続けると、サーバー側のコネクションプールを食いつぶし、最終的にシステム全体を停止させる。

② 例外処理の欠如による「ゾンビプロセス」

DB接続エラーやネットワーク切断が発生した際、適切にエラーハンドリングが行われていないと、AutoCADはフリーズするか、あるいは「図面は開いていないが、VBAのメモリ上には接続情報だけが残る」という中途半端な状態に陥る。

3. プロダクションクオリティのコード実装

ここでは、保守性と再利用性を極限まで高めるため、標準モジュールにコードを羅列するのではなく、クラスモジュールを用いたカプセル化を採用する。

クラスモジュール: `clsDrawingManager`

このクラスは、DBとの通信と権限判定の責務を一身に担う。

' Class Module: clsDrawingManager
Option Explicit

' 列挙型によるステータスの定義(マジックナンバーを排除)
Public Enum DrawingStatus
    dsUnknown = 0
    dsDraft = 1      ' 編集可能
    dsApproved = 2   ' 読み取り専用
    dsReleased = 3   ' 読み取り専用(ロック)
End Enum

Private pConnectionString As String
Private pFilePath As String

' 初期化メソッド
Private Sub Class_Initialize()
    ' 本来は設定ファイルや環境変数から取得すべき
    pConnectionString = "Provider=SQLOLEDB;Data Source=YOUR_SERVER;Initial Catalog=YOUR_DB;Integrated Security=SSPI;"
End Sub

' 図面パスの設定
Public Property Let TargetFilePath(ByVal Value As String)
    pFilePath = Value
End Property

' 図面のステータスを取得し、権限を判定するメインロジック
' Returns: True if ReadOnly mode is required
Public Function IsReadOnlyRequired() As Boolean
    Dim conn As ADODB.Connection
    Dim rs As ADODB.Recordset
    Dim sql As String
    Dim statusValue As Integer
    
    IsReadOnlyRequired = False ' デフォルトはFalse
    Set conn = New ADODB.Connection
    Set rs = New ADODB.Recordset
    
    On Error GoTo ErrorHandler

    ' 1. DB接続
    conn.Open pConnectionString
    
    ' 2. ステータス照会 (図面パスをキーに検索)
    ' ※ SQLインジェクション対策として、実務ではパラメータ化クエリを推奨
    sql = "SELECT Status FROM DrawingTable WHERE FilePath = '" & Replace(pFilePath, "'", "''") & "'"
    
    rs.Open sql, conn, adOpenForwardOnly, adLockReadOnly
    
    If Not rs.EOF Then
        statusValue = rs.Fields("Status").Value
        
        ' 3. ステータスに基づいた権限判定
        Select Case statusValue
            Case dsDraft
                IsReadOnlyRequired = False
            Case dsApproved, dsReleased
                IsReadOnlyRequired = True
            Case Else
                ' 不明なステータスの場合は安全側に倒してReadOnlyにする
                IsReadOnlyRequired = True
        End Select
    Else
        ' DBに存在しない図面は、安全のためにReadOnlyで開くか、エラーを出す
        Err.Raise vbObjectError + 513, "clsDrawingManager", "図面情報がDBに見つかりません。"
    End If

CleanUp:
    ' リソースの確実な解放(重要!)
    If Not rs Is Nothing Then
        If rs.State = adStateOpen Then rs.Close
    End If
    Set rs = Nothing
    
    If Not conn Is Nothing Then
        If conn.State = adStateOpen Then conn.Close
    End If
    Set conn = Nothing
    Exit Function

ErrorHandler:
    MsgBox "【DBエラー】" & vbCrLf & Err.Description, vbCritical, "System Error"
    IsReadOnlyRequired = True ' エラー時は安全のためにReadOnly
    Resume CleanUp
End Function

標準モジュール: 実行制御

クラスを利用して、実際にAutoCADのドキュメントを開く処理を行う。

' Standard Module
Option Explicit

Sub OpenDrawingWithPermissionCheck()
    Dim acadApp As Object ' AutoCAD.Application
    Dim targetDoc As Object ' AutoCAD.Document
    Dim dwgManager As clsDrawingManager
    Dim targetPath As String
    Dim isReadOnly As Boolean
    
    ' ターゲット図面のパス(実際にはダイアログ等から取得)
    targetPath = "C:\Projects\Design_A_001.dwg"
    
    On Error GoTo FatalError
    
    ' AutoCADオブジェクトの取得
    Set acadApp = GetObject(, "AutoCAD.Application")
    
    ' 1. 管理クラスのインスタンス化と設定
    Set dwgManager = New clsDrawingManager
    dwgManager.TargetFilePath = targetPath
    
    ' 2. DB連携による権限チェック
    Debug.Print "Checking permission for: " & targetPath
    isReadOnly = dwgManager.IsReadOnlyRequired()
    
    ' 3. AutoCADでのオープン実行
    ' Documents.Open(Name, ReadOnly)
    ' ※ 第2引数のReadOnlyが、我々の設計の肝となる
    Set targetDoc = acadApp.Documents.Open(targetPath, isReadOnly)
    
    If isReadOnly Then
        MsgBox "この図面は承認済みのため、「読み取り専用」で開いています。", vbInformation, "Status: Approved"
    Else
        MsgBox "編集権限を確認しました。通常モードで開きます。", vbInformation, "Status: Draft"
    End If
    
    Set dwgManager = Nothing
    Exit Sub

FatalError:
    MsgBox "図面を開けませんでした。" & vbCrLf & Err.Description, vbCritical
    Set dwgManager = Nothing
End Sub

4. プロフェッショナルのための追加知見

このシステムを実戦投入するにあたり、以下の3点についても検討しておくべきだ。

A. ファイルロックの競合(Race Condition)

DB上で「編集可」となっていても、他のユーザーがWindowsレベルでファイルを開いている場合、AutoCADは「読み取り専用」として開くか、エラーを返す。DBのステータスとOSのファイルロック状態は必ずしも一致しない。`Documents.Open` の戻り値や、エラーハンドリングをさらに精緻化する必要がある。

B. SQLインジェクションへの配慮

上記のサンプルコードでは、簡略化のために文字列結合でSQLを生成している。しかし、ファイルパスに `’`(シングルクォート)が含まれる場合や、悪意のある入力があった場合に備え、実務では `ADODB.Command` オブジェクトを使用したパラメータ化クエリを徹底すること。

C. バージョン互換性の考慮

もし、DBに「図面バージョン」の概念があるなら、`Documents.Open` の前に、ファイル自体のバージョン(DWG形式)をチェックするロジックを組み込むべきだ。古いバージョンのAutoCADで新しい形式を開こうとしてクラッシュする、といった事態を防ぐためである。

結びに代えて

自動化エンジニアの価値は、「コードが動くこと」ではなく、「運用が破綻しない仕組みを作ること」にある。

単なるファイル操作を、データベースという「規律」に基づいたシステムへと昇華させる。この設計思想こそが、現場のエンジニアから信頼されるアーキテクトへの第一歩である。

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