【テクニカル・上級編】【ライブラリ機能】ModelDocExtension.InsertLibraryFeatureExを用いた社内標準「ポケット・ボスカタログ」の座標指定インサート – SolidWorks VBA解析バイブル

スポンサーリンク

SolidWorks VBAを掌握する極限の知見:ModelDocExtension.InsertLibraryFeatureExによる社内標準ポケット・ボスカタログの座標指定インサート

製造業におけるCAD自動化の究極の目的は、属人性の排除と設計プロセスのスループット限界突破にある。
「社内標準のポケットやボス形状を、設計者が毎回手動でライブラリからドラッグ&ドロップし、寸法や位置を拘束する」――このレガシーなオペレーションは、ヒューマンエラーの温床であり、大規模なアセンブリにおける設計変更の足かせとなる。

今回は、SolidWorks APIの真髄である `ModelDocExtension.InsertLibraryFeatureEx` を用い、ハードコーディングを完全に排除した「座標指定型のライブラリ機能自動インサートエンジン」を構築する。
単なるコードの羅列ではない。オブジェクトのライフサイクル、COMプロキシのメモリ管理、そして実務の荒波を生き抜くための堅牢性まで踏み込んだ、チーフアーキテクトとしての知見をここに開示する。

1. アーキテクチャ設計:なぜ `InsertLibraryFeatureEx` なのか

レガシーなVBAコードの多くは、パーツを新規に開いてアセンブリに挿入するか、単にマクロ記録をそのまま貼り付けた脆弱な構造をしている。しかし、社内標準の「ポケット・ボスカタログ(`.sldlfp`)」をプログラムから自在に操る場合、以下の要件を満たす必要命題が生じる。

1. 外部参照の完全制御: ライブラリフィーチャの配置において、親パーツとのリンク切れやパスのハードコーディングを防ぐ。
2. 位置・寸法の動的オーバーライド: 配置する基準面(Plane)と、XY座標(および必要に応じた回転・設定値)をプログラムから外部データ(CSVやDB)と同期させる。
3. トランザクションの保護: 途中でエラーが発生した場合、フィーチャツリーが中途半端な破損状態(汚染状態)に陥るのを防ぐ。

`ModelDocExtension.InsertLibraryFeatureEx` は、これらすべての要件を低レベルで処理するための唯一無二のメソッドである。しかし、このメソッドは引数の型や配列の構造が極めて厳密であり、VBAの緩い型システムで挑むと容易にクラッシュ(Fatal Error)を引き起こす。

2. 実装コード:極限まで最適化されたインサートエンジン

以下のコードは、指定された基準面上に、外部定義されたライブラリパーツ(`.sldlfp`)を、指定座標へ正確にインサートするための実用モジュールである。エラーハンドリングとオブジェクトの明示的解放(メモリ最適化)を徹底している。

Option Explicit

‘ ==============================================================================
‘ 業務自動化エンジニアリング標準モジュール:ライブラリフィーチャ自動配置エンジン
‘ ==============================================================================

Public Sub ExecuteLibraryFeatureInsertion()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swModelExt As SldWorks.ModelDocExtension

‘ 1. アプリケーションコンテキストの取得(早期バインディングによる型安全性の確保)
Set swApp = Application.SldWorks
If swApp Is Nothing Then
MsgBox “SolidWorksが起動していません。”, vbCritical
Exit Sub
End If

Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなパーツドキュメントが存在しません。”, vbCritical
Exit Sub
End If

‘ パーツドキュメントであることの型チェック (swDocPART = 1)
If swModel.GetType <> swDocPART Then
MsgBox “このマクロはパーツファイルでのみ実行可能です。”, vbExclamation
Exit Sub
End If

Set swModelExt = swModel.Extension

‘ 2. 実行パラメータの定義(実務ではCSVやDB、JSONから動的取得することを推奨)
Dim libraryPath As String
libraryPath = “C:\Company_Standards\Library\Pocket_Standard.sldlfp”

Dim targetPlaneName As String
targetPlaneName = “Front Plane” ‘ 配置基準面

‘ 配置座標 (X, Y) [mm] -> API内部単位である「メートル (Meters)」に即座に変換する
Dim targetX As Double: targetX = 50.0
Dim targetY As Double: targetY = 30.0

‘ 3. トランザクション開始(失敗時のロールバックを担保)
swModel.ClearSelection2 True

‘ 基準面の選択
Dim boolstatus As Boolean
boolstatus = swModel.Extension.SelectByID2(targetPlaneName, “PLANE”, 0, 0, 0, False, 0, Nothing, 0)
If Not boolstatus Then
MsgBox “指定された基準面が見つかりません: ” & targetPlaneName, vbCritical
GoTo CleanUp
End If

‘ 4. ライブラリフィーチャのインサート実行
‘ InsertLibraryFeatureExのシグネチャ:
‘ (LibFileName As String, ConfigName As String, x As Double, y As Double, z As Double,
‘ RotAngle As Double, LinkToLibrary As Boolean,
‘ Parameters As Variant, References As Variant)

Dim configName As String
configName = “” ‘ デフォルトコンフィギュレーション

Dim rotAngle As Double
rotAngle = 0.0 ‘ ラジアンではなく度数法で指定するパラメータもあるが、基底APIの仕様に準拠

Dim linkToLibrary As Boolean
linkToLibrary = True ‘ 社内標準なのでライブラリとのリンクを維持(改訂管理のため)

‘ 単位系の変換 (mm -> m)
Dim convX As Double: convX = targetX / 1000#
Dim convY As Double: convY = targetY / 1000#
Dim convZ As Double: convZ = 0#

Dim vParams As Variant
Dim vRefs As Variant
‘ パラメータおよび参照のカスタム配列が必要な場合はここで構築する(今回はデフォルト値を使用するためEmpty)
vParams = Empty
vRefs = Empty

‘ 実行
Dim swFeat As SldWorks.Feature
On Error GoTo ErrorHandler

‘ 処理の重みとAPIの非同期性を考慮し、一時的に画面描画を停止
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayHideAllTypes, True

Set swFeat = swModelExt.InsertLibraryFeatureEx( _
libraryPath, _
configName, _
convX, _
convY, _
convZ, _
rotAngle, _
linkToLibrary, _
vParams, _
vRefs _
)

If swFeat Is Nothing Then
Err.Raise 10001, “InsertLibraryFeatureEx”, “ライブラリフィーチャのインサートに失敗しました。パスまたは参照エンティティを確認してください。”
End If

‘ フィーチャツリーの再構築
swModel.ForceRebuild3 False

MsgBox “社内標準ポケットの配置が正常に完了しました。”, vbInformation
GoTo CleanUp

ErrorHandler:
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical

CleanUp:
‘ 5. メモリ最適化とCOM参照の明示的解放
‘ GCに頼らず、明示的にNothingを代入することでSolidWorksプロセス側との通信ブリッジを即座に破棄する
Set swFeat = Nothing
Set swModelExt = Nothing
Set swModel = Nothing
Set swApp = Nothing

‘ 画面描画の復元
If Not swApp Is Nothing Then
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayHideAllTypes, False
End If
End Sub

3. チーフアーキテクトが教える「現場の罠」とメモリ最適化の極意

オブジェクトライフサイクルとメモリリークの防止

VBAはガベージコレクション(GC)の挙動がブラックボックスである。SolidWorks APIを使用する際、COMオブジェクト(`SldWorks.ModelDoc2` や `SldWorks.Feature` など)の参照を保持したままプロシージャを抜けると、SolidWorksのプロセス空間内にゾンビオブジェクトが残り、メモリリークや最悪の場合のSolidWorks強制終了(クラッシュ)を引き起こす。
上記のコードの通り、`CleanUp` ラベルを必ず用意し、生成したすべてのオブジェクト変数に対して `Set obj = Nothing` を明示的に実行することが、エンタープライズ環境における絶対の鉄則である。

単位系(Units)の罠

SolidWorks APIの内部演算単位は、常に 「メートル(Meters)、キログラム(Kilograms)、秒(Seconds)」 である。
UI上では「mm」で設計・入力させていても、APIに渡す座標値は必ず `1000.0` で割るスケーリング処理を挟まなければならない。これを忘れると、モデルの原点から数キロメートル離れた宇宙空間にポケットが生成され、画面が真っ白になる現象(いわゆる「どこに行った現象」)に直面することになる。

レガシー環境と保守性への配慮

社内標準ライブラリ(`.sldlfp`)のパスが変更された際、コードを書き換えるために全クライアントPCのマクロを配布し直すような愚行は避けるべきだ。
実務システムにおいては、インサートパスをINIファイル、あるいはローカルネットワーク上の共通データベース(SQLiteやJSON)から動的に読み込むラッパー関数を一段上に噛ませる設計が望ましい。

4. 総括

`ModelDocExtension.InsertLibraryFeatureEx` を完全に手なづけることは、社内標準化された設計プロセスの自動化における強力な武器となる。
単に「動くコード」を書くフェーズは過ぎた。メモリの寿命を意識し、トランザクションを制御し、システム間連携を見据えた堅牢なアーキテクチャを構築することこそが、真のエンジニアリングである。

次回のトピックでは、この座標指定インサートをさらに発展させ、外部ERPから出力されたBOM(部品表)と連動した「完全無人・自動パーツジェネレータ」の構築手法を解説する。期待されたい。

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