【入門編】【実務中級】合致エラー(Mate Error)が発生したフィーチャーをVBAで自動検出してドキュメントから一括削除するクレンジングマクロ – SolidWorks VBA解析バイブル

スポンサーリンク

設計変更の嵐が吹き荒れた翌朝、アセンブリを開くと画面左側のフィーチャーツリーが「真っ赤なエラーマーク(警告)」で埋め尽くされている……。3D CADを扱う設計者なら、誰もが一度は冷や汗を流したことのある光景ですよね。

「合致エラーを一つひとつ右クリックして削除するだけで、午前中が終わってしまった」
「マクロの記録を使ってみたけれど、特定のファイルでしか動かなくて役に立たなかった」

そんな悩みを抱えているあなたへ。
今回は、SolidWorks VBAを使って、アセンブリ内の「エラーを起こしている合致関係」を自動で検出し、ボタン一発で一括削除するクレンジングマクロを一緒に作りましょう!

マクロ記録の「決まった操作の再生」から脱却し、「自分で状況を判断して処理する」というプログラミングの本質へステップアップするのに最適なテーマです。「ここをクリアすれば、SolidWorks VBAの基本はバッチリですよ」と自信を持って言える設計になっています。

優しく、丁寧に、そしてプロの現場で即戦力となる深い知見まで詰め込んで解説します。リラックスして、お気に入りのコーヒーを片手に読み進めてくださいね。

—

1. なぜ「マクロの記録」ではエラー合致を消せないのか?

まずは、なぜマクロの記録(自動記録機能)ではこの処理が作れないのか、その理由から紐解いていきましょう。

マクロの記録は、「画面上の特定の名前(例: `合致1`)を選択して削除した」という、あなたの「操作」をそのまま記録するだけの機能です。
しかし、実務のアセンブリでは以下の状況が常に変化します。

  • エラーが起きている合致の名前は毎回違う(`一致5` だったり `同軸12` だったりする)。
  • エラーの数も、発生している場所もバラバラ。

つまり、マクロに必要なのは「操作の記録」ではなく、「アセンブリ全体を見渡して、エラーが出ている合致を自分で探し出し、それだけを狙い撃ちして消す」という「ロジック(論理)」なのです。

オブジェクトの繋がり(イメージ図)

SolidWorksの内部データは、以下のような「階層構造(ツリー構造)」になっています。

[アセンブリ (ModelDoc2)]
│
└── [フィーチャーの並び (Feature)]
├── 部品A (Component)
├── 部品B (Component)
└── [合致フォルダ (MateGroup)]
├── 合致1 (Mate) ── [ステータス: 正常]
├── 合致2 (Mate) ── [ステータス: エラー!] ── ★これを見つけて消したい!
└── 合致3 (Mate) ── [ステータス: 正常]

VBAを使って、このツリー構造の上から下までを順番にスキャン(走査)し、「おや、君はエラーを起こしている合致(Mate)だね?」と判定して、安全に削除していくコードを構築します。

—

2. 実務直結!エラー合致一括クレンジングマクロ

それでは、実際のVBAコードを見てみましょう。
SolidWorksのVBAエディタ(Alt + F11)を開き、挿入メニューから「標準モジュール」を作成して、以下のコードをそのまま貼り付けてみてください。

Option Explicit

‘ ==============================================================================
‘ 処理名:DeleteErrorMates
‘ 概要:アクティブなアセンブリ内の「エラー/警告」が出ている合致フィーチャーを
‘ 自動的に検出し、一括で安全に削除します。
‘ ==============================================================================
Public Sub DeleteErrorMates()
‘ — 1. SolidWorksのオブジェクト変数の宣言 —
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssy As SldWorks.AssemblyDoc
Dim swFeat As SldWorks.Feature
Dim swSubFeat As SldWorks.Feature

‘ — 2. 削除対象を一時的にストックするコレクション —
‘ ループの最中に直接削除すると、ツリーのインデックスがズレて誤動作するため、
‘ 一度リストに退避させてから最後に一括削除します(超重要プロテクニック)。
Dim deleteList As Collection
Set deleteList = New Collection

‘ — 3. SolidWorksへの接続とアクティブドキュメントの取得 —
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc

‘ 実行前チェック:ドキュメントが開かれているか?
If swModel Is Nothing Then
MsgBox “SolidWorksでアセンブリを開いてから実行してください。”, vbExclamation, “エラー”
Exit Sub
End If

‘ 実行前チェック:開いているのは本当にアセンブリか?
If swModel.GetType <> swDocumentTypes_e.swDocASSEMBLY Then
MsgBox “このマクロはアセンブリドキュメントでのみ実行できます。”, vbExclamation, “エラー”
Exit Sub
End If

‘ アセンブリ用オブジェクトにキャスト
Set swAssy = swModel

‘ — 4. フィーチャーツリーの走査(トラバース) —
‘ アセンブリの最初のフィーチャーを取得
Set swFeat = swModel.FirstFeature

Do While Not swFeat Is Nothing
‘ フィーチャーのタイプ名を取得
Dim featTypeName As String
featTypeName = swFeat.GetTypeName2()

‘ 「合致フォルダ(MateGroup)」を見つけたら、その中身をスキャンする
If featTypeName = “MateGroup” Then
‘ フォルダ内の最初の合致(子フィーチャー)を取得
Set swSubFeat = swFeat.GetFirstSubFeature()

Do While Not swSubFeat Is Nothing
‘ 子フィーチャーのエラー状態をチェック
If IsFeatureError(swSubFeat) Then
‘ エラーがあれば削除リストに追加
deleteList.Add swSubFeat
End If
‘ 次の合致へ進む
Set swSubFeat = swSubFeat.GetNextSubFeature()
Loop
End If

‘ 次のメインフィーチャーへ進む
Set swFeat = swFeat.GetNextFeature()
Loop

‘ — 5. 安全な一括削除処理の実行 —
Dim errorCount As Long
errorCount = deleteList.Count

If errorCount = 0 Then
MsgBox “エラーのある合致関係は見つかりませんでした。きれいなアセンブリです!”, vbInformation, “クレンジング完了”
Exit Sub
End If

‘ ユーザーへの最終確認
Dim confirm As VbMsgBoxResult
confirm = MsgBox(“エラーの発生している合致が ” & errorCount & ” 件見つかりました。” & vbCrLf & _
“これらを一括削除してもよろしいですか?”, vbYesNo + vbQuestion, “削除の確認”)

If confirm = vbNo Then
MsgBox “処理をキャンセルしました。”, vbInformation
Exit Sub
End If

‘ 画面更新を一時停止して処理速度を劇的に向上させる
swModel.FeatureManager.EnableFeatureTree = False

‘ リストに溜めたエラー合致を順番に選択して削除
Dim item As Variant
Dim targetFeat As SldWorks.Feature
Dim selectStatus As Boolean
Dim deleteStatus As Boolean

For Each item In deleteList
Set targetFeat = item
‘ フィーチャーを選択(追加選択モードで選択バッファに溜める)
selectStatus = targetFeat.Select2(True, 0)

If selectStatus Then
‘ 選択した合致を削除
deleteStatus = swModel.EditDelete()
If Not deleteStatus Then
Debug.Print “削除に失敗しました: ” & targetFeat.Name
End If
End If
Next item

‘ 画面更新を再開し、アセンブリを再構築(リビルド)
swModel.FeatureManager.EnableFeatureTree = True
swModel.ForceRebuild3 True ‘ 強制再構築

MsgBox errorCount & ” 件のエラー合致をクリーンアップしました!”, vbInformation, “成功”
End Sub

‘ ==============================================================================
‘ 関数名:IsFeatureError
‘ 概要:対象のフィーチャーにエラーまたは警告が発生しているかを判定します。
‘ ==============================================================================
Private Function IsFeatureError(ByVal feat As SldWorks.Feature) As Boolean
Dim errorCode As Long
Dim warningCode As Long

‘ フィーチャーのエラーコードと警告コードを取得
‘ (正常な場合は 0 が返されます)
errorCode = feat.GetErrorCode2()
warningCode = feat.GetWarningCode()

‘ エラーコードまたは警告コードが 0 以外なら「異常あり」と判定
If errorCode <> 0 Or warningCode <> 0 Then
IsFeatureError = True
Else
IsFeatureError = False
End If
End Function

—

3. ここがプロの知恵!ソースコードの深掘り解説

このコードには、実務で絶対にバグを起こさないための「プロのノウハウ」が3つ散りばめられています。これらを理解することで、あなたのVBAの理解度は一気に深まります。

① なぜ見つけた瞬間に削除(Delete)してはいけないのか?

最も陥りやすい罠が、ツリーを上からスキャンしながら、エラーを見つけたその場で `swSubFeat.Select2` して `EditDelete` してしまうことです。

‘ 【悪い例:バグの原因になります】
Do While Not swSubFeat Is Nothing
If エラー判定 Then
swSubFeat.Select2 …
swModel.EditDelete ‘ ← ここで消すと、ツリーの構造が変わってしまう!
End If
Set swSubFeat = swSubFeat.GetNextSubFeature() ‘ ← 次の要素を見失ってエラーになる
Loop

ツリーのループ中に要素を削除すると、SolidWorksは「次に進むべき相手(`GetNextSubFeature`)」を見失い、マクロが途中でクラッシュするか、いくつかのエラー合致を読み飛ばしてしまいます。

これを防ぐために、今回のコードでは `deleteList` という「ゴミ箱(コレクション)」を一時的に用意し、削除したい合致をメモしておくだけに留めています。すべてのスキャンが終わった後に、安全な別のループで一括してゴミ箱の中身を削除しているのです。

② `GetErrorCode2` と `GetWarningCode` の使い分け

SolidWorksのフィーチャーエラーには、完全に破綻している「エラー(赤マーク)」と、注意を促す「警告(黄マーク)」の2種類があります。
APIではこれらが明確に区別されています。

  • `GetErrorCode2()`: 致命的なエラーコードを返します(正常なら `0`)。
  • `GetWarningCode()`: 警告コードを返します(正常なら `0`)。

プロの現場では、「警告マークが付いた合致も、後々のトラブルの種になるので一緒に消し去りたい」というケースがほとんどです。そのため、今回の判定関数 `IsFeatureError` では、両方の値が `0` であること(=完全な正常)を厳しくチェックしています。

③ `EnableFeatureTree = False` による高速化

大量のエラー合致を1つずつ消していく際、SolidWorksは毎回、画面左側のツリー表示を更新しようとします。これが数十件に及ぶと、画面がチラつき、処理速度が著しく低下します。

そこで、削除処理の直前に `EnableFeatureTree = False` でツリーの描画更新を止め、すべて消し去った後に `True` に戻して一括で再描画させています。この1行を入れるだけで、処理速度が3倍〜10倍近く高速化します。

—

4. 陥りやすいエラーとトラブルシューティング

実際にこのマクロを動かす際、初心者が引っかかりやすいポイントを先回りして解説します。

Q1. 「実行時エラー ’91’: オブジェクト変数または With ブロック変数が設定されていません」と出る

原因: SolidWorksで何もファイルを開いていないか、または「部品(Part)」や「図面(Drawing)」を開いた状態で実行していませんか?
対策: コードの冒頭にある「実行前チェック」が正しく機能しているか確認してください。必ずアセンブリ(`.sldasm`)をアクティブにした状態で実行する必要があります。

Q2. エラー合致は消えたけれど、画面の表示が変わらない

原因: SolidWorksの画面描画(グラフィックス)が追い付いていない状態です。
対策: コードの最後にある `swModel.ForceRebuild3 True` が、モデルを完全に強制再構築して画面を最新状態に更新します。これが入っていれば解決します。

—

まとめ:マクロ記録の先にある「自動化の感動」へ

お疲れ様でした!
今回作成したクレンジングマクロは、設計変更が多い現場であればあるほど、日常の設計業務を劇的にサポートしてくれる相棒になります。

今回学んだ以下のステップは、すべての高度なSolidWorks VBAの土台となる超重要コンセプトです。

1. ツリーの走査(トラバース): `FirstFeature` から順に要素を巡回する。
2. 状態の判定(インテリジェンス): `GetTypeName2` や `GetErrorCode2` でオブジェクトの状態を見分ける。
3. 安全な一括処理: リストに溜めてから一括で削除・編集を行う。

これが理解できれば、次は「エラーのある合致だけを抑制(サプレス)するマクロ」や、「特定の名前を持つ部品だけを抽出するマクロ」など、応用は無限に広がります。

「手作業でやっていたあの不毛な時間が、自分が書いたコードで一瞬で終わった!」という感動を、ぜひ設計チームの仲間にもお裾分けしてあげてくださいね。

一歩ずつ、楽しみながらVBAの階段を上っていきましょう。あなたなら、きっとSolidWorksを自由自在に操るエキスパートになれますよ!

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