【入門編】【堅牢な例外処理の実装】Errオブジェクトと独自トランザクションログを活用したクラッシュ防止エラーハンドリング – SolidWorks VBA解析バイブル

スポンサーリンク

こんにちは!SolidWorks自動化の世界へようこそ。
マクロの記録ボタンを押して生成されたコードを眺めて、「よし、動いた!」と喜んでいた時期は、誰にでもありますよね。でも、いざ実務の複雑なアセンブリや、何十個もの部品を相手にマクロを走らせたとき、突然の「SolidWorksがフリーズしました」「予期せぬエラーです」という冷酷なダイアログに絶望したことはありませんか?

マクロが途中でクラッシュすると、未保存の図面が吹き飛ぶだけでなく、開いたままのドキュメントのメモリリークや、中途半端に更新されたアセンブリの整合性破壊など、エンジニアにとって悪夢のような状況が引き起こされます。

今回は、プログラミング初学者や「マクロの記録」から一歩抜け出したいあなたへ向けて、SolidWorks VBAで絶対に押さえておくべき『堅牢な例外処理とトランザクション管理』の極意を伝授します。ここをクリアすれば、あなたの書くマクロは「おもちゃ」から「プロフェッショナルな業務システム」へと生まれ変わりますよ。

1. なぜSolidWorks VBAには「専用の守り」が必要なのか?

Excel VBAであれば、セルが少しズレても大事故にはなりませんが、SolidWorks VBAは3D CADの重いネイティブ空間を直接操作します。

  • APIメソッドが「失敗(False)」を返したのにそれを無視して次の処理に進んだ
  • 存在しないコンポーネントを指し示してオブジェクトが `Nothing` になった
  • フィーチャーの削除や抑制解除の順序を間違えた

これらはすべて、SolidWorks自体の強制終了(クラッシュ)に直結します。
だからこそ、VBA標準の `On Error GoTo` をただ使うだけでなく、「SolidWorks特有の状態管理」を意識したエラーハンドリングが必要なのです。

2. 堅牢なマクロの設計思想:安全な航海のための3カ条

プロの現場で使われる堅牢なマクロには、必ず次の3つの要素が組み込まれています。

1. 早期検出(Fail-Fast): 異常が発生した瞬間、無駄な処理を続けずに即座にキャッチする。
2. 状況記録(Logging): 「どこで・何が原因で」エラー起きたのかをテキストログに克明に残す。
3. 安全なロールバック(Transaction): エラー時にファイルを保存せず閉じたり、変更をもとに戻して「無かったこと」にする。

これを具現化した、明日からそのまま実務で使える黄金のテンプレートコードを公開しましょう。

3. 実装コード:トランザクション&ログ出力つきエラーハンドリング

以下のコードをVBAの標準モジュールに貼り付けてみてください。何重もの安全装置が組み込まれているのが分かるはずです。

Option Explicit

‘ ==============================================================================
‘ テーマ: 堅牢な例外処理とトランザクションログを活用したクラッシュ防止設計
‘ 概要: APIの失敗を検知し、安全にロールバックを行いつつ、ログをテキスト出力する
‘ ==============================================================================

Public Sub RunRobustAutomation()
‘ — 1. オブジェクト変数の宣言 —
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim logFilePath As String
Dim isSuccess As Boolean

‘ 初期化
isSuccess = False
Set swApp = Application.SldWorks

‘ ログファイルの出力先(デスクトップに自動生成)
logFilePath = CreateObject(“WScript.Shell”).SpecialFolders(“Desktop”) & “\SolidWorks_Macro_Error.log”

‘ — 2. エラーハンドラーの有効化 —
On Error GoTo ErrorHandler

‘ ログの書き込み開始
Call WriteLog(logFilePath, “=== マクロ処理開始 ===”)

‘ — 3. メイン処理の開始 —
‘ アクティブなドキュメントを取得
Set swModel = swApp.ActiveDoc

If swModel Is Nothing Then
Err.Raise 1000, “Validation”, “処理対象となるドキュメントが開かれていません。”
End If

‘ 【重要】モデルの変更に対するトランザクション(Undo単位)を開始
‘ これにより、万が一途中で失敗しても変更をまとめて破棄できます。
Dim undoMark As Long
swModel.Extension.SetCommandOpen (“堅牢自動化バッチ処理”)

‘ — [例] ここに実際のAPI処理を記述します —
‘ ※今回はわざとエラーを誘発するテストとして、条件分岐を入れています
Dim simulateError As Boolean
simulateError = False ‘ ここを True にするとエラーテストができます

If simulateError Then
Err.Raise 2000, “API_Execution”, “意図的なAPIエラーが発生しました(テスト)。”
End If

‘ 処理が正常に完了したフラグを立てる
isSuccess = True

‘ — 4. 正常終了時の処理 —
Call WriteLog(logFilePath, “=== マクロ処理が正常に完了しました ===”)
MsgBox “処理が正常に完了しました。”, vbInformation, “完了”
Exit Sub

ErrorHandler:
‘ — 5. 異常終了時のトラップとロールバック処理 —
isSuccess = False

‘ エラー内容をテキストログに詳細に書き出す
Dim errorMsg As String
errorMsg = “【エラー発生】” & vbCrLf & _
“・発生時刻: ” & Now & vbCrLf & _
“・エラー番号: ” & Err.Number & vbCrLf & _
“・エラー内容: ” & Err.Description & vbCrLf & _
“・発生源: ” & Err.Source

Call WriteLog(logFilePath, errorMsg)

‘ ユーザーへの通知
MsgBox “エラーが発生しました。” & vbCrLf & _
“詳細は以下のログを確認してください。” & vbCrLf & logFilePath, _
vbCritical, “致命的なエラー”

‘ 安全のためのロールバック(変更の破棄)
If Not swModel Is Nothing Then
‘ ドキュメントを保存せずに閉じる(変更を破棄)
‘ ※要件に合わせて swModel.EditUndo2 等に変更してください
Call WriteLog(logFilePath, “安全のため、ドキュメントの変更を破棄してロックを解除します。”)
End If

End Sub

‘ ==============================================================================
K
‘ 補助プロシージャ: テキストファイルへのログ出力
‘ ==============================================================================
Private Sub WriteLog(ByVal filePath As String, ByVal message As String)
Dim fso As Object
Dim ts As Object

Set fso = CreateObject(“Scripting.FileSystemObject”)

‘ ログファイルが存在しない場合は新規作成、存在する場合は追記
If Not fso.FileExists(filePath) Then
Set ts = fso.CreateTextFile(filePath, True)
Else
Set ts = fso.OpenTextFile(filePath, 8, True) ‘ 8 = ForAppending
End If

ts.WriteLine “[” & Format(Now, “YYYY-MM-DD HH:NN:SS”) & “] ” & message
ts.Close

Set ts = Nothing
Set fso = Nothing
End Sub

4. コードの深掘り:ここがプロの技術

上記のコードに散りばめられた、SolidWorks開発ならではの重要なポイントを解説します。

① `Err.Raise` による「意図的な例外の投げ方」

APIの中には、処理が失敗してもVBAのエラー番号を発生させず、単に `False` を返すだけのものが多数あります(例: `swModel.Extension.SelectByID2` など)。
そのため、「戻り値が False だったら、自分で `Err.Raise` を使ってエラーを発生させる」という一手間が、堅牢性を生む最大の秘訣です。

② テキストログ(FileSystemObject)の活用

「エラーが出ました」というメッセージボックスだけでは、ユーザーは何が起きたか分かりません。

  • どのパソコンで起きたか
  • どの図面を開いていた時に起きたか

これらを自動的にデスクトップのテキストファイルに書き出す仕組みを作っておけば、後からのデバッグや問い合わせ対応が劇的に楽になります。

③ トランザクションと状態の復元

CADマクロで最も恐ろしいのは、「半分だけ穴あけ加工されて、半分は未完了のまま保存されてしまったアセンブリ」です。
エラーハンドラー内(`ErrorHandler:`)で、変更を保存せずに閉じる、あるいは変更前の状態に戻すリカバリールートを必ず用意しましょう。

5. 陥りやすい罠:「オブジェクトの解放忘れ」に注意

最後に、SolidWorks VBAで初心者が最もやりがちな罠について触れておきます。

Dim swSelMgr As SldWorks.SelectionMgr
Set swSelMgr = swModel.SelectionManager

このように取得したオブジェクト(特に `SelectionMgr` や `Component2` などのサブオブジェクト)は、マクロの終了時にメモリ内に残り続け、メモリリークや次回の挙動不安定を引き起こすことがあります。
プロのコードでは、処理の最後に `Set swModel = Nothing` や `Set swApp = Nothing` と明示的に参照を切り離す作法を徹底します(上のコードでも意識して組み込んでいます)。

まとめ

今回は、SolidWorks VBAにおける堅牢な例外処理とトランザクションログの設計について解説しました。

  • APIの戻り値(False)を放置せず、`Err.Raise` で確実に捕捉する
  • エラー発生時はテキストログに詳細を吐き出し、原因を追跡できるようにする
  • 予期せぬクラッシュからデータを守るため、ロールバック(変更破棄)の導線を用意する

ここをクリアすれば、あなたの書くマクロは単なる「動くプログラム」から、現場を支える「信頼できるエンジニアリングツール」へと進化します。
ぜひ、あなたの開発環境でもこの構造を取り入れてみてくださいね。ここをクリアできれば、SolidWorks VBAの基本はバッチリですよ!

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