アセンブリの「負債」を自動検知せよ:SolidWorks APIによるプロパティ検証の極致
設計現場において、アセンブリの階層が深くなればなるほど、「プロパティの欠落」は爆弾となる。PDM連携の失敗、BOM出力の不整合、購買部門への誤発注。これらは単なるヒューマンエラーではない。「検証の自動化」という設計思想の欠如が引き起こすシステム的欠陥だ。
本稿では、SolidWorks VBAの深淵に触れつつ、アセンブリ内の全コンポーネントを再帰的に巡回し、必須プロパティをリアルタイムで監視・レポートする極限のスクリプトを提示する。
—
1. 巡回アルゴリズムの真髄:再帰処理とオブジェクトのライフサイクル
アセンブリを走査する際、単なるループでは不十分だ。サブアセンブリを含む無限階層に対応するためには、再帰関数(Recursive Function)が必須となる。
ここで重要なのが「メモリの解放」だ。VBAはガベージコレクションが脆弱であるため、`SwComponent` や `SwModelDoc` といったCOMオブジェクトをスタックに積み続けると、大規模アセンブリでは即座にメモリリークを引き起こす。常に `Set obj = Nothing` を徹底し、参照カウンタを適切に管理することが、堅牢なシステム構築の最低条件である。
—
2. 実装:プロパティ検証エンジン
以下のコードは、指定した必須プロパティが欠落しているコンポーネントを特定し、ユーザーに警告レポートを提示する中核ロジックである。
Option Explicit
‘ 必須プロパティ定義
Private Const REQUIRED_PROPS As String = “材質|仕上げ|メーカー名”
Sub ValidateAssemblyProperties()
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 Or swModel.GetType <> swDocASSEMBLY Then
MsgBox “アセンブリを開いた状態で実行してください。”, vbCritical
Exit Sub
End If
Set swAssy = swModel
Dim report As String
report = “”
‘ 再帰的にコンポーネントを巡回
TraverseComponents swAssy.GetComponents(False), report
If report <> “” Then
MsgBox “以下のコンポーネントでプロパティが欠落しています:” & vbCrLf & report, vbExclamation
Else
MsgBox “全てのコンポーネントのプロパティは正常です。”, vbInformation
End If
End Sub
Private Sub TraverseComponents(vComps As Variant, ByRef report As String)
Dim i As Long
Dim swComp As SldWorks.Component2
Dim swModel As SldWorks.ModelDoc2
Dim swCustProp As SldWorks.CustomPropertyManager
Dim propList() As String
Dim j As Long
Dim val As String
propList = Split(REQUIRED_PROPS, “|”)
For i = LBound(vComps) To UBound(vComps)
Set swComp = vComps(i)
Set swModel = swComp.GetModelDoc2
If Not swModel Is Nothing Then
Set swCustProp = swModel.Extension.CustomPropertyManager(“”)
For j = LBound(propList) To UBound(propList)
swCustProp.Get4 propList(j), False, val, val
If Trim(val) = “” Then
report = report & swComp.Name2 & ” [” & propList(j) & “]” & vbCrLf
End If
Next j
‘ サブアセンブリがある場合は再帰
If swComp.GetChildrenCount > 0 Then
TraverseComponents swComp.GetChildren, report
End If
End If
‘ 明示的解放:メモリリークを防ぐための要諦
Set swCustProp = Nothing
Set swModel = Nothing
Set swComp = Nothing
Next i
End Sub
—
3. シニアエンジニアが意識すべき「極限の最適化」
① GetModelDoc2の罠
上記のコードで `swComp.GetModelDoc2` を呼び出しているが、これには注意が必要だ。モデルがメモリにロードされていない場合、このメソッドは `Nothing` を返す。大規模アセンブリで「軽量表示」を使用している場合、全コンポーネントを意図的にロードする必要があり、パフォーマンスと精度のトレードオフが生じる。真のアーキテクトは、ロードの成否を判定し、必要に応じて `swModel.Extension.OpenDocument` を検討する柔軟性を持つべきだ。
② Windows APIとの連携
もし警告レポートをより高度なUI(例えば、特定の行をダブルクリックで該当部品をハイライトするなど)にしたいのであれば、VBAの `MsgBox` では力不足だ。ユーザーフォームを作成し、`SendMessage` や `PostMessage` APIを用いて、SolidWorksの選択状態(`swModel.SelectByID2`)を操作するイベント駆動型アーキテクチャへと進化させる必要がある。
③ レガシー環境への配慮
SolidWorksのバージョンが古い場合、`Get4` メソッドの挙動が微妙に異なるケースがある。`CustomPropertyManager` は、コンフィギュレーションごとのプロパティを参照する際、引数にコンフィギュレーション名を明示的に渡す必要があることを忘れてはならない(今回は空文字でアクティブなコンフィグを指定している)。
—
結びに:自動化とは「思想」である
ツールはあくまで補助輪に過ぎない。このスクリプトを導入した直後、現場からは「面倒だ」という声が上がるだろう。しかし、設計品質の担保を個人の注意深さに依存する組織に未来はない。
技術者はコードを書く際、単に動くものを作るのではなく、「システムの整合性を強制する仕組み」を設計しなければならない。このプロパティ検証システムは、あなたの設計環境を「人間がミスをする余地」から「ミスが構造的に排除される環境」へと変える第一歩となるはずだ。
次は、これをPDM(SOLIDWORKS PDM)のライフサイクル遷移イベントとフックさせ、検証を通らなければ図面出図ができないフローを構築するところまで突き詰めてほしい。健闘を祈る。
