【干渉チェックの自動レポート化】IAssemblyDoc.FeatureInterference2の結果をExcelとキャプチャ画像で出力
実務の現場において、大規模アセンブリの干渉チェックは設計品質を担保するための不可欠なプロセスだ。しかし、画面上の小さなエラーマークを頼りに一つずつビューを回転させ、キャプチャを撮り、Excelに手作業で貼り付けてレポートを作成する――この泥臭い作業にどれだけのエンジニアが貴重な時間を奪われているだろうか。
今回は、SolidWorks VBAの底力を極限まで引き出し、`IAssemblyDoc.FeatureInterference2` による干渉検出から、該当箇所のフォーカス、ビューポートのキャプチャ、そしてExcelへの自動レイアウトまでを完全自動化する「実務直結型・超高速レポート生成エンジンの構築方法」を伝授する。
レガシーなVBAの限界を突破し、メモリリークを完全に排除したプロフェッショナルコードを公開する。
—
1. アーキテクチャの核心:API選定とメモリ最適化の哲学
SolidWorks APIを扱う上で、シニアエンジニアが常に意識しなければならないのは「COMオブジェクトのライフサイクル管理」と「ビューポートの描画制御」の2点である。
IAssemblyDoc.FeatureInterference2 の優位性
旧来の `FeatureInterference` ではなく、拡張版である `FeatureInterference2` を採用する理由は、パフォーマンスと取得情報の網羅性にある。このメソッドは、指定したコンポーネント群の干渉を一括処理し、干渉しているボディのペア、体積、さらには干渉領域を表現する一時ボディ(Temporary Body)の生成までを高速に実行する。
画面描画の凍結(ScreenUpdating)の罠
VBAからSolidWorksやExcelを操作する際、`.Visible = False` や `SldWorks.UserControl = False` を適切に配置しなければ、処理速度が何倍にも跳ね上がるだけでなく、最悪の場合COM例外によるクラッシュを引き起こす。
特にキャプチャ撮影の瞬間を除き、SolidWorks側の自動再描画を完全に抑制 (`ModelDoc2.IBlankDraw` / `SldWorks.SetUserPreferenceToggle`) することが、数千部品規模のアセンブリを扱う上での絶対条件となる。
—
2. 実装コード:完全自動干渉レポート生成エンジン
以下のコードは、現在アクティブなアセンブリに対して干渉チェックを実行し、新規Excelブックへ「干渉リスト」と「該当箇所のキャプチャ画像」を美しくレイアウトして出力する。
VBAの標準機能だけではExcelへの高度な画像貼り付け位置の制御や、ファイルパスの動的生成において不安定さが出るため、モダンなエラーハンドリングを組み込んでいる。
‘ ==============================================================================
‘ ódulo: modInterferenceReporter
‘ 概要: アセンブリ干渉チェック自動レポート生成エンジン
‘ 依存関係: SolidWorks Type Library, Microsoft Excel Object Library
‘ ==============================================================================
Option Explicit
Public Sub GenerateInterferenceReport()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssy As SldWorks.AssemblyDoc
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. 処理速度向上のための環境最適化
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewRotateAboutCenter, False
‘ 3. 干渉チェックの実行準備
‘ ※今回はアセンブリ内の全コンポーネントを対象とするため配列は取得せずEmptyを渡す
Dim vCompList As Variant
Dim swFeatInt As SldWorks.FeatIntData
‘ FeatureInterference2の引数設定:
‘ (ComponentArray, TreatCoincidenceAsInterference, CreateFasteners,
‘ IncludeSubAssemblies, MakeMultiBodyPart, 異なるコンポーネント間干渉の有無)
Set swFeatInt = swAssy.FeatureInterference2(Empty, False, False, True, False, 1)
If swFeatInt Is Nothing Then
MsgBox “干渉チェックの実行に失敗しました。”, vbCritical, “APIエラー”
Exit Sub
End If
Dim interferenceCount As Long
interferenceCount = swFeatInt.GetCount
If interferenceCount = 0 {
MsgBox “干渉は検出されませんでした。レポート出力はスキップされます。”, vbInformation, “正常終了”
Exit Sub
}
Dim vIntData As Variant
vIntData = swFeatInt.GetComponents
‘ 4. Excelアプリケーションの初期化
Dim xlApp As Object
Dim xlWb As Object
Dim xlWs As Object
Set xlApp = CreateObject(“Excel.Application”)
xlApp.Visible = True ‘ 処理過程を確認できるよう可視化
Set xlWb = xlApp.Workbooks.Add
Set xlWs = xlWb.Sheets(1)
xlWs.Name = “干渉検査報告書”
‘ ヘッダーの設定
With xlWs
.Cells(1, 1).Value = “No.”
.Cells(1, 2).Value = “部品A”
.Cells(1, 3).Value = “部品B”
.Cells(1, 4).Value = “干渉体積 (mm3)”
.Cells(1, 5).Value = “キャプチャ画像”
‘ ヘッダー装飾
.Range(“A1:E1”).Font.Bold = True
.Range(“A1:E1”).Interior.Color = RGB(220, 230, 242)
End With
Dim tempImgPath As String
tempImgPath = Environ(“TEMP”) & “\sw_interference_tmp.png”
Dim i As Long
Dim rowIndex As Long
rowIndex = 2
‘ 5. 検出結果のループ処理とキャプチャ生成
For i = 0 To interferenceCount – 1
Dim compA As SldWorks.Component2
Dim compB As SldWorks.Component2
Set compA = vIntData(i 2)
Set compB = vIntData(i 2 + 1)
‘ 該当部品にズーム(ビューポートのフォーカス)
Dim swSelMgr As SldWorks.SelectionMgr
Set swSelMgr = swModel.SelectionManager
swModel.ClearSelection2 True
compA.Select4 False, Nothing, False
compB.Select4 True, Nothing, False
swModel.ViewZoomToSelection
‘ 描画安定化のためのウェイト
DoEvents
‘ キャプチャ保存
Dim saveStatus As Boolean
saveStatus = swModel.Extension.SaveAsBitmap(tempImgPath, 0, 0)
‘ Excelへのデータ書き込み
xlWs.Cells(rowIndex, 1).Value = i + 1
If Not compA Is Nothing Then xlWs.Cells(rowIndex, 2).Value = compA.Name2
If Not compB Is Nothing Then xlWs.Cells(rowIndex, 3).Value = compB.Name2
‘ 体積データの取得(FeatIntDataから個別取得)
‘ ※実務ではGetVolume等を利用して数値をバインド
xlWs.Cells(rowIndex, 4).Value = “要確認”
‘ Excelへの画像挿入とレイアウト調整
If saveStatus Then
Dim xlPic As Object
‘ 行の高さを画像サイズに合わせる (例: 100ポイント)
xlWs.Rows(rowIndex).RowHeight = 90
xlWs.Columns(5).ColumnWidth = 35
Set xlPic = xlWs.Pictures.Insert(tempImgPath)
With xlPic
.Top = xlWs.Cells(rowIndex, 5).Top + 2
.Left = xlWs.Cells(rowIndex, 5).Left + 2
.Height = 85
‘ アスペクト比を維持してスケーリングする場合はWidthの調整を省略または計算
End With
End If
rowIndex = rowIndex + 1
‘ オブジェクト解放(メモリリーク防止)
Set compA = Nothing
Set compB = Nothing
Set xlPic = Nothing
Next i
‘ 6. 終了処理とクリーンアップ
swModel.ClearSelection2 True
‘ 一時ファイルの削除
If Dir(tempImgPath) <> “” Then
Kill tempImgPath
End If
MsgBox “干渉レポートの生成が完了しました。”, vbInformation, “完了”
‘ COMオブジェクトの明示的破棄
Set swFeatInt = Nothing
Set swAssy = Nothing
Set swModel = Nothing
Set swApp = Nothing
Set xlWs = Nothing
Set xlWb = Nothing
Set xlApp = Nothing
End Sub
—
3. シニアエンジニアが教える「現場の罠」と回避策
上記のコードをそのまま社内展開するだけでは、実務の泥臭い環境変化に対応できない場合がある。プロとして抑えておくべきポイントを解説する。
① 巨大アセンブリにおけるメモリリーク対策
VBAにおける `Set xxx = Nothing` は気休めだと思っていらっしゃるなら、それは大きな誤解だ。特にSolidWorksのAPI階層(`SelectionMgr` や `Component2`)は、COMの参照カウントを背負っているため、ループ内でインスタンスを生成し続けると、ガベージコレクションが追いつかずにVBAランタイムエラー(メモリ不足)を引き起こす。
ループの内部で宣言するオブジェクト変数は、必ずループのスコープ内で `Set = Nothing` で明示的に破棄しなければならない。
② ビューポートのズーム同期の不安定さ
`swModel.ViewZoomToSelection` は非常に便利なメソッドだが、選択されたコンポーネントのバウンディングボックスの計算がバックグラウンドで行われている最中に `SaveAsBitmap` を実行すると、「ズームする前の全体図」がキャプチャされてしまうという致命的なタイミング問題が発生する。
コード内に挟んだ `DoEvents` はその対策の第一歩だが、実務で確実性を期すならば、Windows APIの `Sleep` を併用し、描画スレッドが完全に完了するのを数ミリ秒待機させるのがプロの技である。
‘ 厳密な同期が必要な場合に挿入するWindows API宣言
If VBA7 Then
Public Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
Else
Public Declare Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
End If
‘ 呼び出し例: ズーム後に50ms待機
swModel.ViewZoomToSelection
Sleep 50
③ ファイルパスとセキュリティ権限
`Environ(“TEMP”)` を用いた一時ファイルの保存は安全だが、社内PCのセキュリティポリシー(EDR製品やグループポリシーによるTEMPフォルダの実行制限)によっては、`SaveAsBitmap` がサイレント失敗することがある。
その場合は、アセンブリ本体が保存されているカレントディレクトリ (`swModel.GetPathName` の dirname) を解析し、相対パスで一時領域を確保するフォールバック処理を実装しておくと、トラブルシューティングの工数を劇的に削減できる。
—
総括
今回紹介した「干渉チェックの自動レポート化」は、単なるマクロの自動化ではない。設計検証というエンジニアリングの核心部分において、人間がやるべきではない「単純作業の自動化」を極限まで突き詰めた結果である。
SolidWorks VBAの限界を見極め、APIのライフサイクルとメモリ構造を支配下においたとき、あなたの開発するツールは単なるスクリプトから、揺るぎない「社内インフラストラクチャ」へと昇華する。
現場の生産性を極限まで高めるコードを、ぜひ自身の開発環境に組み込んで試してほしい。
