【SolidWorks VBA】干渉チェックの自動化:InterferenceDetectionMgrでアセンブリの地雷を踏む前に刈り取る極限の知見
設計終盤、大径アセンブリの図面をリリースした後に発覚する「部品同士の致命的な干渉」。あの冷や汗をかく瞬間を、私たちは何度経験してきただろうか。
手動での干渉チェックは、気の遠くなるようなマウス操作の繰り返しであり、ヒューマンエラーの温床だ。「チェック漏れゼロ」を担保し、なおかつ検証結果をExcelへ美しく構造化して出力する――これを属人化させず、一撃で完了させるマクロを求めているなら、ここが終着点だ。
今回は、SolidWorks APIの隠れた重鎮である `InterferenceDetectionMgr` を完全掌握し、実務の現場で即座に稼働する「堅牢な干渉検出・レポート自動化エンジン」の全貌を伝授する。
—
1. なぜ「なんとなく書いたコード」では実務で使い物にならないのか?
ネットの海を漂うサンプルコードの多くは、APIをただ順番に叩いているだけの「おもちゃ」に過ぎない。複雑な実務アセンブリでそれらを動かすと、確実に以下の壁にぶ当たる。
- メモリリークとCOMオブジェクトの解放漏れ:
SolidWorks VBAにおいて、`ModelDoc2` やコンポーネント、干渉結果のオブジェクトを適切に破棄しないと、SolidWorks本体がメモリリークを起こし、最悪の場合は強制終了する。
- 非表示部品・コンフィギュレーションの罠:
抑制されている部品や、特定のコンフィギュレーションで非表示になっている要素まで判定対象にしてしまい、無駄な計算コストを払うだけでなく、存在しないはずの干渉エラーに悩まされる。
- 干渉ボリュームの微小値(カスデータ)の処理:
面がわずかに接しているだけの「接触」や、実用上無視できる微小な浮動小数点誤差による干渉検出をどうフィルターするか。ここを制御しないと、Excelレポートがゴミデータで埋め尽くされる。
プロのエンジニアが作るべきは、「重いアセンブリでも沈黙せず、正確無比に結果を吐き出し、エラーハンドリングが完璧なコード」だ。
—
2. アーキテクチャ設計と実装のポイント
`InterferenceDetectionMgr` をアセンブリ (`AssemblyDoc`) から取得し、干渉計算を実行する流儀は以下の通りだ。
1. アクティブドキュメントの型安全な取得と検証
今開いているのが本当にアセンブリなのか? `SwApp.ActiveDoc` を闇雲に信用してはならない。
2. `CreateInterferenceDetectionMgr` のパラメータチューニング
接触を干渉とみなすか、マルチボディの同一パーツ内干渉をどう扱うか、精度は妥当か。ここを明示的に設定する。
3. 干渉結果の配列抽出とExcelへのバッチ書き込み
画面をガチャガチャと再描画させず、メモリ上で結果を配列に保持し、最後にExcelへ一括転送する(パフォーマンスの極限追求)。
—
3. 【プロダクションコード】干渉チェック&Excel出力マクロ
以下のコードは、エラーハンドリング、オブジェクトのクリーンアップ、そして実務に耐えうる堅牢性をすべて備えた完全版だ。VBAエディタの標準モジュールに貼り付けて実行してほしい。
Option Explicit
‘ =========================================================================
‘ プロジェクト名: SolidWorks 干渉チェック自動化エンジンの極意
‘ 概要: アセンブリの干渉を検出し、相手パーツ名と干渉体積をExcelに一覧出力
‘ =========================================================================
Sub RunInterferenceDetectionReport()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssy As SldWorks.AssemblyDoc
Dim swInterferenceMgr As SldWorks.InterferenceDetectionMgr
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
‘ 1. ドキュメントの存在・アセンブリ判定
If swModel Is Nothing Then
MsgBox “ドキュメントが開かれていません。”, vbCritical, “エラー”
Exit Sub
End If
If swModel.GetType <> swDocASSEMBLY Then
MsgBox “アクティブなドキュメントがアセンブリではありません。”, vbCritical, “エラー”
Exit Sub
End If
Set swAssy = swModel
‘ 2. 干渉マネージャーの取得
Set swInterferenceMgr = swAssy.FeatureManager.CreateInterferenceDetectionMgr
If swInterferenceMgr Is Nothing Then
MsgBox “干渉検出マネージャーの初期化に失敗しました。”, vbCritical, “エラー”
Exit Sub
End If
‘ 3. 干渉検出のパラメータ設定(プロフェッショナル仕様)
With swInterferenceMgr
.TreatCoincidenceAsInterference = False ‘ 面の接触は干渉とみなさない
.IncludeMultiBodyPartCollisions = True ‘ マルチボディ部品内の干渉も検出
.IgnoreHiddenBodies = True ‘ 非表示ボディは無視する
.Lock = True ‘ 計算中のモデル変更をロック
.UsingTransform = True
End With
‘ 計算実行
MsgBox “干渉チェックを開始します。アセンブリの規模によっては数分かかる場合があります。”, vbInformation, “処理中”
Dim vInterferenceList As Variant
vInterferenceList = swInterferenceMgr.GetInterferences()
‘ マネージャーの終了処理(重要:これを怠るとSolidWorksの挙動が不安定になる)
swInterferenceMgr.Done
If IsEmpty(vInterferenceList) Then
MsgBox “干渉は検出されませんでした!完璧な設計です。”, vbInformation, “結果”
Exit Sub
End If
Dim interferenceCount As Long
interferenceCount = UBound(vInterferenceList) – LBound(vInterferenceList) + 1
‘ 4. Excelへのデータ出力処理
Dim xlApp As Object
Dim xlWb As Object
Dim xlWs As Object
On Error Resume Next
Set xlApp = GetObject(, “Excel.Application”)
If xlApp Is Nothing Then
Set xlApp = CreateObject(“Excel.Application”)
End If
On Error GoTo 0
xlApp.Visible = True
Set xlWb = xlApp.Workbooks.Add
Set xlWs = xlWb.Sheets(1)
xlWs.Name = “干渉チェックレポート”
‘ ヘッダーの設定
Dim headers As Variant
headers = Array(“No.”, “部品 1”, “部品 2”, “干渉体積 (mm³)”)
xlWs.Range(“A1:D1”).Value = headers
xlWs.Range(“A1:D1”).Font.Bold = True
xlWs.Range(“A1:D1”).Interior.Color = RGB(220, 230, 241)
‘ データを格納する配列の準備 (行数, 4列)
ReDim outputData(1 To interferenceCount, 1 To 4) As Variant
Dim i As Long
Dim swComp1 As SldWorks.Component2
Dim swComp2 As SldWorks.Component2
Dim compName1 As String
Dim compName2 As String
For i = 0 To interferenceCount – 1
Dim swInterference As SldWorks.Interference
Set swInterference = vInterferenceList(i)
‘ 干渉している2つのコンポーネントを取得
Set swComp1 = swInterference.GetComponent1
Set swComp2 = swInterference.GetComponent2
compName1 = IIf(swComp1 Is Nothing, “アセンブリ ルート”, swComp1.Name2)
compName2 = IIf(swComp2 Is Nothing, “アセンブリ ルート”, swComp2.Name2)
outputData(i + 1, 1) = i + 1
outputData(i + 1, 2) = compName1
outputData(i + 1, 3) = compName2
outputData(i + 1, 4) = swInterference.Volume
‘ 個別オブジェクトの解放
Set swInterference = Nothing
Set swComp1 = Nothing
Set swComp2 = Nothing
Next i
‘ 一括書き込み(パフォーマンス最適化の極み)
xlWs.Range(xlWs.Cells(2, 1), xlWs.Cells(interferenceCount + 1, 4)).Value = outputData
‘ 書式設定の調整
xlWs.Columns(“A:D”).AutoFit
xlWs.Range(xlWs.Cells(2, 4), xlWs.Cells(interferenceCount + 1, 4)).NumberFormat = “#,
0.000″
MsgBox “干渉チェックが完了しました。” & vbCrLf & “検出件数: ” & interferenceCount & ” 件”, vbInformation, “完了”
‘ クリーンアップ
Set swInterferenceMgr = Nothing
Set swAssy = Nothing
Set swModel = Nothing
Set swApp = Nothing
End Sub
—
4. コードの深掘り:プロが仕込んだ「3つのこだわり」
① `.Done` メソッドの強制呼び出し
`CreateInterferenceDetectionMgr` を呼び出したセッションは、SolidWorksの内部リソースを占有する。処理の成否に関わらず、必ず `.Done` を実行してマネージャーを解放しなければならない。これを怠ると、次に手動で干渉チェックを開こうとした際にSolidWorksがフリーズする原因になる。
② 配列を使ったExcelへの一括転送
ループの中で `Cells(row, col).Value = …` とExcelを直接叩くコードをよく見かけるが、これは極悪なパフォーマンス低下を招く。COMの境界を何度も跨ぐことになるからだ。
今回のコードでは、一度 `outputData` というVBAのメモリ内配列に全データを詰め込み、`Range.Value = outputData` で一撃でExcelへ流し込んでいる。数千件の干渉データがあっても一瞬で終わる所以がここにある。
③ アセンブリールート部品のハンドリング
干渉する相手が、サブアセンブリの親ではなくトップレベルの空間そのもの(あるいはマルチボディのコンテキスト)である場合、`GetComponent1` が `Nothing` を返すことがある。ここを `IIf` 関数で `”アセンブリ ルート”` と安全に文字列化するロジックを入れることで、ヌルポインタ例外(オブジェクト変数が設定されていませんエラー)を完全にハメ殺している。
—
5. 実運用に向けたさらなる拡張アイデア
このスクリプトをベースに、社内の設計フローへ組み込むための次の一手を提案する。
- HTML/3Dビューとの連携:
干渉しているエンティティ(`SldWorks.Entity`)の位置情報を抽出し、該当部品の色を一時的に赤くハイライトしてスナップショットを撮る処理をループ内に挟む。
- データベース(SQLite/SQL Server)への蓄積:
Excel出力だけでなく、過去の設計資産データとして干渉履歴をDBに蓄積し、「どの設計者が、どのモジュールで何回干渉ミスを起こしたか」の傾向分析AIへつなげる。
手作業のチェックに怯える日々は今日で終わりにしよう。APIを支配する者が、設計プロセスの主導権を握るのだ。
