SolidWorks VBAを掌握する極限の知見
【実務中級】大規模アセンブリのパフォーマンス劇的改善:VBA実行中の画面描画停止とイベント抑制
こんにちは。チーフアーキテクトの私だ。
日々の業務で、数千点を超える大規模アセンブリの自動化に挑み、VBAの実行ボタンを押した瞬間にフリーズしたかのような重さに絶望したことはないか?
「進捗が見えないから不安になって画面を触り、挙句の果てにSolidWorksごとクラッシュした」——そんな悲劇を、私は幾度となく現場で目撃してきた。
素人が書いたコードは、パーツを1つ配置するたびにグラフィック画面を再描画し、裏でアセンブリ全体の干渉や再構築(Rebuild)を走らせる。これでは数万馬力のエンジンの上で、ブレーキを踏みながらアクセルを踏み続けているようなものだ。
今回は、SolidWorks VBAのパフォーマンスを極限まで引き上げ、「処理スピードを数倍〜十数倍に跳ね上げる」ための決定版テクニックを伝授する。オブジェクトのライフサイクルとAPIの挙動を知り尽くした者だけが扱える、実務直結の堅牢なデザインパターンを公開しよう。
—
なぜ、あなたのマクロは遅いのか?
SolidWorks APIにおける最大のボトルネックは、CPUの演算能力ではない。「UI(ユーザーインターフェース)の更新」と「不要な再構築(Rebuild)」である。
デフォルトの状態では、VBAからアセンブリに対して以下のような無駄な負荷がかかっている。
1. 画面のライブ描画(Graphics Update): パーツが動くたびにOpenGLのパイプラインが走る。
2. 自動再構築: 形状が変わるたびに、親・子関係の依存性が評価される。
3. イベントの拾い上げ: 外部からの操作や内部のステータス変化を監視し続ける。
これらをVBAの実行中だけ完全にシャットアウトし、処理が完了した瞬間に一気に開放する。これが大規模アセンブリを制するための絶対鉄則だ。
—
劇的改善を実現する3種の神器
SolidWorks APIには、この負荷を制御するための強力なメソッドが用意されている。
1. `SldWorks.UserControl` / `ModelDoc2.Visible`: 画面描画の抑制
2. `AssemblyDoc.SuppressFasteners` / 各種マニュアル再構築の活用
3. エラーハンドリング(確実な状態復帰): 途中でマクロがエラー落ちした際、画面がフリーズしたままになるのを防ぐための「例外処理の鉄則」
特に3つ目が重要だ。パフォーマンスチューニングにおいて、「エラー時に環境を元に戻せないコードは、凶器でしかない」。必ず`On Error`構文を組み合わせ、安全性を担保しなければならない。
—
【プロダクションコード】コピペで使える堅牢な最適化テンプレート
以下に、実務の現場でそのまま組み込める堅牢なコードを示す。
アセンブリの新規作成、あるいは大量のコンポーネントを配置・合致させる重い処理を想定した構造だ。
Option Explicit
‘ =========================================================================
‘ 模块名: ModAssemblyOptimizer
‘ 用途: 大規模アセンブリ処理のパフォーマンス劇的改善テンプレート
‘ 著者: チーフアーキテクト
‘ =========================================================================
Sub Main_OptimizeAssemblyProcess()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssy As SldWorks.AssemblyDoc
‘ 状態管理フラグ
Dim boolStatus As Boolean
Dim lngErrors As Long
Dim lngWarnings As Long
‘ 1. アプリケーションのインスタンス取得
Set swApp = Application.SldWorks
If swApp Is Nothing Then
MsgBox “SolidWorksが起動していません。”, vbCritical
Exit Sub
End If
‘ アクティブドキュメントの取得(新規アセンブリ作成の場合はここでCreateDocumentを行う)
Set swModel = swApp.ActiveDoc
‘ アセンブリドキュメントかどうかの型チェック
If swModel Is Nothing Then
‘ 新規アセンブリを開く場合の実装例
‘ Set swModel = swApp.NewDocument(“C:\ProgramData\SolidWorks\SolidWorks 202X\templates\アセンブリ.asmdot”, 0, 0, 0)
MsgBox “対象となるアセンブリが開かれていません。”, vbExclamation
Exit Sub
End If
If swModel.GetType <> swDocASSEMBLY Then
MsgBox “アクティブなドキュメントがアセンブリではありません。”, vbCritical
Exit Sub
End If
Set swAssy = swModel
‘ =====================================================================
‘ 【重要】パフォーマンス最適化の開始(ここから)
‘ =====================================================================
On Error GoTo ErrorHandler ‘ 途中でエラーが発生しても確実に復帰させる
‘ A. 画面描画の完全停止(最も効果が高い)
swApp.Visible = False
‘ B. 自動再構築の抑制(モデルの自動アップデートを止める)
‘ ※注意: ジオメトリの計算が必要な場合は処理の最後に明示的にRebuildを呼ぶ
boolStatus = swModel.SetUserPreferenceToggle(swUserPreferenceToggle_e.swAutoRebuildModel, False)
‘ C. ユーザーインタラクションの停止(ポップアップや警告の抑制)
swApp.SetUserPreferenceIntegerValue swUserPreferenceIntegerValue_e.swInteractiveState, 0
‘ =====================================================================
‘ 重い実務処理のシミュレーション(ここに実際の部品配置や合致処理を書く)
‘ =====================================================================
Dim i As Long
Debug.Print “— 大規模処理開始: ” & Now & ” —”
For i = 1 to 100
‘ 例: 仮想的なコンポーネントの挿入や合致定義
‘ swAssy.AddMate5(…) などの重い処理
DoEvents ‘ 必要に応じてOSに制御を返す(フリーズ偽装対策)
Next i
Debug.Print “— 大規模処理終了: ” & Now & ” —”
‘ =====================================================================
‘ 【重要】パフォーマンス最適化の終了と環境復帰(正常系)
‘ =====================================================================
‘ 1. 自動再構築を元に戻す
swModel.SetUserPreferenceToggle swUserPreferenceToggle_e.swAutoRebuildModel, True
‘ 2. モデル全体の強制再構築を1度だけ実行(整合性の担保)
swModel.ForceRebuild3 False
‘ 3. 画面描画とUIを復帰
swApp.Visible = True
swApp.SetUserPreferenceIntegerValue swUserPreferenceIntegerValue_e.swInteractiveState, 1
MsgBox “すべての処理が正常に完了しました。”, vbInformation, “最適化完了”
Exit Sub
ErrorHandler:
‘ =====================================================================
‘ 【超重要】例外処理:エラー時でも必ずSolidWorksのUIと描画を復帰させる
‘ =====================================================================
On Error Resume Next
swModel.SetUserPreferenceToggle swUserPreferenceToggle_e.swAutoRebuildModel, True
swApp.Visible = True
swApp.SetUserPreferenceIntegerValue swUserPreferenceIntegerValue_e.swInteractiveState, 1
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“内容: ” & Err.Description, vbCritical, “致命的なエラー”
End Sub
—
アーキテクトからの実務アドバイス:ファイル・DB連携時の罠
現場でこのマクロを組み込む際、データベース(ExcelやPDM、外部SQLなど)から部品データを大量に読み込み、次々とアセンブリに組み込んでいくアーキテクチャを採用することが多いはずだ。
ここで1つ、プロとして絶対に守るべき注意点を挙げておこう。
> 「ループ内でドキュメントを開閉するな。メモリリークの温床になる。」
もし外部ファイル(部品やサブアセンブリ)をコード内から開いて配置していく場合、`swApp.CloseDoc` を適切に行わないと、SolidWorksのプロセス内にメモリが残留し、後半になるにつれて急激に動作が重くなり、最終的にOut of Memoryでクラッシュする。
さらに、画面描画を止めている(`swApp.Visible = False`)状態の裏でドキュメントを開閉する場合、エラーハンドリングが漏れていると、ドキュメントが開いたまま画面からロストし、バックグラウンドプロセスとしてCPUを食いつぶす幽霊現象を引き起こす。
必ず「開く・処理する・閉じる」のライフサイクルを明確に管理し、今回紹介した`Visible = False` と `On Error` による確実な復帰構文をセットで運用してほしい。
—
結び
大規模アセンブリの自動化において、パフォーマンスは単なる「快適さ」ではなく、「システムが完遂するかどうか(信頼性)」の命題である。
今回紹介したテクニックをあなたの開発環境に導入すれば、これまで何分もかかっていた重い処理が、わずか数秒で、しかも裏で静かに、確実に完了する快感を味わえるはずだ。
プロフェッショナルなコードで、退屈な手作業を過去のものにしよう。
