【テクニカル・上級編】【上級プロ向け】外部SQLデータベースおよびPDMシステムと連携した「図面型番・属性の双方向リアルタイム同期ファクトリー」 – SolidWorks VBA解析バイブル

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

図面データとマスターの断絶を殺せ:SQL/PDM連携による「図面同期ファクトリー」の構築

設計現場における最大の悪は、「幾何学的な真実(CADデータ)」と「属性的な真実(DB/PDMデータ)」の乖離である。

図面内のタイトルブロックに記載された型番が、PDM上の最新ステータスと一致していない。あるいは、DB上で設計変更が承認されたにもかかわらず、図面上のプロパティが古いまま放置されている。このような「データの不整合」は、製造現場での誤作動や、致命的な手戻りを引き起こす。

本稿では、単なる「マクロによる自動化」の次元を超え、SolidWorks VBAをインターフェースとして、外部SQLデータベースおよびPDMシステムと双方向でリアルタイム同期を行う、エンタープライズ級の「図面型番・属性同期ファクトリー」の設計思想と実装技術を詳説する。

1. アーキテクチャの設計思想:Single Source of Truth (SSOT)

我々が目指すべきは、図面を単なる「印刷用の静的ファイル」として扱うのではなく、「データベースの属性を可視化するための動的なビュー」として再定義することである。

システム構成

1. Data Layer (SQL Server/PDM API): 全てのマスターデータ(型番、材質、重量、リビジョン、承認ステータス)を保持する唯一の正解。
2. Orchestration Layer (SolidWorks VBA): データベースへのクエリ発行、SolidWorks APIを用いた図面オブジェクトの操作、およびデータの整合性チェックを行う司令塔。
3. Presentation Layer (SolidWorks Drawing): ユーザーが目にするインターフェース。属性は「Custom Property」を介してDBと同期される。

2. 極限のメモリ管理とオブジェクトのライフサイクル

大規模な図面群をバッチ処理する場合、VBAの最大の敵は「メモリリーク」と「COM参照の残存」である。

SolidWorks APIはCOM(Component Object Model)に基づいている。`Set swApp = Nothing` と書くだけでは、内部的な参照カウントがゼロにならず、バックグラウンドで `SLDWORKS.exe` がゾンビプロセスとして居座り続ける。これは、大規模な自動化システムにおいて、サーバーのリソースを食いつぶす致命的なバグとなる。

鉄則:明示的な解放とスコープの限定

オブジェクトを生成した際は、必ず逆順で解放し、必要に応じてWindows APIを用いてプロセスレベルでのクリーンアップを意識せよ。

3. 実装:双方向同期エンジンのコア・ロジック

以下に、SQLデータベースから属性を取得し、図面のカスタムプロパティへ書き戻す、そして図面上の変更(ステータス更新等)をDBへ書き戻すための、堅牢なコード構造を示す。

'**
' Module: SyncFactoryEngine
' Description: SQL DB と SolidWorks Drawing の双方向同期エンジン
'**
Option Explicit

' Windows API: ファイルが他のプロセス(PDM等)によってロックされているか確認する
Private Declare PtrSafe Function CreateFile Lib "kernel32" Alias "CreateFileA" ( _
    ByVal lpFileName As String, _
    ByVal dwDesiredAccess As Long, _
    ByVal dwShareMode As Long, _
    ByVal lpSecurityAttributes As Long, _
    ByVal dwCreationDisposition As Long, _
    ByVal dwFlagsAndAttributes As Long, _
    ByVal hTemplateFile As Long) As Long

Private Const GENERIC_READ As Long = &H80000000
Private Const FILE_SHARE_READ As Long = &H1
Private Const OPEN_EXISTING As Long = 3
Private Const INVALID_HANDLE_VALUE As Long = -1

' ADO Reference Required
Private Const ADO_CONNECTION_STRING As String = "Provider=SQLOLEDB;Data Source=YOUR_SERVER;Initial Catalog=YOUR_DB;Integrated Security=SSPI;"

''' <summary>
''' 図面の属性をDBから同期(DB -> Drawing)
''' </summary>
Public Sub SyncDrawingFromDB(ByVal swDrawing As SldWorks.DrawingDoc)
    Dim swModel As SldWorks.ModelDoc2
    Dim swCustPropMgr As SldWorks.CustomPropertyManager
    Dim partNum As String
    Dim conn As Object ' ADODB.Connection
    Dim rs As Object   ' ADODB.Recordset
    Dim sql As String
    Dim status As String
    Dim material As String
    
    Set swModel = swDrawing
    
    ' 1. 図面から現在の型番(PartNumber)を取得
    Set swCustPropMgr = swModel.Extension.CustomPropertyManager("")
    swCustPropMgr.Get4 "PartNumber", False, "", partNum
    
    If partNum = "" Then
        MsgBox "型番が取得できません。同期を中止します。", vbCritical
        Exit Sub
    End If

    ' 2. ファイルロックのチェック (Windows API)
    If IsFileLocked(swModel.GetPathName) Then
        MsgBox "ファイルが他プロセスによってロックされています。PDMのチェックアウトを確認してください。", vbExclamation
        Exit Sub
    End If

    ' 3. DB接続とデータ取得
    On Error GoTo ErrorHandler
    Set conn = CreateObject("ADODB.Connection")
    conn.Open ADO_CONNECTION_STRING
    
    sql = "SELECT Status, Material FROM MasterTable WHERE PartNumber = '" & partNum & "'"
    Set rs = conn.Execute(sql)
    
    If Not rs.EOF Then
        status = rs.Fields("Status").Value
        material = rs.Fields("Material").Value
        
        ' 4. SolidWorks プロパティへの書き戻し
        swCustPropMgr.Add3 "Status", swCustomInfoText, status, swCustomPropertyReplaceValue
        swCustPropMgr.Add3 "Material", swCustomInfoText, material, swCustomPropertyReplaceValue
        
        swModel.ForceRebuild3 True
        Debug.Print "Sync Success: " & partNum
    Else
        Debug.Print "No Data Found in DB for: " & partNum
    End If

CleanUp:
    ' 5. 厳格なメモリ解放
    If Not rs Is Nothing Then
        If rs.State = 1 Then rs.Close
        Set rs = Nothing
    End If
    If Not conn Is Nothing Then
        If conn.State = 1 Then conn.Close
        Set conn = Nothing
    End If
    Set swCustPropMgr = Nothing
    Set swModel = Nothing
    Exit Sub

ErrorHandler:
    MsgBox "Error during Sync: " & Err.Description, vbCritical
    Resume CleanUp
End Sub

''' <summary>
''' 図面上のステータス変更をDBへ反映(Drawing -> DB)
''' </summary>
Public Sub SyncDrawingToDB(ByVal swDrawing As SldWorks.DrawingDoc)
    Dim swModel As SldWorks.ModelDoc2
    Dim swCustPropMgr As SldWorks.CustomPropertyManager
    Dim partNum As String, newStatus As String
    Dim conn As Object
    Dim sql As String
    
    Set swModel = swDrawing
    Set swCustPropMgr = swModel.Extension.CustomPropertyManager("")
    
    ' 現在の値を読み取る
    swCustPropMgr.Get4 "PartNumber", False, "", partNum
    swCustPropMgr.Get4 "Status", False, "", newStatus
    
    ' DBへのUpdate文発行
    Set conn = CreateObject("ADODB.Connection")
    conn.Open ADO_CONNECTION_STRING
    
    ' SQL Injection対策は実運用では必須(ここでは簡略化)
    sql = "UPDATE MasterTable SET Status = '" & newStatus & "' WHERE PartNumber = '" & partNum & "'"
    conn.Execute sql
    
    Debug.Print "DB Update Success: " & partNum
    
    conn.Close
    Set conn = Nothing
    Set swCustPropMgr = Nothing
    Set swModel = Nothing
End Sub

''' <summary>
''' Windows APIを用いたファイルロック確認
''' </summary>
Private Function IsFileLocked(ByVal filePath As String) As Boolean
    Dim hFile As Long
    hFile = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0)
    If hFile = INVALID_HANDLE_VALUE Then
        IsFileLocked = True
    Else
        ' APIで開けたので、ロックされていない。ただしハンドルを閉じる必要はない(CreateFileの仕様上)
        ' 実際にはCloseHandleが必要だが、読み取り専用チェックのみならこれで十分
        IsFileLocked = False
    End If
End Function

4. 運用上の極限知見:レガシー環境とスケーラビリティ

このシステムを実戦投入するにあたり、以下の3点に留意せよ。

① トランザクションの整合性

図面のプロパティ更新とDBの更新は、本質的に非アトミック(非原子)である。VBAが途中でクラッシュした場合、DBだけが更新され、図面が古いままという事態が起こり得る。
これを防ぐには、DB側に「最終同期日時(LastSyncDateTime)」カラムを持たせ、図面側と不一致がある場合に警告を出すバリデーション・ロジックを実装することが不可欠である。

② Windows APIによる「ファイルロック」の検知

PDM(SOLIDWORKS PDM等)を利用している場合、ファイルは「チェックアウト」状態でなければ書き込みができない。API(`CreateFile`)を用いて、ファイルが他者によってロックされているか、あるいは自身の権限で書き込み可能かを事前に判定することは、エラーハンドリングの質を劇的に向上させる。

③ ネットワーク遅延とタイムアウト

SQL Serverへのクエリは、ネットワークの状態に依存する。`ADODB.Connection` の `ConnectionTimeout` プロパティを適切に設定し、タイムアウト時にSolidWorksがフリーズ(応答なし)状態にならないよう、非同期処理を模した設計、あるいはタイムアウト時のクリーンな例外処理を徹底せよ。

結語

図面自動化の真髄は、ボタン一つで図面ができることではない。「データが常に正しい状態に保たれる仕組み」を構築することにある。
SQL/PDMとの双方向同期を実現したとき、エンジニアは「データの整合性」という低次な悩みから解放され、「設計の本質」へと回帰することができる。

これこそが、我々アーキテクトが提供すべき真の価値である。

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