SolidWorks VBAを掌握する:アセンブリ構造を支配する「イベント駆動型」監視アーキテクチャ
SolidWorksの自動化において、最も脆弱で、かつ最も強力な領域が「アセンブリの構造変化」を検知するプロセスだ。多くのエンジニアは、ボタンを押すたびにアセンブリ全体をループで走査する「ポーリング方式」を採用する。だが断言しよう。それは非効率の極みであり、大規模アセンブリでは致命的なパフォーマンス劣化を招く。
本稿では、`SldWorks.AssemblyDoc` のイベントをクラスモジュールでフックし、コンポーネントの追加・削除をリアルタイムで検知する「真のプロフェッショナルな監視システム」の構築法を伝授する。
—
1. なぜ「ポーリング」ではダメなのか
アセンブリ内の全コンポーネントを `GetComponents` で取得し、名前やパスをDBと比較する手法は、小規模なモデルでは機能する。しかし、部品数が数百を超えるアセンブリでこれを頻繁に行えば、SolidWorksのメインスレッドは計算負荷で悲鳴を上げる。
我々が目指すべきは、SolidWorksのイベントスタックを直接叩く「プッシュ型」の設計だ。ユーザーがツリー操作を行った瞬間にのみ処理を走らせることで、システム負荷を極限までゼロに近づける。
—
2. 実装の要:WithEventsによるイベントハンドリング
VBAにおいて、SolidWorksのイベントを捉えるには「クラスモジュール」が必須である。標準モジュールにグローバル変数を置くような稚拙な設計は捨て去り、コンポーネントのライフサイクルをオブジェクトとしてカプセル化する。
Step 1: クラスモジュールの作成(名前:`clsAssemblyHandler`)
このクラスは、現在開いているアセンブリのライフサイクルを監視する司令塔となる。
‘ クラスモジュール: clsAssemblyHandler
Option Explicit
‘ SolidWorksのアセンブリイベントをフックする宣言
Public WithEvents swAssembly As SldWorks.AssemblyDoc
‘ コンポーネント追加時のイベント
Private Function swAssembly_ComponentAddedNotify(ByVal ComponentModel As Object, ByVal ComponentName As String) As Long
Debug.Print “検知: コンポーネントが追加されました -> ” & ComponentName
‘ ここでDB連携や外部システムへの通知処理を呼び出す
‘ 注意: 処理が重い場合は、DoEventsでメインスレッドをブロックしない工夫が必要
Call SyncToExternalSystem(“ADD”, ComponentName)
swAssembly_ComponentAddedNotify = 0 ‘ 0を返すのが作法
End Function
‘ コンポーネント削除時のイベント
Private Function swAssembly_DeleteNotify(ByVal ComponentModel As Object, ByVal ComponentName As String) As Long
Debug.Print “検知: コンポーネントが削除されました -> ” & ComponentName
Call SyncToExternalSystem(“DELETE”, ComponentName)
swAssembly_DeleteNotify = 0
End Function
Private Sub SyncToExternalSystem(action As String, compName As String)
‘ 【重要】ここでのエラー処理が全体のクラッシュを防ぐ鍵となる
On Error Resume Next
‘ JSON送信やAPIコールのロジックをここに記述
‘ 外部DB接続にはADODBなどを使用し、接続プールの管理を徹底すること
End Sub
—
3. アプリケーションの起動とメモリ管理
クラスモジュールを定義しただけでは機能しない。メインの標準モジュールで、このクラスのインスタンスを「永続化」する必要がある。
Step 2: 標準モジュール(制御用)
Option Explicit
Public g_Handler As clsAssemblyHandler
Public Sub StartMonitoring()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Or swModel.GetType <> swDocASSEMBLY Then
MsgBox “アセンブリを開いてください。”
Exit Sub
End If
‘ インスタンス化してイベントをバインド
Set g_Handler = New clsAssemblyHandler
Set g_Handler.swAssembly = swModel
MsgBox “アセンブリ監視を開始しました。”
End Sub
—
4. プロの現場で生き残るための「3つの鉄則」
1. メモリリークを徹底的に排除する
VBAのイベントフックは、インスタンスが破棄されない限りメモリに居座る。アセンブリを閉じる際、必ず `Set g_Handler = Nothing` を実行するクリーンアップルーチンを実装すること。これを怠ると、SolidWorksのシャットダウンが遅延し、挙動が不安定になる。
2. 外部連携は「非同期」を意識する
外部DBへの書き込みやREST APIコールを行う際、もしレスポンスが遅延すればSolidWorksの操作感は著しく低下する。通信処理は可能な限り軽量化し、必要であれば「キューイング処理」を検討せよ。メインスレッドを止めないことが、エンジニアとしての品格だ。
3. 再帰的更新の罠を回避する
コンポーネントの追加を検知してプログラム側で何らかの加工を行うと、その処理が再度「追加イベント」をトリガーし、無限ループに陥ることがある。`DisableEvents` 的なフラグを立てて、プログラム自身が操作する際にはイベントを無視するガード条件を必ず設けること。
—
最後に:自動化は手段であり目的ではない
今回紹介した技術は、単なるコードの断片ではない。アセンブリ内の「動き」を可視化し、設計データと製造現場をデジタルで繋ぐための「神経系」だ。
もしあなたが、このアーキテクチャを理解し、自身の環境に適用できるのであれば、ルーチンワークに追われる日々に終止符を打つ準備はできているはずだ。次は、このイベントを活用して「自動合致(Mate)設定」をリアルタイムで走らせるモジュールへと拡張していこう。
設計の自動化とは、堅牢な基盤の上にのみ築かれるものだ。健闘を祈る。
