SolidWorks APIの深淵:CustomPropertyManagerを支配し、メタデータの「完全性」を担保する
SolidWorksの自動化において、最も軽視されがちだが、PDM連携や下流工程のCAD/CAMにおいて致命的な差を生むのが「カスタムプロパティの書き込み」だ。
単に `Add3` メソッドを叩けば良いと思っているなら、それはアマチュアの思考である。大規模アセンブリやライフサイクル管理を想定したシステムにおいて、メタデータの不整合は「技術的負債」の直接的な要因となる。
本稿では、レガシーを継承しつつ、極限まで堅牢性を高めたカスタムプロパティ操作のアーキテクチャを解剖する。
—
1. なぜ `CustomPropertyManager` の実装に「儀式」が必要なのか
`IModelDocExtension::CustomPropertyManager` は、SolidWorksのドキュメントと外部システムを繋ぐ唯一無二のインターフェースだ。しかし、このAPIは「既存値の有無」や「設定(Configuration)のスコープ」によって挙動が巧妙に変化する。
無策に `Add3` を連発すれば、値の二重定義や、意図しない設定への書き込みを招く。我々が目指すべきは、「冪等性(Idempotency)」の確保である。何度実行しても、必ず同じ結果になるコードを書け。
—
2. 堅牢なメタデータ注入の実装パターン
以下のコードは、単なるプロパティ追加ではない。既存値の検証、書き込み失敗時のハンドリング、そしてメモリへの負荷を最小限に抑えたアーキテクチャの雛形だ。
Option Explicit
‘ 伝説的なエンジニアは、定数をハードコードせず、型安全な管理を好む
Private Const PROP_APPROVED_BY As String = “承認者”
Private Const PROP_PART_NUMBER As String = “図番”
Private Const PROP_MATERIAL As String = “材料名”
Public Sub UpdateCustomProperties(ByVal swModel As SldWorks.ModelDoc2, _
ByVal approvedBy As String, _
ByVal partNum As String, _
ByVal materialName As String)
Dim swModelDocExt As SldWorks.ModelDocExtension
Dim swCustPropMgr As SldWorks.CustomPropertyManager
Dim retVal As Long
If swModel Is Nothing Then Exit Sub
‘ 拡張インターフェースの取得(メモリ効率を考慮し、必要なスコープでのみ保持)
Set swModelDocExt = swModel.Extension
Set swCustPropMgr = swModelDocExt.CustomPropertyManager(“”) ‘ “”はユーザー定義(ファイル全体)
‘ トランザクション的な操作をカプセル化する
Call WriteProperty(swCustPropMgr, PROP_APPROVED_BY, approvedBy)
Call WriteProperty(swCustPropMgr, PROP_PART_NUMBER, partNum)
Call WriteProperty(swCustPropMgr, PROP_MATERIAL, materialName)
‘ 強制的なリビルドが必要な場合はここでトリガー
‘ swModel.ForceRebuild3 False
‘ 明示的なオブジェクト解放(VBAのガベージコレクションを信用するな)
Set swCustPropMgr = Nothing
Set swModelDocExt = Nothing
End Sub
Private Sub WriteProperty(ByRef propMgr As SldWorks.CustomPropertyManager, _
ByVal propName As String, _
ByVal propValue As String)
Dim retVal As Long
‘ Add3: 第3引数は「設定固有」フラグ。第4引数は「値」。
‘ Add3は既存キーがある場合、戻り値として ‘swCustomInfoResult_AlreadyExists’ を返す
retVal = propMgr.Add3(propName, swCustomInfoType_Text, propValue, swCustomPropertyAddOption_ReplaceValue)
‘ ログ管理:ここでエラーハンドリングを行い、監査証跡を残すのがプロの作法
If retVal = swCustomInfoResult_Error Then
Debug.Print “Error: Failed to write ” & propName
End If
End Sub
—
3. シニアエンジニアが意識すべき「メモリとパフォーマンスの最適化」
1. `IModelDocExtension` の再利用を避けよ
ループ内で `Extension` を何度も呼び出すのは愚策だ。必ずループの外で保持し、オブジェクトの参照をキャッシュせよ。VBAのCOM参照は、頻繁な生成と破棄が積み重なると、メモリリークの温床となる。
2. `swCustomPropertyAddOption_ReplaceValue` の活用
`Add3` のオプションには必ず `ReplaceValue` を指定せよ。これにより、「既存があれば更新、なければ追加」というロジックを分岐なしで完結できる。条件分岐を減らすことは、バグの発生源を減らすことに直結する。
3. Windows APIによる外部同期
もしPDMがファイルをロックしている場合、SolidWorks APIがエラーを返すことがある。その際は、ファイル属性(ReadOnly)を `GetFileAttributes` で事前にチェックし、プロセスの競合を未然に防ぐ防護壁を設けるべきだ。
—
4. 最後に:コードは「生き物」である
あなたが書いたこのマクロは、十年後に誰かがメンテナンスすることになる。
「なぜここで `””` を指定したのか?」「なぜ `Set` を明示的に `Nothing` にしているのか?」
これらの問いに対する答えが、ソースコード内のコメントではなく、コードの構造自体から読み取れるようにせよ。
SolidWorks APIは奥が深い。しかし、オブジェクトのライフサイクルと、その操作がドキュメントに与える影響を理解していれば、恐れることは何もない。
さあ、退屈な手作業を自動化し、エンジニアとしての本質的な創造に時間を割け。それが、我々アーキテクトの矜持だ。
