SolidWorks VBAを掌握する極限の知見:アセンブリ図面自動化の布石 – 部品番号とカスタムプロパティの一括調停
SolidWorks VBAによる自動化の領域において、アセンブリの構築(`AddComponents`や`AddMate5`)で満足しているうちは、まだ初級の域を出ない。真の地獄、そして真の効率化が始まるのは「図面化(Drawing)」のフェーズ、特にバルーン(部品番号)とカスタムプロパティの完全なる同期をプログラム下においた瞬間からだ。
現場の設計者が最も疲弊するのは、アセンブリ構造が変わるたびに図面の部品表(BOM)を手動で確認し、カスタムプロパティ(特に`PartNumber`や`Description`)の抜け漏れを修正する作業である。
今回は、アセンブリ図面を自動生成するための布石として、コンポーネント群のカスタムプロパティをVBAから一気通貫で整備し、図面側が迷わず参照できる「堅牢なメタデータ基盤」を構築する極限の知見を授ける。
—
1. アセンブリ・コンポーネント走査のパラダイムシフト
`AssemblyDoc`からコンポーネントを取得する際、再帰処理(Recursive)を安易に実装してメモリリークやスタックオーバーフローを引き起こすエンジニアが後を絶たない。SolidWorks APIにおけるコンポーネントツリーの走査は、COMオブジェクトの参照カウントのライフサイクルを完全に支配下におく必要がある。
特に大規模アセンブリにおいて、すべてのコンポーネントの`IComponent2`を不必要に保持し続けると、VBAのGC(ガベージコレクション)の遅延相まってSolidWorks本体がフリーズする。
走査時は常に変数を即座に解放し、必要な情報(ファイルパスや設定名)だけを抽出する設計思想が求められる。
—
2. 実務仕様:カスタムプロパティ一括同期エンジン
以下のコードは、アクティブアセンブリの全構成部品(サブアセンブリ含む)を再帰的に走査し、特定のカスタムプロパティ(例: `BOM_NAME` と `STOCK_NO`)が未設定の場合はファイル名から自動生成して流し込む、実務直結のVBAモジュールである。
レガシー環境やマルチバイト文字(日本語ファイル名)が混在する極限の現場でも耐えうるよう、エラーハンドリングとオブジェクトの明示的解放を徹底している。
Option Explicit
‘ =========================================================================
‘ 権限: チーフアーキテクト専用モジュール
‘ 概要: アセンブリ内全コンポーネントのカスタムプロパティ一括整備エンジン
‘ =========================================================================
Sub Main_SyncComponentProperties()
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
‘ 処理の高速化と画面描画の凍結(パフォーマンス最適化)
swApp.UserControl = False
swApp.Visible = False
swModel.EditRebuild
On Error GoTo ErrorHandler
‘ ルートコンポーネントの取得と再帰処理の開始
Dim swRootComp As SldWorks.Component2
Set swRootComp = swAssy.GetRootComponent3(True)
If Not swRootComp Is Nothing Then
ProcessComponentTree swRootComp
End If
ErrorHandler:
If Err.Number <> 0 Then
MsgBox “致命的なエラーが発生しました: ” & Err.Description, vbCritical
End If
‘ 描画の復元とオブジェクトの完全解放
swApp.Visible = True
swApp.UserControl = True
Set swRootComp = Nothing
Set swAssy = Nothing
Set swModel = Nothing
Set swApp = Nothing
MsgBox “カスタムプロパティの一括同期が完了しました。”, vbInformation
End Sub
‘ ————————————————————————-
‘ 再帰的コンポーネント走査プロシージャ
‘ ————————————————————————-
Private Sub ProcessComponentTree(ByVal swComp As SldWorks.Component2)
Dim vChildComps As Variant
Dim i As Long
Dim swChildComp As SldWorks.Component2
‘ 子コンポーネントの取得
vChildComps = swComp.GetChildren
If IsEmpty(vChildComps) Then Exit Sub
For i = LBound(vChildComps) To UBound(vChildComps)
Set swChildComp = vChildComps(i)
‘ 抑制されている部品や軽量コンポーネントの例外処理
If Not swChildComp.IsSuppressed() Then
‘ コンポーネントの参照モデル(Part / SubAssembly)を取得
Dim swChildModel As SldWorks.ModelDoc2
Set swChildModel = swChildComp.GetModelDoc2()
If Not swChildModel Is Nothing Then
‘ プロパティ書込実行
Call WriteCustomProperties(swChildModel, swChildComp)
End If
‘ 再帰呼び出し(サブアセンブリの深層へ潜る)
ProcessComponentTree swChildComp
End If
‘ ループごとのメモリ解放(極限のメモリ最適化)
Set swChildModel = Nothing
Set swChildComp = Nothing
Next i
End Sub
‘ ————————————————————————-
пени: カスタムプロパティ書き込み・調停ロジック
‘ ————————————————————————-
Private Sub WriteCustomProperties(ByVal swModel As SldWorks.ModelDoc2, ByVal swComp As SldWorks.Component2)
Dim swCustPropMgr As SldWorks.CustomPropertyManager
Dim configName As String
Dim fileName As String
Dim valOut As String
Dim resolvedValOut As String
Dim boolstatus As Boolean
configName = swComp.ReferencedConfiguration
fileName = swModel.GetTitle()
‘ 拡張子を除いた純粋なファイル名を抽出(部品番号のデフォルト候補)
Dim baseFileName As String
baseFileName = Left(fileName, InStrRev(fileName, “.”) – 1)
‘ コンフィギュレーション固有のカスタムプロパティマネージャーを取得
Set swCustPropMgr = swModel.Extension.CustomPropertyManager(configName)
If Not swCustPropMgr Is Nothing Then
‘ 1. 「PartNumber」プロパティの存在確認と自動設定
swCustPropMgr.Get4 “PartNumber”, False, valOut, resolvedValOut
If resolvedValOut = “” Then
‘ 未設定の場合はファイル名を割り当て
swCustPropMgr.Add3 “PartNumber”, swCustomInfoText, baseFileName, swCustomPropertyReplaceValue
End If
‘ 2. 「BOM_REV」プロパティの初期化(未設定なら “00” を付与)
swCustPropMgr.Get4 “BOM_REV”, False, valOut, resolvedValOut
If resolvedValOut = “” Then
swCustPropMgr.Add3 “BOM_REV”, swCustomInfoText, “00”, swCustomPropertyReplaceValue
End If
End If
Set swCustPropMgr = Nothing
End Sub
—
3. シニアエンジニアが押さえるべきアーキテクチャの急所
上記のコードを実務の巨大な製品データ管理(PDM)やレガシーなファイルサーバー環境で運用する際、以下のポイントが成否を分ける。
① `UserControl = False` と画面描画のブラックボックス化
何千点ものアセンブリをプログラムが走査する場合、SolidWorksの画面が再描画(Graphics Update)されるたびに数秒のオーバーヘッドが発生する。`swApp.Visible = False` を組み合わせることで、バックグラウンドワーカーの如く高速にメタデータを書き換えることが可能だ。ただし、エラー時にUIが消えたままロストするリスクがあるため、必ず `ErrorHandler` 内で `Visible = True` に復元するコードを担保すること。
② コンフィギュレーション名(ReferencedConfiguration)の厳密な指定
SolidWorksの厄介な仕様として、アセンブリに配置されたコンポーネントが「どのコンフィギュレーションを参照しているか」は親アセンブリ側のコンテキストに依存する。ドキュメント全体(Document Level)のプロパティをいじっても、図面上の部品表(BOM)がコンフィギュレーション固有のプロパティを参照している場合、値が空欄になる事故が多発する。必ず `swComp.ReferencedConfiguration` から取得したコンフィギュレーション名に対して `CustomPropertyManager` を引き当てなければならない。
—
4. 図面自動生成(Drawing Automation)への接続
このVBAによって、アセンブリ内のすべての構成部品に `PartNumber` や `BOM_REV` が完璧に調停された。
この状態を作り上げておけば、次に実行する「アセンブリ図面の自動生成とバルーン(部品番号)の一括自動挿入(`AutoBalloon5`)」のAPI処理において、バルーンの引き出し線やBOMの品名が一切の破綻なく、一撃で整うことになる。
小手先のマクロ記録に頼るな。SolidWorks APIのオブジェクトモデルの深層を理解し、メモリとパフォーマンスを極限までチューニングした者だけが、真の設計自動化の果実を手にすることができる。
