SolidWorks VBAを掌握する極限の知見
【実務中級】AddMate5の「MateErrorStatus」戻り値を使った合致成功・失敗の動的判定とログ出力
こんにちは。チーフアーキテクトの私だ。
これまで数多くの大規模アセンブリ自動化プロジェクトを見てきたが、現場で最も多いトラブルは何だと思う?
「せっかく組んだマクロが、巨大アセンブリのモデル更新で突然エラーを吐いて止まる」
「どの部品とどの面(フェイス)の組み合わせで合致(Mate)が破綻したのか、デバッグ画面の海から探す羽目になる」
特に、`IMate2` や `IAssemblyDoc::AddMate5` を使った動的な合致生成において、エラーハンドリングを怠ることは、時限爆弾を抱えてコードを走らせるようなものだ。
今回は、`AddMate5` が返す `MateErrorStatus` のビットマスクを完全網羅し、「なぜ合致が失敗したのか」をプログラム自身に判定させ、テキストログとして自動出力するプロダクションコードを授けよう。お遊びのコードは書かない。実務で即座に使える堅牢な設計だけを叩き込む。
—
1. なぜ「なんとなく合致」のコードは実務で破綻するのか?
多くの初学者や中級の壁を超える手前のエンジニアは、次のようなコードを書く。
‘ 【悪手】エラーを無視、または Err だけで判定するダメな例
Dim swMateLnk As SldWorks.Mate2
Set swMateLnk = swAssy.AddMate5(swMateType_Coincident, swMateAlign_ALIGNED, False, 0, 0, 0, 0, 0, 0, 0, 0, False, errorStatus)
If errorStatus <> 0 Then
MsgBox “合致失敗!” ‘ ← これじゃあ何が原因で失敗したか分からない!
End If
これの何が問題か?
SolidWorksのAPIは広大だが、`AddMate5` の第13引数(または戻り値周辺)で返される `errorStatus`(MateErrorStatus)は、単なる「失敗したかどうか」のフラグではなく、失敗の「理由」をビット演算で保持しているのだ。
面が存在しないのか? ジオメトリが干渉しているのか? すでに過拘束(Over-defined)なのか?
これを無視して「動かない」と嘆くのは、目隠しでF1カーを運転するようなもの。APIの仕様をねじ伏せ、状態をコードでロギングするのがプロの仕事だ。
—
2. `MateErrorStatus` の真実とビット判定のロジック
`AddMate5` のエラーステータスは、主に以下のようなエラーコードの組み合わせ(ビットフラグ)として返される。
- `swAddMateError_NoError` (0) : 成功
- `swAddMateError_IncorrectEntity` (1) : エンティティが無効、または選択ミス
- `swAddMateError_EntitiesAlreadyMated` (2) : すでに同じ合致が存在する
- `swAddMateError_NonSelectableEntity` (4) : 選択できないエンティティ
- `swAddMateError_Failed` (7) : 一般的な失敗
これらを正確に捉えるには、単なる `If` 文ではなく、ビットAND演算子 (`And`) を用いた判定が必要になる。ここをサボるから、複雑なアセンブリでデバッグ地獄に陥るのだ。
—
3. 【プロダクションコード】堅牢な動的合致&ログ出力システム
実務の現場でそのままコピー&ペーストし、パスや対象コンポーネント名を書き換えるだけで稼働するメインモジュールを公開しよう。
このコードは、ファイルI/Oによるエラーログ出力(UTF-8対応のFileSystemObject)も標準装備している。
Option Explicit
‘ ==============================================================================
‘ 業務自動化アーキテクチャ: AddMate5 堅牢実行&エラーログ出力モジュール
‘ ==============================================================================
Public Sub RunRobustMateAutomation()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssy As SldWorks.AssemblyDoc
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
‘ ドキュメントチェック
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
‘ ログファイルのパス設定 (デスクトップに出力)
Dim logFilePath As String
logFilePath = CreateObject(“WScript.Shell”).SpecialFolders(“Desktop”) & “\SolidWorks_Mate_ErrorLog.txt”
‘ ログファイルの初期化
Call InitializeLogFile(logFilePath)
Call WriteLog(logFilePath, “=== 合致自動定義プロセス開始: ” & Now & ” ===”)
‘ — 【実務シミュレーション】コンポーネントの選択と合致実行 —
‘ ※実務ではここでコレクションや外部DB/CSVから部品名と面名を取得してループさせます
Dim compName1 As String, compName2 As String
compName1 = “Bracket-1<1>”
compName2 = “BasePlate-1<1>”
‘ ターゲットの面をクリアして選択 (本来はIModelDocExtension::SelectByID2等を使用)
swModel.ClearSelection2 True
Dim boolstatus As Boolean
‘ 例: Face<1> 同士を一致(Coincident)させる仮実装
boolstatus = swModel.Extension.SelectByID2(“Face1”, “FACE”, 0, 0, 0, True, 1, Nothing, 0)
boolstatus = swModel.Extension.SelectByID2(“Face2”, “FACE”, 0, 0, 0, True, 1, Nothing, 0)
Dim errorStatus As Long
Dim swMate As SldWorks.Mate2
‘ AddMate5の実行
‘ 引数: Type, Aligned, Flip, Dist, DistMax, DistMin, Ang, AngMax, AngMin, LockRotation, UseLimits, 戻り値(ErrorStatus)
Set swMate = swAssy.AddMate5( _
swMateType_Coincident, _
swMateAlign_ALIGNED, _
False, _
0#, 0#, 0#, 0#, 0#, 0#, 0#, 0#, _
False, _
errorStatus)
‘ — エラーステータスの動的解析とログ出力 —
If errorStatus = 0 Then
Call WriteLog(logFilePath, “[SUCCESS] 合致の作成に成功しました: ” & compName1 & ” と ” & compName2)
swModel.EditRebuild3 ‘ モデルの再構築
Else
Dim errDetail As String
errDetail = ParseMateError(errorStatus)
Dim logMsg As String
logMsg = “[ERROR] 合致失敗 | 対象: ” & compName1 & ” & ” & compName2 & ” | コード: ” & errorStatus & ” | 詳細: ” & errDetail
Call WriteLog(logFilePath, logMsg)
MsgBox “合致の作成に失敗しました。詳細はデスクトップのログを確認してください。” & vbCrLf & “理由: ” & errDetail, vbExclamation
End If
Call WriteLog(logFilePath, “=== 合致自動定義プロセス終了 ===”)
MsgBox “処理が完了しました。”, vbInformation
End Sub
‘ ==============================================================================
‘ MateErrorStatus のビットマスク解析エンジン
‘ ==============================================================================
Private Function ParseMateError(ByVal errCode As Long) As String
Dim details As String
details = “”
‘ ビット演算によるエラー要因の特定
If (errCode And 1) <> 0 Then details = details & “【不適切なエンティティ(IncorrectEntity)】 ”
If (errCode And 2) <> 0 Then details = details & “【すでに合致済み(EntitiesAlreadyMated)】 ”
If (errCode And 4) <> 0 Then details = details & “【選択不可能なエンティティ(NonSelectableEntity)】 ”
If (errCode And 8) <> 0 Then details = details & “【ジオメトリの矛盾・過拘束(Redundant/Failed)】 ”
If (errCode And 16) <> 0 Then details = details & “【参照先の欠落またはコンテキストエラー】 ”
If details = “” Then
details = “不明なエラー (Raw Code: ” & errCode & “)”
End If
ParseMateError = details
End Sub
‘ ==============================================================================
‘ ファイルI/O: テキストログ書き込みユーティリティ
‘ ==============================================================================
Private Sub InitializeLogFile(ByVal filePath As String)
Dim fso As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ ファイルが存在する場合は上書き作成
Dim ts As Object
Set ts = fso.CreateTextFile(filePath, True)
ts.Close
End Sub
Private Sub WriteLog(ByVal filePath As String, ByVal message As String)
Dim fso As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ ForAppending (8), Unicode (True)
Dim ts As Object
Set ts = fso.OpenTextFile(filePath, 8, True)
ts.WriteLine message
ts.Close
End Sub
—
4. 現場で生きる!ファイル・データベース連携の設計知見
このマクロを単発のツールで終わらせず、社内の設計プロセスに組み込む(DBやCSV連携を行う)場合の注意点を共有しておこう。
1. トランザクション的思考(ロールバックの担保)
アセンブリの合致定義途中でエラーが発生した場合、中途半端に拘束されたモデルが残ると、次回の実行時に `swAddMateError_EntitiesAlreadyMated` や予期せぬ過拘束を引き起こす。
エラーを検知した際は、直ちに `IModelDocExtension::Undo` をコールするか、ファイルを保存せずに閉じる(`swModel.CloseDoc`)リトライ・クリーンアップ機構を必ず設計に組み込め。
2. 外部DB/CSVからのデータインジェクション時のエンティティ名一意性
ExcelやSQLデータベースから「どの部品のどの面を結合するか」を読み込む際、コンポーネント名(例: `Bracket-1<1>`)はコンフィギュレーションやアセンブリの階層が変わると一発で崩壊する。
実務では、Component2::GetPathName や Component2::GetID を組み合わせ、パスベースで一意に特定できる仕組みを裏で構築しておくべきだ。
—
チーフアーキテクトからの総括
「動けばいいや」のコードは、現場のエンジニアの信頼を失う。
SolidWorks APIは非常に強力だが、その分、内部で起きているエラーを隠蔽しやすい。今回紹介した `MateErrorStatus` のビット解析と、堅牢なログ出力を取り入れるだけで、あなたの組む自動化ツールの「品質」はプロの領域へと飛躍する。
エラーを恐れるな。エラーを「可視化」するシステムを作れ。それが、真の業務自動化エンジニアの仕事だ。
