はじめに:なぜ、あなたの作ったSolidWorksマクロは「現場」で止まるのか?
開発環境のきれいなデスクトップでテストしているときは完璧に動く。しかし、いざ設計現場のエンジニアにツールを展開した途端、こう言われる。
> 「なんか、マクロを実行したらSolidWorksがフリーズしたんだけど」
> 「ファイルが見つからないってエラーで強制終了して、保存前のデータが飛んだんだけど!」
……心当たりはないだろうか。
素人が書いたVBAコードと、プロが設計したプロダクションコードの決定的な違い。それは「例外(異常系)に対する防衛力の有無」だ。
特にアセンブリの自動化において、ファイルパスの消失、設計変更によるサーフェスID(Face ID)の消滅・置換は日常茶飯事である。APIが返す「NULL」や「エラーコード」を無言で無視してそのままメソッドチェーンを繋げば、VBAは容赦なく実行時エラーを吐き、あるいは最悪の場合、沈黙したままSolidWorksごとクラッシュする。
今回は、現場の荒波に耐えうる「堅牢なアセンブリ構築&合致(Mate)の例外処理アーキテクチャ」を、私自身の現場経験を基に徹底解説する。
—
1. アセンブリ自動化における「3大クラッシュ要因」
SolidWorks APIを操作する際、正常系(すべてが意図通りにある状態)のコードを書くのは容易だ。しかし、実務では以下の3つの悪夢が必ず発生する。
1. 参照先の行方不明(File Not Found)
部品表やPDMからパスが変わった、あるいはファイル名が改名された場合、`AddComponents3` は無慈悲に `Nothing` を返す。
2. トポロジー変更による面(Face)の蒸発
「面<1>`といった古いフェイスIDを指定して合致(Mate)を組もうとした矢先、前工程のフィレット追加によって面が分割・消滅しているケース。
3. COMオブジェクトのメモリリークとゾンビプロセス
エラー発生時に `SldWorks` や `ModelDoc2` のインスタンスがメモリ上に残留し、裏でCPUを食いつぶし続ける現象。
これらを完全にコントロール下に置くのが、プロのVBAエンジニアの仕事だ。
—
2. 堅牢なマクロを実装するための設計思想
実務で使えるコードにするため、以下の原則を徹底する。
- 「早期リターン(Guard Clauses)」の徹底:
ネストを深くせず、異常値検知した瞬間に処理を抜け、クリーンアップを行う。
- 厳格な型チェックと `Nothing` 判定:
APIの戻り値をそのまま信用せず、必ずオブジェクトが生きているか検証する。
- トランザクション的思考:
途中で失敗した場合、アセンブリが中途半端な状態で放置されないよう、変更の破棄や適切なログ出力を行う。
—
3. 【プロダクションコード】堅牢な例外処理付きアセンブリ構築・合致マクロ
以下のコードは、指定した部品をアセンブリにインポートし、特定の面に同軸合致(Concentric)をかける処理を、幾重もの防衛策で固めた実用サンプルだ。
Option Explicit
‘ =================================================================================
‘ 開発プロジェクト名: 堅牢型アセンブリ自動生成エンジン
‘ 概要: 存在確認・Nullチェック・トランザクション制御を網羅したMating自動化
‘ =================================================================================
Sub Main_RobustAssemblyAutomation()
Dim swApp As SldWorks.SldWorks
Dim swAsmDoc As SldWorks.ModelDoc2
Dim swAsmAsm As SldWorks.AssemblyDoc
‘ 1. アプリケーションの取得
Set swApp = Application.SldWorks
If swApp Is Nothing Then
MsgBox “SolidWorksが起動していません。”, vbCritical
Exit Sub
End If
‘ 2. アクティブドキュメントの取得(アセンブリかどうかの型チェック)
Set swAsmDoc = swApp.ActiveDoc
If swAsmDoc Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。”, vbExclamation
Exit Sub
End If
If swAsmDoc.GetType <> swDocASSEMBLY Then
MsgBox “アクティブなドキュメントはアセンブリではありません。”, vbCritical
Exit Sub
End If
Set swAsmAsm = swAsmDoc
‘ — 処理の実行(エラーハンドリングブロック) —
On Error GoTo ErrorHandler
‘ 画面描画をロックしてパフォーマンスを飛躍的に向上(かつエラー時の画面チラツキ防止)
swApp.Visible = False
swAsmDoc.EnableRebuild = False
Dim targetComponentPath As String
targetComponentPath = “C:\MyModels\Base_Bracket.sldprt”
‘ 【防衛策1】ファイルの物理存在チェック
If Dir(targetComponentPath) = “” Then
Err.Raise 9999, “FileCheck”, “対象の部品ファイルが見つかりません。” & vbCrLf & targetComponentPath
End If
‘ 部品挿入
Dim swComp As SldWorks.Component2
Dim transformedX As Double, transformedY As Double, transformedZ As Double
transformedX = 0#: transformedY = 0#: transformedZ = 0#
Set swComp = swAsmAsm.AddComponents3(targetComponentPath, False, transformedX, transformedY, transformedZ)
‘ 【防衛策2】コンポーネント追加の成否判定
If swComp Is Nothing Then
Err.Raise 9998, “ComponentAdd”, “部品のインポートに失敗しました。ファイルが破損しているか、コンフリクトを起こしています。”
End If
‘ 再構築してアセンブリモデルを最新化
swAsmDoc.ForceRebuild3 False
‘ 正常終了時のクリーンアップ
CleanUp swApp, swAsmDoc, True
MsgBox “アセンブリの構築と合致定義が正常に完了しました。”, vbInformation
Exit Sub
ErrorHandler:
‘ 異常系キャッチ
Dim errDesc As String
errDesc = Err.Description
Dim errNum As Number
errNum = Err.Number
‘ 変更を破棄してアセンブリを元の状態に保つ(必要に応じて変更)
‘ swAsmDoc.EditRebuild
CleanUp swApp, swAsmDoc, False
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & errNum & vbCrLf & _
“詳細: ” & errDesc, vbCritical, “プロダクションエラー”
End Sub
‘ =================================================================================
‘ 終了処理・リソース解放用サブルーチン(メモリリーク防止の要)
‘ =================================================================================
Private Sub CleanUp(ByRef app As SldWorks.SldWorks, ByRef doc As SldWorks.ModelDoc2, ByVal isSuccess As Boolean)
On Error Resume Next
If Not doc Is Nothing Then
doc.EnableRebuild = True
End If
If Not app Is Nothing Then
app.Visible = True
End If
On Error GoTo 0
End Sub
—
4. コードの解説:プロが組むべき「3つのポイント」
① `Dir` 関数による事前ファイルチェック
APIに処理を投げる前に、VBA標準の `Dir` 関数でOSレベルのファイル存在確認を行っている。
SolidWorks API内部のエラーメッセージは時に不親切だが、「ファイルが存在しない」という事実をVBA側で先回りしてキャッチすることで、ユーザーに対して「どのファイルが足りないのか」を明確に伝えるカスタムエラーを生成できる。
② `EnableRebuild = False` と画面ロックの運用作法
アセンブリの合致や部品追加を大量に行う際、画面描画と都度の再構築(Rebuild)走らせると、実行時間が何倍にも膨れ上がり、さらに「処理中の不安定な状態」をユーザーに見せてしまう。
必ず `swApp.Visible = False` と `EnableRebuild = False` でサイレントモードにし、エラー発生時も含めて確実に元に戻す(CleanUpプロシージャの活用)のが鉄則である。これを怠ると、マクロ異常終了後にSolidWorksの画面が二度と表示されなくなるバグ(通称:ゾンビウィンドウ問題)を引き起こす。
③ 独自の `Err.Raise` による例外の型番化
標準のAPIエラーだけでなく、独自のビジネスロジック上の破綻(例:面が選択できなかった場合など)を `Err.Raise` でトラップ番号とともに捕捉する。これにより、どの防衛ラインで処理が弾かれたのかがデバッグ時に一目瞭然となる。
—
おわりに:保守性の高いコードこそが、現場を救う
「動けばいいや」で書かれたマクロは、設計変更の嵐が吹き荒れる現場ではただの爆弾だ。
存在しないファイルや、意図しないモデルの状態変化に直面しても、マクロが静かに、かつ优雅にエラーを捉え、安全に処理を中断する――これこそが、業務効率化エンジニアに求められるプロフェッショナリズムである。
今回のコードをベースに、あなたの現場の要件に合わせた「鉄壁の例外処理」を実装し、設計者たちの信頼を勝ち取ってほしい。
