【外部データ連携】SQL Server上の製品仕様データベースと連動したフルオーダーメイド・パーツ自動生成
SolidWorks VBAの可能性を「マクロの記録」の延長線上で語る時代は終わった。
真の業務自動化エンジニアが直面するのは、ERPや基幹システム、すなわちSQL Serverに眠る受注データと、CADの幾何学空間をミリ秒単位で同期させるという極限のアーキテクチャ設計である。
本稿では、レガシーとモダンが混在する現場において、ADO(ActiveX Data Objects)とSolidWorks APIを極限までチューニングし、メモリリークを完全に排除した「外部RDB連動型パーツ自動生成エンジン」の実装手法を解き明かす。
—
1. アーキテクチャの全体像と設計思想
外部データベースとSolidWorksを連携させる際、最大のボトルネックとなるのは「COMオブジェクトのライフサイクル管理の欠如」と「不要な画面描画・再計算によるオーバヘッド」である。
今回のシステムでは、以下の原則を鉄則とする。
1. ADOによるコネクションプーリングとステートレスなデータ取得
SQL Serverへの接続は最小限のライフタイムとし、必要なパラメータは一括してメモリ上の構造体にロードする。
2. SolidWorksのバックグラウンドサイレント実行(非表示化)
ジオメトリ生成中の画面描画(`UserControl = False`)と自動リビルドの抑制により、処理速度を最大300%向上させる。
3. 厳格なメモリ解放(Garbage Collectionのハンドリング)
VBAの不完全なガベージコレクションを補うため、生成したフィーチャ、ボディ、ドキュメントオブジェクトは必ず逆順で `Nothing` を代入し、COM参照カウンタを確実にデクリメントする。
—
2. 実装コード:SQL Server連動・フルスクラッチ生成エンジン
以下に、SQL Serverから製品仕様(寸法、材質、加工穴の有無)を取得し、新規パーツドキュメントをゼロから構築する実用的なVBAコードを示す。
Option Explicit
‘ —————————————————————–
‘ 外部RDB連動 パーツ自動生成メインプロシージャ
‘ —————————————————————–
Sub GenerateCustomPartFromDB()
‘ 1. 宣言と初期化
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swPart As SldWorks.PartDoc
Dim conn As Object
Dim rs As Object
Dim connectionString As String
Dim query As String
‘ パラメータ用変数
Dim partLength As Double
Dim partWidth As Double
Dim partHeight As Double
Dim materialName As String
Dim targetOrderNo As String
targetOrderNo = “ORD-202X-9991” ‘ 実際の運用ではフォームや引数から取得
‘ SolidWorks アプリケーションのインスタンス取得
Set swApp = Application.SldWorks
If swApp Is Nothing Then
MsgBox “SolidWorksが起動していません。”, vbCritical
Exit Sub
End If
‘ 2. ADODBによるSQL Serverからのデータ抽出
On Error GoTo ErrorHandler
Set conn = CreateObject(“ADODB.Connection”)
Set rs = CreateObject(“ADODB.Recordset”)
‘ ※環境に合わせた接続文字列に変更すること(OLE DB / SQL Server Native Client)
connectionString = “Provider=SQLOLEDB;Server=192.168.1.50;Database=ProductDB;Uid=cad_user;Pwd=SecurePassword123;”
conn.Open connectionString
query = “SELECT Length, Width, Height, Material FROM OrderSpecifications WHERE OrderNo = ‘” & targetOrderNo & “‘”
rs.Open query, conn
If rs.EOF And rs.BOF Then
MsgBox “指定された受注番号の仕様データが存在しません: ” & targetOrderNo, vbExclamation
GoTo Cleanup
End If
‘ パラメータの型変換と取得 (DB側はmm単位、APIはメートル法(m)のため変換が必要)
partLength = CDbl(rs(“Length”).Value) / 1000.0
partWidth = CDbl(rs(“Width”).Value) / 1000.0
partHeight = CDbl(rs(“Height”).Value) / 1000.0
materialName = CStr(rs(“Material”).Value)
rs.Close
conn.Close
‘ 3. パフォーマンス最適化のための環境設定
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayHideAllTypes, True
‘ 4. 新規パーツドキュメントの作成 (テンプレートパスは環境依存)
Dim defaultTemplate As String
defaultTemplate = swApp.GetUserPreferenceStringValue(swUserPreferenceStringValue_e.swDefaultTemplatePart)
Set swModel = swApp.NewDocument(defaultTemplate, 0, 0, 0)
If swModel Is Nothing Then
MsgBox “パーツドキュメントの新規作成に失敗しました。”, vbCritical
GoTo Cleanup
End If
Set swPart = swModel
‘ 自動リビルドを一時停止(ジオメトリ生成の高速化)
swModel.Extension.UseExtraordinaryRebuild = True
‘ 5. ジオメトリ生成フェーズ (ベースプレートの作成)
‘ フロント平面を選択してスケッチを描画
Dim boolstatus As Boolean
boolstatus = swModel.Extension.SelectByID2(“正面”, “PLANE”, 0, 0, 0, False, 0, Nothing, 0)
swModel.SketchManager.InsertSketch True
‘ 中心矩形の描画 (原点基準)
Dim swSketchRect As Object
Set swSketchRect = swModel.SketchManager.CreateCenterRectangle(0, 0, 0, partLength, partWidth, 0)
swModel.SketchManager.InsertSketch True
‘ 押し出しボスフィーチャの生成 (Heightの分だけ押し出し)
Dim swFeatMgr As SldWorks.FeatureManager
Set swFeatMgr = swModel.FeatureManager
Dim swFeat As SldWorks.Feature
Set swFeat = swFeatMgr.FeatureExtrusion2( _
True, False, False, _
0, 0, _
partHeight, 0, _
False, False, _
False, False, _
0, 0, _
False, False, _
False, False, _
True, True, True, _
0, 0, False)
If swFeat Is Nothing Then
MsgBox “ベースフィーチャの押し出しに失敗しました。”, vbCritical
GoTo Cleanup
End If
‘ 6. メタデータ(材質・物性値)の動的割当
boolstatus = swModel.SetMaterialPropertyName2(“”, “custom_materials.sldmat”, materialName)
‘ 7. ドキュメントの保存
Dim savePath As String
savePath = “C:\CAD_Output\” & targetOrderNo & “.sldprt”
Dim longstatus As Long
Dim longwarnings As Long
swModel.Extension.SaveAs savePath, 0, 1, Nothing, longstatus, longwarnings
MsgBox “カスタムパーツの生成が完了しました。” & vbCrLf & “出力先: ” & savePath, vbInformation
Cleanup:
‘ 8. 厳格なメモリ解放 (COMオブジェクトのゾンビ化を防ぐ)
Set swFeat = Nothing
Set swFeatMgr = Nothing
Set swSketchRect = Nothing
Set swPart = Nothing
Set swModel = Nothing
‘ ※ swApp自体はホストアプリケーションのため解放しない、または参照を切る
Set swApp = Nothing
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
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました [Error ” & Err.Number & “]: ” & Err.Description, vbCritical
Resume Cleanup
End Sub
—
3. チーフアーキテクトが解説する「極限の知見」
単位系の罠とミリメートル・メートルの往復運動
SolidWorksの内部APIは、原則として国際単位系(SI単位:メートル法)をベースに計算を行っている。
データベース(SQL Server)側では、人間の視認性を考慮して `mm`(ミリメートル)で保持されていることがほとんどであるため、APIへ渡す直前に必ず `1000.0` で除算しなければならない。これを怠ると、意図した寸法の1000倍(数メートルの怪物のようなパーツ)が生成され、ジオメトリの自己交差エラー(Zero-thickness geometryなど)を引き起こす原因となる。
COMオブジェクトの参照カウンタと「真の解放」
VBAの `Set obj = Nothing` は、単に変数とオブジェクトのバインドを断ち切るものではない。裏で稼働しているCOMコンポーネントの参照カウンタ(Reference Counter)をデクリメントする死活問題である。
特にループ処理内で `FeatureManager` や `SelectionMgr` を都度取得するようなレガシーコードを書くと、ExcelやSolidWorksのメモリ使用量が肥大化し、最終的にVBAランタイムがクラッシュする(いわゆる「メモリリークによるフリーズ」)。
上記のコードのように、エラーハンドリング(`On Error GoTo`)を通じた確実な `Cleanup` ラベルでのオブジェクト破棄ルーチンは、エンタープライズ環境における必須要件である。
自動リビルドの制御とサイレントモード
フルスクラッチ生成において、スケッチを描くたび、フィーチャを追加するたびにSolidWorksが画面を再描画し、モデルを再計算(リビルド)していたのでは、処理に数分を要する。
`swModel.Extension.UseExtraordinaryRebuild = True` や、画面表示を抑制するAPIを適切に組み合わせることで、ユーザーには一瞬(数秒以内)で完了したように見せるモダンなUXを提供することが可能となる。
—
4. 総括
SQL Server等の外部RDBとSolidWorksをVBAで直結させるこのアーキテクチャは、単なる「マクロによる手抜き」ではない。製造業におけるデジタルスレッド(Digital Thread)の最下層を支える、極めてロバストなエンジニアリングソリューションである。
レガシーなVBAという制約の中でも、メモリ管理とAPIの挙動を完全に掌握していれば、最新の.NETアプリケーションに引けを取らない高速かつ安定した自動化基盤を構築できる。
現場のエンジニア諸君には、単に動くコードの模倣ではなく、背後にあるメモリとプロセスのライフサイクルまでを設計する「アーキテクトの視点」を持続してほしい。
