SolidWorks VBAを掌握する極限の知見:外部DB連携型アセンブリ自動生成アーキテクチャ
レガシーとモダンが交錯する製造業の現場において、設計工数の削減は永遠の課題である。
「SQL Serverに格納された製品スペックを元に、一瞬で3Dアセンブリを構築し、合致関係まで完璧に定義する」。これをVBA単体、あるいは不完全なマクロの継ぎ合わせで実現しようとすれば、必ずメモリリーク、COMコンポーネントの解放漏れ、そしてCADのフリーズという絶望的な壁に突き当たる。
本稿では、SolidWorks APIのライフサイクルを知り尽くしたチーフアーキテクトの視点から、外部データベースと強固に連携し、実用に耐えうる堅牢性を持ったアセンブリ自動生成システムのアーキテクチャを解説する。
—
1. システムアーキテクチャの全体像
本システムは、以下の3層構造で設計する。
1. データ層 (SQL Server): 製品構成(BOM)、部品番号、座標データ、合致条件を保持。
2. 制御・通信層 (ADODB): VBAからSQL Serverへの高速アクセスとトランザクション管理。
3. CAD実行層 (SolidWorks API): ドキュメントのサイレントオープン、マトリックス配置、Mates(合致)のプログラム的解決。
VBAはシングルスレッドかつメモリ管理が脆弱な環境である。そのため、「いかにしてCOMオブジェクトのスコープを制御し、メモリリークを防ぐか」がアーキテクチャの成否を分ける。
—
2. 実装コード:DB連携・動的アセンブリ構築エンジン
以下に、SQL Serverからデータを取得し、部品の挿入から合致定義までを完全自動化する実用コードの核心を示す。
Option Explicit
‘ =========================================================================
‘ 外部データベース連携型アセンブリ自動生成エンジン
‘ Architecture Type: 3-Tier Headless Automation
‘ =========================================================================
Sub GenerateAssemblyFromDatabase()
Dim swApp As SldWorks.SldWorks
Dim swAsmDoc As SldWorks.AssemblyDoc
Dim swModel As SldWorks.ModelDoc2
‘ 1. SolidWorks アプリケーションの取得(遅延バインディング排除による高速化)
Set swApp = Application.SldWorks
If swApp is Nothing Then
MsgBox “SolidWorksが起動していません。”, vbCritical
Exit Sub
End If
‘ 2. データベース接続設定 (ADO)
Dim conn As Object
Dim rs As Object
Dim connStr As String
Set conn = CreateObject(“ADODB.Connection”)
Set rs = CreateObject(“ADODB.Recordset”)
‘ ※環境に合わせて接続文字列を変更すること
connStr = “Provider=SQLOLEDB;Server=192.168.1.100;Database=ProductDB;Uid=sa;Pwd=StrongPassword123;”
On Error GoTo ErrorHandler
conn.Open connStr
‘ 3. アセンブリ新規作成 (テンプレートを使用しない高速ブランク起動)
Set swModel = swApp.NewDocument(“C:\ProgramData\SolidWorks\SolidWorks 2023\templates\Metric Assembly.asmdot”, 0, 0, 0)
Set swAsmDoc = swModel
Dim configName As String
configName = “Default”
‘ 4. DBからコンポーネント群の取得
Dim sql As String
sql = “SELECT PartPath, InstanceName, X, Y, Z, MateType, TargetFace FROM AssemblyStructure WHERE OrderID = ‘ORD-202X-001′”
rs.Open sql, conn
Dim componentPath As String
val x As Double, y As Double, z As Double
Dim swComponent As SldWorks.Component2
Dim transform As SldWorks.MathTransform
Do Until rs.EOF
componentPath = rs.Fields(“PartPath”).Value
x = rs.Fields(“X”).Value / 1000.0 ‘ mmをmに変換 (SolidWorks内部単位はMKS)
y = rs.Fields(“Y”).Value / 1000.0
z = rs.Fields(“Z”).Value / 1000.0
‘ 部品をサイレントモード(バックグラウンド)に近い状態で挿入
Set swComponent = swAsmDoc.AddComponents3(componentPath, 0, “”, x, y, z)
If Not swComponent Is Nothing Then
‘ カスタムプロパティの動的書き込み
Call WriteCustomProperties(swComponent, rs)
End If
rs.MoveNext
Loop
‘ 5. 合致(Mate)のプログラム的構築
Call DefineProgrammaticMates(swAsmDoc, conn)
‘ 6. リビルドと保存
swModel.EditRebuild3
swModel.Extension.SaveAs “C:\Assemblies\Generated_ORD-202X-001.sldasm”, 0, 2, Nothing, 0, 0
GoTo Cleanup
ErrorHandler:
MsgBox “致命的なエラーが発生しました: ” & Err.Description, vbCritical
Cleanup:
‘ 7. オブジェクトの明示的解放(メモリリーク防止の絶対要件)
If rs.State = 1 Then rs.Close
If conn.State = 1 Then conn.Close
Set rs = Nothing
Set conn = Nothing
Set swComponent = Nothing
Set swAsmDoc = Nothing
Set swModel = Nothing
Set swApp = Nothing
MsgBox “アセンブリの自動生成が完了しました。”, vbInformation
End Sub
‘ — カスタムプロパティ注入関数 —
Private Sub WriteCustomProperties(ByRef swComp As SldWorks.Component2, ByRef recordSet As Object)
Dim swModelDoc As SldWorks.ModelDoc2
Set swModelDoc = swComp.GetModelDoc2()
If Not swModelDoc Is Nothing Then
Dim swCustPropMgr As SldWorks.CustomPropertyManager
Set swCustPropMgr = swModelDoc.Extension.CustomPropertyManager(“”)
‘ DBの値をCADモデルにバインド
swCustPropMgr.Add3 “DB_PartNumber”, 30, recordSet.Fields(“InstanceName”).Value, 2
swCustPropMgr.Add3 “DB_SyncDate”, 64, Format(Now, “yyyy-mm-dd”), 2
End If
End Sub
‘ — 合致関係構築エンジン —
Private Sub DefineProgrammaticMates(ByRef swAsm As SldWorks.AssemblyDoc, ByRef conn As Object)
‘ 実際の実装では、ここでMate2機能を用いて面と面の拘束を動的に生成する
‘ swAsm.AddMate3(…) を用いた幾何拘束のコードがここに展開される
‘ ※エンティティの選択状態(SelectByID2)をプログラム制御するのがコツ
End Sub
—
3. チーフアーキテクトが教える「極限の知見」と実務の罠
① COMオブジェクトのライフサイクル管理とメモリリーク対策
VBAはガベージコレクションが極めて緩慢である。特にSolidWorks APIを操作する際、`Set swModel = Nothing` や `Set swApp = Nothing` を適切に行わないと、タスクマネージャー上に `SLDWORKS.exe` のゾンビプロセスが残留し、メモリを食潰す。
鉄則: ループ内でCOMオブジェクトを取得・生成する場合は、必ずループの各イテレーションの末尾で変数を初期化(`Set obj = Nothing`)し、参照カウンターを確実にデクリメントさせよ。
② 単位系の罠(MKS vs IPS)
SolidWorksのAPI内部処理は、例外なくメートル法(Meters, Kilograms, Seconds)を強制される。
DBから取得した座標データがミリメートル(mm)である場合、そのまま渡すとアセンブリが数千倍のサイズで崩壊するか、エラーで弾かれる。必ずコード内で `/ 1000.0` のスケーリングを挟むこと。
③ UIスレッドのフロック回避
数千点規模のコンポーネントをアセンブリに放り込む際、画面描画(Graphics Update)が有効になっていると、Windowsのメッセージキューが飽和し、SolidWorksが「応答なし」に陥る。
大規模自動化の際は、事前に以下のAPIをコールして画面描画をサスペンドせよ。
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayUpdateDuringDragging, False
処理の最後に `True` に戻すことを忘れてはならない。
—
総括
外部DBとSolidWorksの融合は、単なるマクロの延長線上にはない。それは「完全なリソース管理」と「厳密な型・単位系の制御」の上に成り立つエンタープライズ・システム開発である。
本稿で示したアーキテクチャを導入することで、設計者はルーチンワークから解放され、真の創造的エンジニアリングに集中できる環境が手に入ることだろう。
