SolidWorksの「鼓動」を捉える:イベント駆動型自動化へのパラダイムシフト
こんにちは。設計自動化の世界へようこそ。
ここまでマクロの記録機能や、ボタンを押して実行する「命令型」のプログラミングを学んできたあなたなら、一度はこんな壁にぶつかったことがあるはずです。
「図面を保存した瞬間に、自動でPDFも書き出せたらいいのに……」
「新しい図面を開いたとき、自動で特定のテンプレートやレイヤー設定を適用したい……」
これらは、人間が操作するのを待つのではなく、SolidWorksというソフトウェア自体の「動き(イベント)」を検知して、プログラムを動かすという、一段上のフェーズの話です。
今日は、単なる「マクロの書き方」を超えて、SolidWorksのシステム内部の動き(イベント)をフックし、設計プロセスを完全に自動制御するための「イベント駆動型設計」という極意を伝授します。ここをクリアすれば、あなたの作るツールは「便利な道具」から「自律して動くシステム」へと進化します。
1. 「命令型」から「イベント駆動型」への進化
まず、これまでのプログラミングと、今回扱う手法の違いを整理しましょう。
命令型(Imperative): 「人間が主役」
これまでのマクロは、あなたがボタンを押した瞬間に動き出します。
- フロー: 人間が操作 $\rightarrow$ マクロ実行 $\rightarrow$ 処理終了
- 弱点: 人間が操作を忘れたら、自動化は何もしてくれません。
イベント駆動型(Event-Driven): 「SolidWorksが主役」
今回のテーマです。SolidWorksの中で「何かが起きた(イベントが発生した)」ことを、プログラムが常に監視しています。
- フロー: SolidWorks内で操作(保存、新規作成など) $\rightarrow$ イベント発生! $\rightarrow$ プログラムが自動起動 $\rightarrow$ 処理実行
- 利点: ユーザーが意識することなく、バックグラウンドでバックアップや外部システムへの通知が完了します。
図解:イベントのメカニズム
[ ユーザーの操作 ]
v
[ SolidWorks 本体 (Engine) ] ----> (イベント発生!: "ファイルが保存されました")
<--- [ イベントフック (Event Hook) ] <---
v
[ あなたの書いたコード (Handler) ]
+--> [ PDF自動書き出し ]
+--> [ サーバーへ通知 ]
+--> [ ログ保存 ]
2. 核心となる「SldWorksEvents」とオブジェクトの寿命
イベントをキャッチするためには、SolidWorksが提供する `SldWorksEvents` というインターフェースを使用します。しかし、ここで初心者が必ず陥る「致命的な罠」があります。
⚠️ 伝説のエンジニアが教える「オブジェクトの寿命」問題
VBAでイベントを検知しようとして、標準モジュール(Module1など)にコードを書いただけでは、イベントは絶対に発生しません。
なぜか? それは、「イベントを待ち受けるオブジェクト(リスナー)」が、マクロの実行が終わった瞬間にメモリから消滅してしまうからです。
イベントを継続的に監視するためには、「クラスモジュール」を使用し、そのインスタンスを「グローバル変数」として保持し続ける必要があります。これが、オブジェクトのライフサイクルを管理するという、プロフェッショナルへの第一歩です。
3. 実践:図面保存時にバックアップを自動生成する設計
それでは、具体的なコードを見ていきましょう。
「図面(Drawing)が保存された瞬間に、その図面のPDFを自動で作成する」という高度な処理を実装するイメージです。
※本来、常時監視にはアドイン(C#)が推奨されますが、ここではVBAの仕組みを理解するために、クラスモジュールを用いた設計パターンを示します。
ステップ1:クラスモジュールを作成する
まず、挿入 $\rightarrow$ クラスモジュール を選択し、名前を `clsEventWatcher` に変更してください。
' --- クラスモジュール: clsEventWatcher ---
Option Explicit
' SolidWorksのイベントをキャッチするための変数
Private WithEvents swApp As SldWorks.SldWorks
' クラスが初期化されるときに呼ばれる
Private Sub Class_Initialize()
' 実行中のSolidWorksインスタンスをセット
Set swApp = Application.SldWorks
Debug.Print "イベント監視を開始しました。"
End Sub
' ファイルが保存されたときに発生するイベント
' SldWorks_FileSaveNotify は、ファイルが保存された直後に呼ばれる
Private Sub swApp_FileSaveNotify(ByVal FileName As String)
On Error GoTo ErrorHandler
Dim swModel As SldWorks.ModelDoc2
Set swModel = swApp.ActiveDoc
' アクティブなドキュメントが「図面」であるか確認
If Not swModel Is Nothing Then
If swModel.GetType = swDocDRAWING Then
Debug.Print "図面の保存を検知: " & FileName
' 【ここで自動化ロジックを呼び出す】
Call CreatePdfBackup(swModel, FileName)
End If
End If
Exit Sub
ErrorHandler:
Debug.Print "エラー発生: " & Err.Description
End Sub
' PDFバックアップを作成するサブルーチン
Private Sub CreatePdfBackup(swModel As SldWorks.ModelDoc2, originalPath As String)
Dim strPdfPath As String
' 元のファイルパスから拡張子を .pdf に変更
strPdfPath = Left(originalPath, InStrRev(originalPath, ".")) & "pdf"
' PDFとして保存(ExportToSavAs を使用)
' ※実際には詳細なエクスポート設定が必要ですが、ここでは概念を示します
swModel.Extension.SaveAs strPdfPath, swSaveAsCurrentVersion, swSaveAsOptions_Silent, Nothing, 0, 0
Debug.Print "PDFバックアップ完了: " & strPdfPath
End Sub
' クラスが破棄されるとき
Private Sub Class_Terminate()
Debug.Print "イベント監視を終了しました。"
End Sub
ステップ2:標準モジュールで「監視役」を起動する
次に、標準モジュールで、上記のクラスを「生き続けさせる」ためのコードを書きます。
' --- 標準モジュール ---
Option Explicit
' ★ここが最重要!クラスのインスタンスをグローバル変数として保持する
' これにより、マクロが終わっても監視役がメモリに残り続ける
Private Watcher As clsEventWatcher
' 監視を開始するメイン関数
Sub StartEventMonitoring()
' すでに動いている場合は一旦リセット
Set Watcher = Nothing
' 監視役(クラス)を生成
Set Watcher = New clsEventWatcher
MsgBox "図面の保存監視を開始しました。" & vbCrLf & _
"図面を保存すると、自動でPDFが作成されます。", vbInformation
End Sub
' 監視を停止する関数
Sub StopEventMonitoring()
Set Watcher = Nothing
MsgBox "監視を停止しました。", vbExclamation
End Sub
4. プロが教える「陥りやすい落とし穴」と回避策
この高度な実装を行う際、あなたは必ず以下の3つの問題に直面します。これを知っているかどうかが、プロとアマチュアの分かれ目です。
① 無限ループの恐怖(再帰呼び出し)
今回の例では、「保存イベント」の中で「PDFを保存」しています。もし、PDFの保存が「ファイル保存イベント」を再度トリガーしてしまう設計になっていると、[保存 $\rightarrow$ イベント $\rightarrow$ 保存 $\rightarrow$ イベント…] という無限ループに陥り、SolidWorksがフリーズします。
- 対策: `swModel.GetType` で対象が図面(Drawing)であるかを厳格にチェックし、保存対象が意図したもの(PDFなど)でない場合は即座に `Exit Sub` するロジックを徹底してください。
② パフォーマンスの重み
イベントハンドラ(`swApp_FileSaveNotify`)の中で、非常に重い計算や、ネットワーク越しに巨大なファイルを転送する処理を書いてはいけません。イベントは「SolidWorksのメインスレッド」で動作するため、あなたのコードが動いている間、ユーザーはSolidWorksを操作できなくなります。
- 対策: 重い処理が必要な場合は、VBAから外部のスクリプト(PythonやVBScript)を非同期で呼び出すか、一度一時ファイルに情報を書き出し、別のプロセスで処理させる設計を検討してください。
③ エラーハンドリングの徹底
イベントハンドラ内でエラーが発生してマクロが止まると、SolidWorks全体の挙動が不安定になることがあります。
- 対策: `On Error GoTo ErrorHandler` を必ず記述し、エラーが起きても「静かにログを残して処理を抜ける」設計にしてください。ユーザーの作業を中断させてはいけません。
まとめ:次なるステップへ
いかがでしたか?
「ボタンを押して動かす」から「システムの動きに同期する」へ。この考え方を手に入れたあなたは、もう単なるマクロ使いではありません。「業務プロセスを設計するエンジニア」への入り口に立っています。
まずは、今回紹介したクラスモジュールの構造を理解し、自分の環境で「ログが出るかどうか」から試してみてください。
一歩ずつ、着実に。SolidWorks VBAの深淵へ、共に進んでいきましょう。応援していますよ!
