【テクニカル・上級編】【外部データベース(SQL Server)連携】ADODBを用いた社内DBからのパラメータ取得とSolidWorksモデルの動的生成 – SolidWorks VBA解析バイブル

スポンサーリンク

SolidWorks VBAを掌握する極限の知見

【外部データベース(SQL Server)連携】ADODBを用いた社内DBからのパラメータ取得とSolidWorksモデルの動的生成

レガシーとモダンが交錯する製造業の現場において、設計自動化のボトルネックは常に「データのサイロ化」にある。ローカルのExcelシートをインプットにする時代は終わった。真にスケーラブルなエンジニアリングチェーンを構築するためには、全社共通の単一情報源(SSOT)であるSQL ServerなどのRDBMSとSolidWorksを直結させなければならない。

本稿では、VBA(Visual Basic for Applications)の限界領域を突き詰め、`ADODB`を用いた高速なデータベース接続と、SolidWorks APIのライフサイクルを完全に制御したオンデマンド・モデリング基盤の構築手法を、チーフアーキテクトの視点から余すところなく解説する。

1. アーキテクチャ設計の要諦:なぜADODBとSolidWorks APIの融合が必要なのか

多くのエンジニアは、データベースからの値の取得にExcelを仲介させる。しかし、数千レコードに及ぶ製品仕様マスターから動的にパラメータを引くたびにI/Oが発生する仲介方式は、システム全体のパフォーマンスを致命的に低下させる。

VBAから直接 `ADODB.Connection` および `ADODB.Recordset` を叩き、メモリ上でパラメータを完結させ、非表示(Silent)モードの `ModelDoc2` へ流し込む。このパイプラインを構築することで、人的ミスを排除した真のワンストップ・ジェネレータが完成する。

2. 実装コード:SQL Server連携型・動的パーツ生成エンジン

以下のコードは、SQL Serverから製品コード(ProductCode)をキーにパラメータ(寸法値)を取得し、アクティブなSolidWorksパーツの寸法(Global Variables / Dimensions)を書き換えて再構築(Rebuild)する実用的なモジュールである。

メモリリークを絶対に許さないVBAコーディング規約に則り、すべてのCOMオブジェクトとデータベース接続は確実に解放(`Nothing`代入)する設計としている。

Option Explicit

‘ =========================================================================
‘ 外部データベース連携・SolidWorks動的モデル生成エンジン
‘ Architecture: ADODB + SolidWorks API (ModelDoc2 / Dimension)
‘ =========================================================================
Public Sub GenerateModelFromDatabase()
‘ 接続文字列 (環境に合わせて変更してください)
Const DB_CONNECTION_STRING As String = _
“Provider=SQLOLEDB;Server=192.168.1.100;Database=EngineeringDB;Uid=AppUser;Pwd=SecurePassword123;”

Dim targetProductCode As String
targetProductCode = “PRD-2023-X99” ‘ 取得対象の製品コード

Dim conn As Object
Dim rs As Object
Dim sql As String

‘ SolidWorks オブジェクト
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim boolstatus As Boolean

On Error GoTo ErrorHandler

‘ ———————————————————————
‘ 1. ADODBを用いたSQL Serverからのパラメータ取得
‘ ———————————————————————
Set conn = CreateObject(“ADODB.Connection”)
conn.ConnectionTimeout = 15
conn.CommandTimeout = 30
conn.Open DB_CONNECTION_STRING

sql = “SELECT Length, Width, Height, HoleDiameter FROM T_ProductSpecs WHERE ProductCode = ‘” & targetProductCode & “‘”

Set rs = CreateObject(“ADODB.Recordset”)
rs.Open sql, conn, 3, 1 ‘ adOpenStatic, adLockReadOnly

If rs.EOF And rs.BOF Then
MsgBox “指定された製品コードがデータベースに存在しません: ” & targetProductCode, vbCritical, “DBエラー”
GoTo CleanUp
End If

‘ パラメータの変数格納
Dim valLength As Double
Dim valWidth As Double
Dim valHeight As Double
Dim valHoleDia As Double

valLength = rs.Fields(“Length”).Value
valWidth = rs.Fields(“Width”).Value
valHeight = rs.Fields(“Height”).Value
valHoleDia = rs.Fields(“HoleDiameter”).Value

‘ レコードセットとコネクションの早期解放
rs.Close
conn.Close
Set rs = Nothing
Set conn = Nothing

‘ ———————————————————————
‘ 2. SolidWorks APIの初期化とモデル操作
‘ ———————————————————————
Set swApp = Application.SldWorks
If swApp Is Nothing Then
MsgBox “SolidWorksが起動していません。”, vbCritical, “APIエラー”
Exit Sub
End If

Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。”, vbExclamation, “警告”
Exit Sub
End If

‘ ドキュメントタイプがパーツ(Part)であることを確認
If swModel.GetType() <> swDocPART Then
MsgBox “このマクロはパーツドキュメントでのみ実行可能です。”, vbCritical, “型エラー”
Exit Sub
End If

‘ ———————————————————————
‘ 3. パラメータの駆動とモデルの更新 (Dimension駆動)
‘ ———————————————————————
‘ 註: あらかじめモデル側に “D1@Boss-Extrude” などの寸法名が定義されている前提
boolstatus = SetDimensionValue(swModel, “Length@Sketch1”, valLength)
boolstatus = SetDimensionValue(swModel, “Width@Sketch1”, valWidth)
boolstatus = SetDimensionValue(swModel, “Height@Boss-Extrude”, valHeight)
boolstatus = SetDimensionValue(swModel, “HoleDia@Cut-Extrude1”, valHoleDia)

‘ 強制再構築 (Rebuild)
‘ swRebuildAll = 4
swModel.EditRebuild3

‘ ビューの強制更新
swModel.ViewZoomToFit2

MsgBox “データベースからのパラメータ適用とモデル生成が正常に完了しました。”, vbInformation, “完了”

CleanUp:
‘ ———————————————————————
‘ 4. メモリリーク防止のための完全解放
‘ ———————————————————————
On Error Resume Next
If Not rs Is Nothing Then rs.Close: Set rs = Nothing
If Not conn Is Nothing Then
If conn.State = 1 Then conn.Close
Set conn = Nothing
End If
Set swModel = Nothing
Set swApp = Nothing
Exit Sub

ErrorHandler:
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“Error Number: ” & Err.Number & vbCrLf & _
“Description: ” & Err.Description, vbCritical, “致命的エラー”
Resume CleanUp
End Sub

‘ =========================================================================
‘ ヘルパー関数: 寸法値の安全な書き換え
‘ =========================================================================
Private Function SetDimensionValue(ByRef model As SldWorks.ModelDoc2, ByVal dimName As String, ByVal value As Double) As Boolean
Dim swDispDim As SldWorks.DisplayDimension
Dim swDim As SldWorks.Dimension

Set swDispDim = model.Parameter(dimName)
If Not swDispDim Is Nothing Then
Set swDim = swDispDim.GetDimension()
‘ 値の設定 (単位はメートル法またはモデル依存。ここではミリメートルを想定し換算が必要な場合は調整)
‘ SetValue2の第2引数には設定コンフィギュレーションを指定 (swSetValue_InAllConfigurations = 1)
Dim setRes As Long
setRes = swDim.SetValue2(value, 1)
SetDimensionValue = (setRes = 0)
Else
SetDimensionValue = False
End If
End Function

3. チーフアーキテクトが教える現場の知見と落とし穴

COMオブジェクトのライフサイクル管理

VBAにおける `CreateObject` や暗黙的なインスタンス化は、ガベージコレクションのタイミングが曖昧である。特にSolidWorksのAPIとADODBを混在させる環境では、エラー発生時にCOMポインタがメモリ上に残り続け、SolidWorks自体がフリーズする原因(ゾンビプロセス)となる。必ず `On Error Goto` を用いたクリーンアップブロック(`CleanUp`)を実装し、明示的に `Nothing` を代入する鉄の掟を遵守せよ。

パフォーマンスの最適化:コネクションのプーリングとトランザクション

数千個のバリエーションを連続して自動生成するバッチ処理を組む場合、ループ内で毎回 `ADODB.Connection` の `Open` と `Close` を繰り返してはならない。接続コストがボトルネックとなるため、処理の最初で一度だけコネクションを張り、必要なレコードを一括取得(またはプリペアドステートメントを活用)する構造に昇華させるべきだ。

単位系(Unit System)の罠

SolidWorksのAPI内部処理は常に「メートル法(MKS: Meters, Kilograms, Seconds)」を基準として動作している。データベースから取得した値が「ミリメートル(mm)」である場合、そのまま `SetValue2` に渡すと意図したサイズの1000分の1のモデルが生成される惨劇を引き起こす。APIに渡す数値は必ずMKS系に換算(例: `value / 1000#`)するバリデーションを挟むこと。

結び

CADと外部DBの統合は、単なる「手間の削減」にとどまらない。それは、受注から設計データ生成までのリードタイムをゼロにし、エンジニアリングのあり方そのものを変革する基盤技術である。レガシーと言われるVBAであっても、背後にあるメモリモデルとAPIの仕様を骨の髄まで理解していれば、最前線で戦う強靭なエンタープライズ・システムを構築できる。

妥協なきコードを書け。それがプロフェッショナル・エンジニアの矜持である。

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