SolidWorks VBAを極める:大規模アセンブリ処理で「フリーズ」を撲滅するUI実装術
こんにちは。現場で「マクロが止まったまま動かない…」と頭を抱えるエンジニアを何人も救ってきた、自動化エンジニアの先輩です。
SolidWorksで数千パーツのアセンブリを操作する際、処理中にUIが「応答なし」になる経験はありませんか?あれは単に見た目が悪いだけでなく、OSがタスクを「死んでいる」と誤認して強制終了させるリスクすらあります。
今日は、「重たい処理中にUIを凍らせない」という、中級者への登竜門となるテクニックを伝授します。
—
1. なぜ「フリーズ」するのか?:イベントループの本質
SolidWorksのVBAは「シングルスレッド」で動作します。メインの処理(重い計算やエクスポート)が動いている間、Windowsからの「画面を描画せよ」「ユーザーのクリックを受け取れ」という命令が処理待ちになり、結果として画面が真っ白に固まります。
これを防ぐための魔法が、`DoEvents`関数です。
—
2. 実践:プログレスバーを滑らかに動かすコード実装
今回は、ユーザーフォーム(`UserForm1`)にプログレスバーを表示し、大規模アセンブリを処理する際のテンプレートを作成します。
ユーザーフォームの準備
1. VBEで `UserForm1` を作成。
2. その中にラベルを配置し、名前を `lblProgress` としてください。
メインコード(標準モジュール)
Option Explicit
‘ 処理を中断させないための核となる関数
Public Sub ProcessLargeAssembly()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim i As Long, totalSteps As Long
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
‘ 処理ステップ数(例:構成部品の数)
totalSteps = 100
‘ ユーザーフォームを表示(モードレスで表示することが重要!)
UserForm1.Show vbModeless
For i = 1 To totalSteps
‘ 1. ここに重い処理を記述(例:各部品のエクスポート)
‘ swModel.Extension.SaveAs(…)
‘ 2. UIを更新する(ここが生命線)
UpdateProgressBar i, totalSteps
‘ 3. Windowsのイベント(描画やクリック)を割り込ませる
DoEvents
Next i
Unload UserForm1
MsgBox “全工程完了!”
End Sub
‘ プログレスバー更新用の補助関数
Private Sub UpdateProgressBar(current As Long, total As Long)
Dim percent As Double
percent = (current / total) 100
With UserForm1
.lblProgress.Width = (.Width – 20) (current / total)
.lblProgress.Caption = Int(percent) & “% 進行中…”
.Repaint ‘ 強制再描画
End With
End Sub
—
3. このコードの「賢いポイント」
① `vbModeless` でのフォーム表示
`UserForm1.Show` の後に `vbModeless` をつけるのがポイントです。これがないと、フォームが表示されている間、SolidWorksの画面自体がロックされてしまい、処理が進まなくなります。
② `DoEvents` の魔術
これが今回の心臓部です。`DoEvents` は、溜まっているWindowsのメッセージキュー(OSからの命令)を処理する時間をVBAに作らせます。これにより、プログレスバーが「更新」され、ユーザーが「キャンセルボタン」を押せる余裕が生まれます。
③ `.Repaint` による強制更新
VBAのラベル更新は、OSのタイミング次第では遅延します。`.Repaint` を呼ぶことで、「今すぐ描画を確定させろ」と命令し、プログレスバーの動きを滑らかにします。
—
4. 陥りやすいエラーと回避策
- 「計算が早すぎてプログレスバーが追いつかない」
- 対策: 10件に1回だけ `DoEvents` を呼ぶように調整してください。あまりに頻繁に呼ぶと、逆に処理速度が低下します。
- 「キャンセルボタンを押しても止まらない」
- 対策: フォーム側に `Public CancelFlag As Boolean` を用意し、ボタンクリック時に `True` に変更させます。ループ内で `If UserForm1.CancelFlag Then Exit For` と判定させれば、安全に中断可能です。
—
先輩からのアドバイス:次に目指すべき場所
ここをクリアしたあなたは、もう「マクロの記録」をただ貼り付けるだけの初心者ではありません。「SolidWorksの機嫌を損ねないコード」を書けるようになりました。
次は、Windows APIの `Sleep` 関数を使って、CPU負荷を一時的に解放する「ウェイト制御」を調べてみてください。さらに高度なバックグラウンド処理の世界が待っています。
自動化は、あなたとチームの時間を創り出す魔法です。ぜひ、このコードをあなたのツールボックスに入れておいてください。応援しています!
