【テクニカル・上級編】【パフォーマンス改善】SwApp.SetUserPreferenceToggleで画面描画を停止してマクロを爆速化 – SolidWorks VBA解析バイブル

スポンサーリンク

画面描画の停止は「通過点」に過ぎない:SolidWorks APIにおける高速化の極意

SolidWorksのAPI開発において、「なぜかマクロが遅い」と頭を抱えるシニアエンジニアは後を絶たない。特に数百の構成部品を持つアセンブリをループ処理する際、一行一行のAPI呼び出しがUIの再描画を誘発し、プロセッサのサイクルを無駄に消費する。

多くの技術者が最初に行う最適化が `swApp.SetUserPreferenceToggle` による描画停止だ。だが、真のアーキテクトであれば、それが「氷山の一角」であることを知っているはずだ。本稿では、描画停止を起点とし、メモリ管理からWindows APIの介入に至るまでの「爆速化」の深淵に触れる。

—

1. 再描画制御の「正解」:SetUserPreferenceToggleとFreeze

単に `swApp.SetUserPreferenceToggle(swUserPreferenceToggle_e.swViewDisplayModePerEntity, False)` を叩くだけでは不十分だ。重要なのは、「いつ制御を戻すか」という異常系を含めたライフサイクル管理にある。

以下のコードは、例外発生時(エラー時)にも確実に描画を復旧させるための堅牢なテンプレートである。

‘ 描画停止と再開を管理する堅牢なラッパーの雛形
Public Sub OptimizedProcess()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2

Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc

‘ 1. 描画・再計算を停止
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayModePerEntity, False
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayMode, False

On Error GoTo Cleanup ‘ 万が一のクラッシュ時に必ず復旧させる

‘ — ここに重い処理を記述 —

Cleanup:
‘ 2. 処理完了・エラー発生に関わらず描画を復旧
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayModePerEntity, True
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayMode, True

‘ 3. 明示的なメモリ解放(VBAではNothing代入が必須)
Set swModel = Nothing
Set swApp = Nothing
End Sub

—

2. オブジェクトのライフサイクルと「隠れたメモリリーク」

VBAはガベージコレクションを備えていない。特に `ModelDocExtension` や `SelectionManager` といった子オブジェクトをループ内で生成し続けると、SolidWorks本体のメモリを圧迫し、処理速度は指数関数的に低下する。

  • プロの鉄則: ループ内でオブジェクトを再生成しない。
  • キャッシュ戦略: ループの「外側」で取得できる参照は全て外に出す。

‘ 悪例:ループ内で毎回GetModelDocExtensionを呼ぶ
‘ 改善例:外側で一度取得し、参照を使い回す
Dim swExt As SldWorks.ModelDocExtension
Set swExt = swModel.Extension

Dim i As Long
For i = 0 To 1000
‘ swExt.SelectByID… のように既存の参照を利用
Next i

—

3. Windows API:SolidWorksの限界を突破する

SolidWorks APIが提供するメソッドだけでは、「システムがフリーズしたかのような挙動(応答なし)」を回避できない場合がある。ここでWindows APIの `LockWindowUpdate` を活用し、OSレベルでウィンドウの更新を物理的に遮断することで、さらにパフォーマンスを一段上のレベルへ引き上げる。

また、`DoEvents` の乱用は避けなければならない。`DoEvents` はUIの応答性を保つために必要だが、入れすぎるとオーバーヘッドが増大する。100回に1回程度に絞るか、タイマー制御を行うのが賢明だ。

—

4. レガシー環境における保守の極意

多くの企業で「10年前のマクロが動かない」という相談を受ける。原因の9割は 「型定義の欠如(Object型への依存)」 だ。

‘ 悪い例:Object型(実行時に型解決するため極めて低速かつ不安定)
Dim swComp As Object

‘ 良い例:厳密な型定義(コンパイル時にバインディングされるため高速)
Dim swComp As SldWorks.Component2

早期バインディング(Early Binding)を徹底し、参照設定を固定することは、単なる保守のためではない。「実行速度」と「予測可能性」を担保するためのエンジニアリング上の義務である。

—

終わりに:アーキテクトとしての矜持

VBAは確かにレガシーな言語かもしれない。しかし、SolidWorksの内部オブジェクトモデルを深く理解し、メモリレイアウトを意識しながらコードを書く技術は、言語の世代を超えて通用する「真のスキル」だ。

描画停止はあくまで手段。重要なのは、CPUとメモリを無駄にせず、SolidWorksという巨大なシステムと対話する際に、最も効率的な経路を選択することである。

貴方のコードが、単なる「作業効率化ツール」ではなく、システムの負荷を最小限に抑える「洗練されたアルゴリズム」へと進化することを期待している。

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