大規模アセンブリのパフォーマンス劇的改善:VBA実行中の画面描画停止とイベント抑制
SolidWorks VBAの開発現場において、数十、数百度の部品(コンポーネント)を持つ大規模アセンブリを動的に構築・制御するマクロを作成したことがある者なら、誰もが一度はあの絶望的な「カクつき」と「フリーズしたかのような待ち時間」に直面したはずだ。
コンポーネントを1つ追加するたびに、SolidWorksは親切にも画面を再描画し、アセンブリ全体の干渉を計算し、フィーチャーツリーを更新し、コンフィギュレーションの状態を評価する。
人間が目視ですべてを確認する必要などないループ処理の最中であっても、この「親切心」は律儀に繰り返される。結果として、数千行のコードが完了するまでに何十分もの時間を浪費することになる。
今回は、SolidWorks VBAの実行速度を限界まで引き上げ、数倍から数十倍のパフォーマンス改善をもたらす「画面描画の凍結(Lock)」と「イベントの抑制(Event Suppression)」の極限の知見を公開する。
—
1. なぜSolidWorks VBAは重くなるのか?(根本原因の解剖)
SolidWorks APIの背後には、C++ベースの重厚長大なCOMオブジェクト群が存在する。VBAからこれらを操作するとき、以下の3つのコストが常にボトルネックとなる。
1. 画面の再描画(Graphics Redraw)
- 形状が追加・変更されるたびにOpenGLのパイプラインが走り、ビューポートが再描画される。
2. 自動再構築(Automatic Rebuild)
- 参照関係(Matesなど)を持つアセンブリでは、微小な変更のたびにソルバーが方程式を解き直す。
3. COM間通信とイベントハンドリング
- SolidWorksアプリケーションからの通知や、ドキュメントのステータス変更イベントをVBA側がアイドル状態で監視・処理しようとする。
これらを制御下に入れずして、実務に耐えうる高速なアセンブリ自動化は語れない。
—
2. パフォーマンスを極限まで高める3つの武器
実務中級者からシニアへステップアップするために必須となる、3つのアーキテクチャ上のアプローチを解説する。
① `SldWorks.ModelDoc2.Visible` または `Frame.SetPauseUpdates`
画面の描画を一時的に停止する。これにより、GPUへの描画命令が完全に遮断され、CPU処理に全リソースを集中させることが可能になる。
② `SldWorks.SldWorks.SetProcessUserPreferenceToggle` によるイベント・再構築の抑制
バックグラウンドでの無駄な再構築や、ユーザーインターフェースからの割り込みを防ぐ。
③ 徹底的なオブジェクトの解放(メモリ最適化)
VBAのガベージコレクションはアテにならない。COMオブジェクト(特に`Component2`や`Mate`など)をループ内で適切に解放しないと、メモリリークを起こし、後半になるにつれてパフォーマンスが急激に低下する。
—
3. 実装コード:劇的爆速化テンプレート
以下に、大規模アセンブリの新規作成および合致(Mate)定義を想定した、実務でそのまま使える堅牢なVBAコードを提示する。エラーハンドリング(トランザクション管理)を組み込み、万が一途中でマクロが中断してもSolidWorksがフリーズ状態(画面ロック解除漏れ)にならないよう配慮している。
Option Explicit
‘ ==============================================================================
‘ 処理名: 大規模アセンブリ高速構築テンプレート
‘ 概要 : 画面描画とイベントを完全に抑制し、アセンブリ生成のオーバーヘッドを極限まで排除する
‘ ==============================================================================
Sub ExecuteHighPerformanceAssemblyCreation()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssy As SldWorks.AssemblyDoc
‘ 状態退避用変数
Dim bVisibleState As Boolean
Dim lPerfFlag As Long
‘ 1. アプリケーションの取得
Set swApp = Application.SldWorks
If swApp Is Nothing Then Exit Sub
‘ 2. 処理開始前のエラーハンドリング準備
On Error GoTo ErrorHandler
‘ 3. 【最重要】パフォーマンス最適化の適用開始
‘ ————————————————————————–
‘ A. 画面描画の停止(モデルドキュメントレベル)
Set swModel = swApp.ActiveDoc
If Not swModel Is Nothing Then
bVisibleState = swModel.Visible
swModel.Visible = False ‘ 描画を完全にフリーズ
End If
‘ B. バックグラウンドの自動再構築をオフにする
‘ (※必要に応じてSolidWorksのシステム設定やドキュメント設定を操作)
swApp.SetUserPreferenceToggle swStateAllConfigurations, False
‘ C. ユーザーインターフェースからのイベントや入力を一時停止
swApp.CommandInProgress = True
‘ ————————————————————————–
‘ — 【メイン処理:ここから重いループやアセンブリ構築を行う】 —
Dim i As Long
Dim compPath As String
Dim swComp As SldWorks.Component2
compPath = “C:\AeroParts\Standard_Bolt.sldprt” ‘ サンプル部品パス
‘ 例:100個の部品を配置し、合致を定義する高負荷な処理を想定
For i = 1 to 100
‘ ※実際にはここで swAssy.AddComponent5 などを実行
‘ コムオブジェクトの参照はループ内で確実に解放すること
Next i
‘ ————————————————————-
ErrorHandler:
If Err.Number <> 0 Then
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “致命的エラー”
End If
‘ 4. 【厳守】環境の復元(例外発生時も必ず実行されるようにする)
‘ ————————————————————————–
If Not swModel Is Nothing Then
swModel.Visible = True ‘ 描画の復元
End If
swApp.CommandInProgress = False
swApp.SetUserPreferenceToggle swStateAllConfigurations, True
‘ 強制的な全体再構築と画面リフレッシュの実行
If Not swModel Is Nothing Then
swModel.ForceRebuild3 False
swModel.GraphicsRedraw2
End If
‘ ————————————————————————–
‘ 5. オブジェクトの明示的解放
Set swModel = Nothing
Set swAssy = Nothing
Set swApp = Nothing
MsgBox “高速処理が完了しました。”, vbInformation, “完了”
End Sub
—
4. チーフアーキテクトからの実務的助言
トランザクション管理の徹底
上記のコードで最も恐ろしいのは、`swModel.Visible = False` や `swApp.CommandInProgress = True` を実行した状態でVBAのエラー(ゼロ除算やオブジェクト不一致など)が発生し、コードが途中で停止することだ。
これが発生すると、SolidWorksの画面が白濁したままフリーズし、ユーザーはタスクマネージャーから強制終了せざるを得なくなる。
必ず `On Error GoTo` 構文を記述し、いかなる例外が起きた場合でも確実に環境が復元される構造(Try-FinallyイディオムのVBA的実装)を担保しなければならない。
メモリリークとの戦い
数千回のループ内で `swAssy.AddComponent` や `CreateMate` を呼び出す際、取得したコンポーネントや合致オブジェクトの変数(例: `Set swComp = …`)をそのまま放置すると、VBAの背後にあるCOM参照カウントが残り続け、メモリを食いつぶしていく。
ループのブロックごとに `Set swComp = Nothing` を挟むなど、メモリのライフサイクルを完全に掌握すること。
—
総括
SolidWorks VBAによる大規模アセンブリの自動化は、単にAPIのメソッドを並べるだけでは実用に耐えない。
ハードウェアのポテンシャルを極限まで引き出し、不要なオーバーヘッドを削ぎ落とすこと——それこそが、現場のエンジニアを救うシニアアーキテクトの仕事である。
描画を止めよ、イベントを抑制せよ。その先にある「圧倒的なスピード」を手に入れた時、あなたのVBAスクリプトは単なるマクロから、真の「エンジニアリング・オートメーション・システム」へと昇華する。
