【実務・中級編】【カスタムプロパティ操作】CustomPropertyManager.GetNamesとGet2を用いた既存メタデータの全走査・一括置換ユーティリティ – SolidWorks VBA解析バイブル

スポンサーリンク

【SolidWorks VBAを掌握する極限の知見】
カスタムプロパティ全走査・一括置換ユーティリティ:負の遺産をクレンジングする堅牢なメタデータ管理術

開発プロジェクトの現場において、最も恐ろしいのは「見えない負債」だ。
社内ニッチな図面管理システムやPLM(製品ライフサイクル管理)への移行期、エンジニアの足を最も引っ張るのが「バラバラに入力されたカスタムプロパティ」である。

「材質」「メダル」「Material」「材質(日本語)」──。
人間が手動で入力してきた歴史的経緯により、同じ意味を持つプロパティが、パーツごとに異なるキー名で乱立している。この混沌としたメタデータを前に、手作業での修正を試みるのは愚行というものだ。

今回は、SolidWorks VBAの底力を引き出し、既存パーツのカスタムプロパティを完全網羅して一括置換・標準化するためのプロダクションコード(実戦投入可能な堅牢なコード)を伝授する。

1. なぜ「力技のプロパティ操作」は破綻するのか?

多くの初学者が書くコードは、以下のようなアプローチをとる。

‘ 【アンチパターン】ハードコーディングされたプロパティ操作
Dim swCustPropExt As SldWorks.CustomPropertyManager
Set swCustPropExt = swModel.Extension.CustomPropertyManager(“”)

‘ 無いかもしれないキーを直接叩いてエラーを起こす
swCustPropExt.Set2 “材質”, “SUS304”

このアプローチが実務で必ず破綻する理由は以下の通りだ:
1. コンフィグレーション依存の罠: プロパティには「アクティブドキュメント全体(共有)」と「コンフィグレーション固有」の2つのスコープが存在する。これを意識せずにアクセスすると、意図しない階層を書き換えてしまう。
2. 存在しないキーへの依存: `Set2`メソッドは、キーが存在しない場合は新規追加するが、既存の「表記揺れキー(例: “材質” と “Material” が両方存在)」を放置したまま上書きすると、ゴミデータが蓄積し続ける。
3. データ型の不整合: `Get2`で取得できる値は常にVariantだが、評価値(ResolvedValout)と評価前(ValOut)の区別をつけないと、数式やコンフィグレーション変数が展開された値を取得できない。

これらを完全に克服するためには、「CustomPropertyManager.GetNames」で既存キーを全列挙し、「Get2」で安全に値を取得・評価した上で、マッピングテーブルに基づいてクレンジングするという設計が必要不可欠だ。

2. 堅牢なメタデータ・クレンジングエンジンの設計方針

今回のユーティリティでは、以下の要件を満たすアーキテクチャを構築する。

  • 全キーの動的取得: `GetNames`配列を走査し、ドキュメント内にどのようなゴミキーが存在しようとも取りこぼさない。
  • デュアルスコープ対応: 標準設定(””)だけでなく、必要に応じてコンフィグレーション固有のプロパティ層にもアプローチできる拡張性を担保する。
  • 安全な置換ロジック: 辞書的(Dictionary)なマッピング構造をVBA上で展開し、表記揺れを統一キーへ綺麗にコンバートする。

3. 【コピペ即実践】カスタムプロパティ一括置換・標準化マクロ

以下のコードは、アクティブなパーツドキュメント(またはアセンブリ)のカスタムプロパティを走査し、あらかじめ定義されたルールに従ってクレンジングを実行するプロフェッショナル向けスクリプトである。

Option Explicit

‘ =========================================================================
‘ ódulo名: ModPropertyCleanser
‘ 概要 : カスタムプロパティ全走査・一括置換ユーティリティ
‘ 備考 : SolidWorks 2021以降推奨
‘ =========================================================================

Public Sub ExecutePropertyCleansing()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swCustPropMgr As SldWorks.CustomPropertyManager

Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc

‘ 1. ドキュメントが開かれているか、かつパーツ/アセンブリか検証
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。”, vbCritical, “エラー”
Exit Sub
End If

Dim docType As Long
docType = swModel.GetType
If docType <> swDocPART And docType <> swDocASSEMBLY Then
MsgBox “このマクロはパーツまたはアセンブリでのみ実行可能です。”, vbExclamation, “対象外”
Exit Sub
End If

‘ 2. カスタムプロパティマネージャーの取得(”” はファイル連動プロパティを指す)
‘ ※特定コンフィグレーション対象にする場合はコンフィグ名を指定
Set swCustPropMgr = swModel.Extension.CustomPropertyManager(“”)

If swCustPropMgr Is Nothing Then
MsgBox “カスタムプロパティマネージャーを取得できませんでした。”, vbCritical, “致命的エラー”
Exit Sub
End If

‘ 3. 既存のプロパティ名一覧(配列)を取得
Dim vPropNames As Variant
vPropNames = swCustPropMgr.GetNames

If IsEmpty(vPropNames) Then
MsgBox “カスタムプロパティは一つも登録されていません。”, vbInformation, “情報”
Exit Sub
End If

‘ 4. 置換・標準化ルールのマッピング定義(Scripting.Dictionaryを使用)
Dim dictMapping As Object
Set dictMapping = CreateStandardizationRules()

Dim i As Long
Dim propName As String
Dim valOut As String
Dim resolvedValOut As String
Dim wasResolved As Boolean
valOut = “”
resolvedValOut = “”
wasResolved = False
Dim resultCode As Long

‘ 5. 全プロパティの走査とクレンジング実行
Dim reportLog As String
reportLog = “— プロパティクレンジング レポート —” & vbCrLf

For i = LBound(vPropNames) To UBound(vPropNames)
propName = CStr(vPropNames(i))

‘ 値と評価済み値の取得 (Get2の引数仕様に注意)
‘ 引数: FieldName, ValOut, ResolvedValOut, WasResolved
resultCode = swCustPropMgr.Get2(propName, valOut, resolvedValOut)

reportLog = reportLog & “発見: [” & propName & “] = ” & resolvedValOut & vbCrLf

‘ 表記揺れキーの統合処理
If dictMapping.Exists(propName) Then
Dim targetStandardKey As String
targetStandardKey = dictMapping(propName)

‘ 標準キーへ値を移行(もしキー名が異なる場合、旧キーの削除と新キーの作成を行う)
If propName <> targetStandardKey Then
‘ 新標準キーに値をセット
resultCode = swCustPropMgr.Set2(targetStandardKey, resolvedValOut)

‘ 古い揺れキーを削除
resultCode = swCustPropMgr.Delete2(propName)

reportLog = reportLog & ” └-> 移行完了: [” & propName & “] ⇒ [” & targetStandardKey & “]” & vbCrLf
End If
End If
Next i

‘ 6. 変更をモデルに反映・再構築
swModel.ForceRebuild3 False

MsgBox reportLog & vbCrLf & “クレンジングが正常に完了しました。”, vbInformation, “完了”
End Sub

‘ =========================================================================
‘ 内部関数: 標準化ルール(表記揺れ辞書)の定義
‘ =========================================================================
Private Function CreateStandardizationRules() As Object
Dim dict As Object
Set dict = CreateObject(“Scripting.Dictionary”)

‘ 【左側:検出する揺れ・レガシーキー】 = 【右側:社内標準キー】

‘ 材質系
dict.Add “材質”, “Material”
dict.Add “材質名”, “Material”
dict.Add “メダル”, “Material”
dict.Add “MAT”, “Material”

‘ 質量・重量系
dict.Add “重量”, “Mass”
dict.Add “質量”, “Mass”
dict.Add “WEIGHT”, “Mass”

‘ 承認者系
dict.Add “承認”, “ApprovedBy”
dict.Add “承認者”, “ApprovedBy”
dict.Add “CHECKED_BY”, “ApprovedBy”

Set CreateStandardizationRules = dict
End Function

4. チーフアーキテクトが教える実装上の急所

このコードを実務のバッチ処理や大規模アセンブリ(数千パーツ)に適用する際、以下のポイントを必ず押さえておかなければならない。

① 黙殺してはならない `Get2` の戻り値

SolidWorks APIのメソッドの多くは、成功時に `swCustomInfoGetResult_Successful`(通常数値として評価される)を返す。今回はシンプル化のために省略しているが、厳密なエンタープライズ環境では、`resultCode` を監視し、読み取り専用ファイルやロックされているプロパティに対する例外処理(Error Handling)を記述すべきだ。

② 大規模アセンブリ一括処理時のパフォーマンス

もしこのロジックを「アセンブリ内の全構成部品(ボルトやナット含む)に再帰的に適用したい」場合、親アセンブリ側から子パーツのプロパティを書き換えるのではなく、各パーツをサイレントオープン(`OpenDoc6` のオプション活用)して個別に処理し、保存して閉じるというバッチパターンをとる方がメモリリークを防げる。アセンブリコンテキスト経由のプロパティ操作は、予期せぬ外部参照の汚染を引き起こすリスクが高い。

③ コンフィグレーション固有プロパティへの拡張

今回のコードはファイルスコープ(全コンフィグ共通)を対象としているが、もし「コンフィグレーション毎に材質が違う」ような複雑な製品群を扱う場合は、`swModel.GetConfigurationNames` で全コンフィグ名を取得し、ループを回す必要がある。その際は `CustomPropertyManager` を取得する際の引数にコンフィグ名を渡すことを忘れてはならない。

5. おわりに:自動化の真髄は「過去の清算」にある

新しいPDMやPLMを導入する際、コンサルティング会社に高額な費用を払ってデータクレンジングを依頼する企業があとを絶たない。しかし、ドメイン知識(自社がどのような表記揺れを生み出してきたか)を最も深く理解しているのは、他でもない社内のエンジニア自身である。

今回提供した `GetNames` と `Get2` を組み合わせたメタデータ走査の知見をベースに辞書を拡張すれば、社内のどんなに汚染されたCADデータであっても、数分で美しく標準化された「次世代システム対応データ」へと生まれ変わらせることができる。

コードを書き、仕組みを支配せよ。
あなたの手によるその自動化こそが、組織を次のステージへと押し上げる最大の原動力となる。

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