【SolidWorks VBA極限活用】ADOとSQL Serverを用いた社内DBからの部品パラメータ自動インポート
CADと外部データベースの連携は、製造業における設計自動化の聖域である。多くの現場では、Excelファイルを仲介させた不安定なマクロや、手作業によるパラメータ入力が横行している。しかし、シニアエンジニアが目指すべき境地はそこではない。
SolidWorks VBAから直接ADO(ActiveX Data Objects)を用いて社内のSQL Serverへシームレスに接続し、型番や材質データをミリ秒単位で取得。モデルの数式(Global Variables / Dimensions)を瞬時に書き換える――このアーキテクチャを構築してこそ、真の「エンジニアリングチェーンの自動化」が達成される。
本稿では、単なるAPIのラッパーではない、メモリ管理の極意、ADOのライフサイクル最適化、そして堅牢なエラーハンドリングを網羅した実戦的コードベースを公開する。
—
1. アーキテクチャの全体像と設計思想
今回のシステムは、以下のパイプラインで動作する。
1. アクティブドキュメントの特定: 現在開いているSolidWorksモデル(`ModelDoc2`)から、ファイル名やカスタムプロパティをキー(型番等)として抽出。
2. SQL Serverへの高速接続: ADO (`ADODB.Connection` / `ADODB.Recordset`) を使用し、コネクションプーリングを意識したセキュアな接続を確立。
3. パラメータの取得: パラメータ化クエリ(Parameterized Query)により、SQLインジェクションを完全に排除しつつ高速にレコードを取得。
4. 数式・寸法の動的更新: `ModelDocExtension` の `AddEquation` または既存変数の書き換えにより、モデルをリビルド。
5. メモリの完全解放: COMオブジェクトの寿命(Life Cycle)を完全に制御し、VBA特有のメモリリークを根絶。
—
2. 実装コード:データベース連携とモデル自動更新エンジン
以下のコードは、SolidWorksの標準VBAモジュールにそのまま組み込み、即座に実運用できるプロダクションクオリティのコードである。
Option Explicit
‘ =========================================================================
‘ 処理名: SQL Server連携による部品パラメータ自動インポート
‘ 概要 : アクティブモデルのカスタムプロパティ(型番)をキーにDBから数値を取得し、
‘ グローバル変数(数式)を更新する。
‘ =========================================================================
Sub ImportParametersFromSQLServer()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swExt As SldWorks.ModelDocExtension
‘ 1. SolidWorks アプリケーションの取得
Set swApp = Application.SldWorks
If swApp Is Nothing Then Exit Sub
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。”, vbCritical, “DB連携エラー”
Exit Sub
End If
Set swExt = swModel.Extension
‘ 2. モデルから検索キー(型番)を取得する
Dim partNumber As String
partNumber = GetCustomProperty(swModel, “PartNumber”)
If Trim(partNumber) = “” Then
MsgBox “カスタムプロパティ ‘PartNumber’ が取得できないか、空です。”, vbExclamation, “中断”
Exit Sub
End If
‘ 3. ADOオブジェクトの宣言 (早期バインディングによるパフォーマンス最大化)
Dim conn As ADODB.Connection
Dim cmd As ADODB.Command
Dim rs As ADODB.Recordset
Set conn = New ADODB.Connection
Set cmd = New ADODB.Command
‘ 接続文字列 (環境に合わせて変更すること。OLE DB Providerを使用)
Dim connString As String
connString = “Provider=MSOLEDBSQL;Server=192.168.1.100\SQLEXPRESS;Database=EngineeringDB;Integrated Security=SSPI;TrustServerCertificate=Yes;”
On Error GoTo ErrorHandler
‘ データベース接続
conn.ConnectionTimeout = 5
conn.Open connString
‘ パラメータ化クエリの設定(セキュリティとプランキャッシュの最適化)
Set cmd.ActiveConnection = conn
cmd.CommandType = adCmdText
cmd.CommandText = “SELECT Width, Height, Thickness, Material FROM M_PartsMaster WHERE PartNo = ?”
‘ パラメータの追加
Dim param As ADODB.Parameter
Set param = cmd.CreateParameter(“PartNoParam”, adVarChar, adParamInput, 50, partNumber)
cmd.Parameters.Append param
‘ レコードセットの取得
Set rs = cmd.Execute
If rs.EOF And rs.BOF Then
MsgBox “指定された型番 [” & partNumber & “] に一致するレコードがDBに存在しません。”, vbExclamation, “データなし”
GoTo Cleanup
End If
‘ 4. 取得した値を変数に格納
Dim valWidth As Double
Dim valHeight As Double
Dim valThickness As Double
Dim strMaterial As String
valWidth = rs.Fields(“Width”).Value
valHeight = rs.Fields(“Height”).Value
valThickness = rs.Fields(“Thickness”).Value
strMaterial = Nz(rs.Fields(“Material”).Value, “Steel”)
‘ 5. SolidWorksのグローバル変数(数式)を更新
‘ すでに数式が存在する場合は更新、なければ追加する
Call SetGlobalVariable(swModel, “Width”, valWidth)
Call SetGlobalVariable(swModel, “Height”, valHeight)
Call SetGlobalVariable(swModel, “Thickness”, valThickness)
‘ 材質の適用(必要に応じてマテリアルデータベースと連携)
‘ swModel.SetMaterialPropertyName2 …
‘ 6. モデルのリビルド(変更を確実に反映)
Dim errors As Long
Dim warnings As Long
swModel.EditRebuild3
MsgBox “データベースからのパラメータインポートが完了しました。”, vbInformation, “成功”
Cleanup:
‘ =====================================================================
‘ 極限のメモリ管理:COMオブジェクトの明示的破棄 (逆順解放)
‘ =====================================================================
On Error Resume Next
If Not rs Is Nothing Then
If rs.State = adStateOpen Then rs.Close
Set rs = Nothing
End If
Set cmd = Nothing
If Not conn Is Nothing Then
If conn.State = adStateOpen Then conn.Close
Set conn = Nothing
End If
Exit Sub
ErrorHandler:
MsgBox “SQL Server連携エラー: ” & Err.Description, vbCritical, “致命的エラー”
Resume Cleanup
End Sub
‘ — ヘルパー関数: カスタムプロパティ取得 —
Private Function GetCustomProperty(ByVal model As SldWorks.ModelDoc2, ByVal propName As String) As String
Dim swCustPropMgr As SldWorks.CustomPropertyManager
Dim valOut As String
Dim resolvedValOut As String
Dim wasResolved As Boolean
‘ コンフィギュレーション固有 または ユーザー定義プロパティから取得
Set swCustPropMgr = model.Extension.CustomPropertyManager(“”)
swCustPropMgr.Get4 propName, False, valOut, resolvedValOut
GetCustomProperty = IIf(resolvedValOut <> “”, resolvedValOut, valOut)
End Function
‘ — ヘルパー関数: グローバル変数の設定(数式エンジン操作) —
Private Sub SetGlobalVariable(ByVal model As SldWorks.ModelDoc2, ByVal varName As String, ByVal val As Double)
Dim swEquationMgr As SldWorks.EquationMgr
Set swEquationMgr = model.GetEquationMgr()
Dim i As Long
Dim count As Long
Dim found As Boolean
Dim eqString As String
found = False
count = swEquationMgr.GetCount()
‘ 既存の数式を検索して書き換える
For i = 0 To count – 1
Dim currentEq As String
currentEq = swEquationMgr.Equation(i)
‘ 「”変数名” = 値」の形式をパース
If InStr(1, currentEq, “””” & varName & “”””, vbTextCompare) = 1 Then
eqString = “””” & varName & “”” = ” & val & “mm”
swEquationMgr.Equation(i) = eqString
found = True
Exit For
End If
Next i
‘ 存在しない場合は新規追加
If Not found Then
eqString = “””” & varName & “”” = ” & val & “mm”
swEquationMgr.Add -1, eqString
End If
End Sub
Private Function Nz(ByVal varVal As Variant, ByVal valIfNull As Variant) As Variant
If IsNull(varVal) Then Nz = valIfNull Else Nz = varVal
End Function
—
ジニアエンジニアとしての視点から、上記のコードに隠された3つのアーキテクチャ上の重要ポイントを解説する。
1. 早期バインディング(Early Binding)の徹底
コードの冒頭で `ADODB.Connection` などを直接生成している(要参照設定: `Microsoft ActiveX Data Objects x.x Library`)。実行時バインディング(`CreateObject`)は、COMの仮想メソッドテーブル(vtable)の解決を動的に行うため、数千回のクエリ実行や大規模なループ処理において致命的なボトルネックとなる。高頻度で実行されるCAD自動化スクリプトにおいては、早期バインディングによるオーバーヘッド削減が絶対条件である。
2. COMオブジェクトのライフサイクル管理と逆順解放
VBAのガベージコレクションは頼りにならない。特にSolidWorks APIと外部データベース(ADO)を混在させる環境では、オブジェクトの解放漏れがメモリリークやSolidWorks本体の突然のクラッシュ(Access Violation)を引き起こす。
コード内の `Cleanup` ラベルを見てほしい。
- レコードセット (`rs`)
- コマンド (`cmd`)
- コネクション (`conn`)
の順に、生成とは完全に逆の順序で `Set Nothing` を明示的に行っている。この規律を守る者だけが、24時間稼働する安定した自動化サーバー環境を手に入れることができる。
3. 数式マネージャー (`EquationMgr`) のスマートなハンドリング
SolidWorksで寸法を外部データ駆動型にする場合、ハードコードされた寸法値を直接いじるよりも、グローバル変数(Global Variables)を介する手法が圧倒的に堅牢である。
`EquationMgr` を操作する際、既に同名のグローバルが存在するかを走査し、存在すればインデックスを指定して更新、なければ新規追加(`-1` 指定)というロジックを組むことで、モデルのコンフィギュレーション構造を破壊せずにクリーンなパラメータ同期を実現している。
—
3. 現場で直面するトラブルシューティングと知見
- 接続タイムアウトとネットワークの揺らぎ:
社内LANやVPN経由のSQL Server接続では、パケットロスによるフリーズが発生しやすい。`conn.ConnectionTimeout = 5` のようにタイムアウトを必ず明示し、SolidWorksのUIスレッドが完全ロックされるのを防ぐこと。
- ドライバの選定:
レガシーな `Provider=SQLOLEDB` は現在非推奨である。最新の `MSOLEDBSQL`(Microsoft OLE Driver for SQL Server)を使用することで、TLS 1.2/1.3への対応やモダンな認証方式(統合セキュリティ等)を安全に利用できる。
総括
SolidWorks VBAは、単なる「お絵かきマクロ」の道具ではない。適切なアーキテクチャと堅牢なデータベース連携を組み合わせることで、企業の基幹システム(ERP/PDM)と直結した、真のエンジニアリング・オートメーション・プラットフォームへと昇華する。
オブジェクトの寿命を支配し、メモリの細部まで気を配る者だけが、CAD自動化の本当の果実を手にすることができる。コードを書き換え、今日の設計現場をアップデートせよ。
