【実務・中級編】【画面再描画の完全制御】SwApp.EnableUserInterfaceとVisibleStateChangeによる圧倒的なマクロ高速化手法 – SolidWorks VBA解析バイブル

スポンサーリンク

【画面再描画の完全制御】SwApp.EnableUserInterfaceとVisibleStateChangeによる圧倒的なマクロ高速化手法

開発プロジェクトの現場で、こんな悪夢を見たことはないだろうか。
「数千点の部品を持つアセンブリに対し、マクロで一括属性変更をかけたところ、画面が激しくチラつき、挙句の果てにOSがフリーズしたかのように数十分待たされる」

もし、あなたの書いたSolidWorks VBAコードが、実行中にいちいちビューポートを再描画し、フィーチャーツリーをピコピコと更新させているなら――今すぐその設計を改めるべきだ。

今回は、SolidWorks APIの深部を抉り、画面再描画とUIを完全に掌握することで「処理速度を限界まで引き上げる極限のパフォーマンスチューニング技術」を授けよう。

1. なぜあなたのマクロは遅いのか?(APIの裏側で起きている悲劇)

SolidWorks VBAの初心者が陥る最大の罠、それは「人間が見ている画面と、APIが処理しているメモリ上のモデルが、常に同期しているという幻想」である。

`ModelDoc2` オブジェクトに対して何らかの操作(コンフィギュレーションの切り替え、フィーチャーの抑制解除、プロパティの書き込みなど)を行うたび、SolidWorksのコアエンジンは以下の処理を裏で強制されている。

1. ジオメトリの再計算(Rebuild)
2. グラフィックバッファのフラッシュとビューポートの再描画
3. FeatureManagerデザインツリーのUIツリー再構築

特に「グラフィックの再描画」と「UIの同期」のコストは、想像を絶するほど重い。1回あたりの描画はわずか0.05秒だとしても、1,000部品をループ処理すれば、純粋な計算以外の「描画待ち時間」だけで50秒をドブに捨てることになる。

プロのエンジニアであれば、マクロ実行中はSolidWorksの目と耳を塞ぎ、計算に全リソースを集中させるべきだ。それを実現するのが `SldWorks.EnableUserInterface` と、イベント駆動による安全管理である。

2. 画面制御の二大巨頭:`EnableUserInterface` と `VisibleStateChange`

画面を爆速化させるためのアプローチには、主に2つのレベルが存在する。これらを適切に組み合わせることで、堅牢かつ圧倒的な高速化が達成される。

① `SldWorks.EnableUserInterface (False / True)`

SolidWorksアプリケーション全体のユーザーインターフェース(UI)の有効/無効を切り替える。
これを `False` にすると、フィーチャーツリーの更新やコマンドの受け付け、そして何よりグラフィック領域のレンダリングが完全に停止する。メモリ上での演算のみが超高速で実行されるため、一括処理のスピードが劇的に跳ね上がる。

② `ModelDoc2.HaltModelUpdate / Lock` 系メソッドとの違い

モデル自体のリビルドを止める手法もあるが、アセンブリ構造の走査やメタデータの書き換えにおいては、UI層そのものをロックする `EnableUserInterface` の方が影響範囲が広く確実な効果を発揮する。

⚠️ 【重要】「画面を閉ざす」ことの危険性と `VisibleStateChange`

UIをロックするコードを書く際、絶対に避けて通れないのが「エラーハンドリングの失敗によるUIフリーズ(デッドロック状態)」だ。
もし `EnableUserInterface False` を実行した直後のコード内で予期せぬエラー(実行時エラー)が発生し、そのままプログラムが中断または終了したとき、SolidWorksのUIが二度と操作できなくなる(グレーアウトしたまま固まる)という致命的なバグを引き起こす。

これを防ぐためには、VBAの `On Error GoTo` を駆使し、いかなる例外が発生しようとも、必ず最後に `EnableUserInterface True` が実行される鉄壁の構造(Try-Finallyイディオムの再現)を構築しなければならない。

3. 【コピペOK】実務で使えるプロダクションコード

以下のコードは、大規模アセンブリ内の全コンポーネントに対して一括処理を行う際を想定した、実務仕様のテンプレートである。エラーハンドリング、UIロックの確実な解除、そして処理時間の計測まで組み込まれた、そのまま現場で使える堅牢な設計となっている。

Option Explicit

‘ メインエントリーポイント
Sub MasterBatchProcess_HighPerformance()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim startTime As Double
Dim uiEnabled As Boolean

‘ 処理時間計測開始
startTime = Timer

‘ SolidWorks アプリケーションの取得
Set swApp = Application.SldWorks
If swApp Is Nothing Then
MsgBox “SolidWorksが起動していません。”, vbCritical
Exit Sub
End If

Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “処理対象のドキュメントが開していません。”, vbExclamation
Exit Sub
End If

‘ ==========================================
‘ 【重要】エラーハンドリングの準備
‘ ==========================================
On Error GoTo ErrorHandler

‘ 1. 画面描画・UIの完全シャットダウン(高速化の核心)
uiEnabled = False
swApp.EnableUserInterface False

‘ 2. モデルの自動再ビルドを抑制(必要に応じて)
‘ swModel.FauxRebuild ? など、状況に応じたチューニング

‘ ==========================================
‘ 重い処理のシミュレーション(例:全コンポーネント走査)
‘ ==========================================
Call ExecuteHeavyProcessing(swApp, swModel)

‘ 正常終了時のクリーンアップ
GoTo CleanUp

ErrorHandler:
‘ 予期せぬエラー発生時、ユーザーに通知しつつ必ずUIを復旧させる
MsgBox “マクロ実行中にエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“内容: ” & Err.Description, vbCritical

CleanUp:
‘ ==========================================
‘ 【絶対遵守】UIの確実な復旧
‘ ==========================================
‘ エラーの有無に関わらず、必ずUIを有効に戻す
swApp.EnableUserInterface True
uiEnabled = True

‘ 画面の強制リフレッシュ(最新の状態を描画)
swModel.GraphicsRedraw2

‘ 完了ログ
Debug.Print “処理完了時間: ” & Format(Timer – startTime, “0.00秒”)
MsgBox “処理が完了しました。 実行時間: ” & Format(Timer – startTime, “0.00秒”) & “秒”, vbInformation
Exit Sub

End Sub

‘ 実際の重い処理をカプセル化するプロシージャ
Private Sub ExecuteHeavyProcessing(ByRef swApp As SldWorks.SldWorks, ByRef swModel As SldWorks.ModelDoc2)
‘ ここに実際のAPI操作(コンフィギュレーション切替、属性書込、フィーチャー操作など)を記述
‘ 例として、単なるウェイトやダミー処理ではなく、モデルトラバーサルを想定

Dim swAssoc As SldWorks.AssemblyDoc
If swModel.GetType = swDocumentASSEMBLY Then
Set swAssoc = swModel
‘ ※UIがロックされているため、ここで画面更新を伴うメソッドは実行されない
‘ メモリ上のデータ構造のみが高速に書き換わる

‘ (ここに実際のコンポーネント走査ロジックが入る)
End If

‘ 処理の途中で進捗をステータスバーに表示したい場合も、
‘ EnableUserInterfaceがFalseの間は無視されるか溜まるため、
‘ 必要に応じて swApp.SendMsgToUser2 等を活用する
End Sub

4. チーフアーキテクトからの実践的アドバイス・注意点

この手法を導入するにあたり、開発現場でハマりがちな罠を先回りして共有しておこう。

1. メッセージボックスやインプットボックスの扱いに注意
`EnableUserInterface False` の状態で `MsgBox` を呼び出すと、SolidWorksのウィンドウが背面に隠れたり、ダイアログがフォーカスを失って操作不能になる現象が起きることがある。UIロック区間内ではユーザーインタラクションを一切行わないこと。ログはすべて `Debug.Print` やテキストファイルへの出力に逃がすのが鉄則だ。

2. データベースや外部ファイル連携との組み合わせ
ExcelやSQL Serverから大量のデータを読み込みながらSolidWorksモデルを書き換えるバッチ処理において、この画面制御を組み合わせることで、処理速度が最大10倍以上に跳ね上がった事例を幾度となく見てきた。外部I/Oと組み合わせる時こそ、この「画面を閉ざす技術」が真価を発揮する。

3. マクロの「行儀の良さ」を保つ
他者へ配布するツールや、チームで共有するアドイン開発において、エラー時にUIが戻らなくなるマクロは「凶器」でしかない。必ず `On Error GoTo` によるセーフティネットを張り巡らせ、プロフェッショナルとしての品質を担保してほしい。

5. まとめ

SolidWorks VBAにおけるパフォーマンスチューニングの本質は、無駄なリソース消費を断つことにある。

  • `swApp.EnableUserInterface False` でグラフィックとUIの更新を完全に断つ。
  • `On Error GoTo` を必ず併用し、いかなる場合でもUIの復旧(`True`)を担保する。
  • 計算がすべて終わったあとに、一度だけ `GraphicsRedraw2` で美しく画面を同期させる。

この知見をあなたの開発環境にインストールした瞬間から、重厚長大なアセンブリを相手にした絶望的な待ち時間は過去のものとなるだろう。
圧倒的なスピードを手に入れ、真に価値のある自動化システムを構築してほしい。

タイトルとURLをコピーしました