【入門編】【上級プロ】マルチプロセッサ環境を模倣したバックグラウンド処理:大規模アセンブリのエクスポート中にUIフリーズを防ぐ進捗管理 – SolidWorks VBA解析バイブル

スポンサーリンク

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負荷を一時的に解放する「ウェイト制御」を調べてみてください。さらに高度なバックグラウンド処理の世界が待っています。

自動化は、あなたとチームの時間を創り出す魔法です。ぜひ、このコードをあなたのツールボックスに入れておいてください。応援しています!

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