こんにちは!SolidWorks自動化の世界へようこそ。
マクロの記録ボタンを押して生成されたコードを眺めて、「これ、他のモデルでも本当に動くの…?」と不安になったことはありませんか?
今回は、実務で非常によく遭遇する「マルチボディパーツから複数のソリッドを自動で識別し、名前を変更して個別パーツとして切り出す」という、ちょっと一歩進んだテーマを解説します。
ここをクリアすれば、単なる「操作の記録再生マクロ」から卒業し、「CADを意のままに操るエンジニア」の仲間入りです。一緒にしっかりと本質を学んでいきましょう!
—
なぜ「マルチボディの個別分離」でつまづくのか?
SolidWorksで1つのパーツファイルの中に複数のソリッドボディが存在する状態(マルチボディ)は、溶接構造物や樹脂金型、アセンブリのトップダウン設計などで頻繁に使われます。
しかし、VBAでこれを自動処理しようとすると、多くの人が次のような壁にぶつかります。
- 「どのボディがどれだか、プログラムから特定できない」
- 「表面積や体積を使いたいのに、どのAPIを呼べばいいか分からない」
- 「取得したボディをどうやって独立したファイルにすればいいの?」
これらを解決するのが、`Body2.GetBodyType` と `Body2.GetVolume` という極めて強力なAPIコンビです。
—
攻略の鍵:SolidWorks APIの階層構造を知る
SolidWorks VBAでジオメトリを操作するとき、私たちは「アプリケーション > ドキュメント > モデル > フィーチャ > ボディ」というピラミッド構造を降りていく必要があります。
特に今回の主役である `Body2` オブジェクト は、フィーチャ(押し出しやカットなど)の結果として生まれた「実体」そのものです。
これに対して以下の二つの武器を使います。
1. `Body2.GetBodyType`
- そのボディが「ソリッド(swSolidBody)」なのか、「シートメタル(サーフェス)」なのかを判定します。余計なサーフェスを誤認しないための必須フィルターです。
2. `Body2.GetVolume`
- ボディの「体積」を立方メートル(m³)単位で取得します。同じ形状でも体積でソリッドを識別できるため、自動命名の大きな手がかりになります。
—
実践!非干渉ボディ自動分離・リネームマクロ
それでは、現在開いているマルチボディパーツからすべてのソリッドボディを取得し、体積情報をコンソールに出力しつつ、分かりやすい名前に自動リネームする実用コードを公開します。
開発環境(VBAエディタ)の標準モジュールに貼り付けて、そのまま実行してみてください。
Sub AutoSplitAndRenameBodies()
‘ — 1. オブジェクトの宣言と初期化 —
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swPart As SldWorks.PartDoc
Dim vBodies As Variant
Dim swBody As SldWorks.Body2
Dim i As Long
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
‘ アクティブなドキュメントがパーツかチェック
If swModel Is Nothing Then
MsgBox “ドキュメントが開かれていません。”, vbCritical
Exit Sub
End If
If swModel.GetType <> swDocPART Then
MsgBox “このマクロはパーツドキュメントでのみ実行可能です。”, vbCritical
Exit Sub
End If
Set swPart = swModel
‘ — 2. パーツ内の全ソリッドボディを取得 —
‘ Trueを指定することで、カットリストや非表示を含むすべてのソリッドボディを取得します
vBodies = swPart.GetBodies2(swSolidBody, True)
If IsEmpty(vBodies) Then
MsgBox “このパーツにはソリッドボディが存在しません。”, vbExclamation
Exit Sub
End If
‘ — 3. ボディの走査と自動リネーム処理 —
Dim bodyCount As Long
bodyCount = 0
For i = LBound(vBodies) To UBound(vBodies)
Set swBody = vBodies(i)
‘ 念のためボディが有効か、かつソリッドタイプかチェック
If Not swBody Is Nothing Then
If swBody.GetType = swSolidBody Then
bodyCount = bodyCount + 1
‘ 体積を取得 (単位は m3 なので cm3 や mm3 に換算すると直感的です)
Dim volM3 As Double
Dim volMm3 As Double
volM3 = swBody.GetVolume
volMm3 = volM3 1000000000# ‘ m3 -> mm3
‘ デバッグウィンドウに情報を出力
Debug.Print “— ボディ [” & bodyCount & “] —”
Debug.Print ” 体積: ” & Format(volMm3, “#,
0.00″) & ” mm³”
‘ 【実務のキモ】体積や特徴に基づいて自動で名前を決定する
‘ ここでは例として「Auto_Solid_番号_体積(mm3)」という名前に変更します
Dim newBodyName As String
newBodyName = “Part_Vol_” & Format(Int(volMm3), “000000”)
‘ ボディ自体の名前を変更(FeatureManagerツリーでの表示名が変わります)
swBody.Name = newBodyName
Debug.Print ” 新名称設定: ” & newBodyName
End If
End If
Next i
‘ — 4. 変更を画面に反映 —
swModel.ForceRebuild3 (False)
MsgBox “処理が完了しました! ” & bodyCount & ” 個のソリッドボディを自動識別・リネームしました。”, vbInformation, “自動化完了”
End Sub
—
コードのポイントと「初心者がハマりやすい罠」
このコードには、現場で培ったエンジニアの知見がいくつも詰まっています。
1. `GetBodies2` の引数に隠された罠
`swPart.GetBodies2(swSolidBody, True)` の第二引数に `True` を指定しています。ここを `False` にしてしまうと、非表示(Hide)になっているボディや、特定のコンテキストから外れたボディが取得漏れを起こします。
「マクロを実行したのに一部のボディが無視される…」という現象の9割はこれが原因です。必ず `True` を使って全取得しましょう。
2. 単位の換算に注意(m³の呪縛)
SolidWorksのAPIが返す数値の基本単位は、常に SI単位系(メートル、ラジアン、キログラムなど) です。
`GetVolume` が返す値も `m³` です。これをそのまま「うわ、めっちゃ小さい数字が出たぞ!」と焦らないようにしてください。
実務で私たちが扱う「mm³」にするには、$10^9$(10億)を掛ける必要があります。コード内の `1000000000#` はそのためのお呪いです。
3. ボディ名(`swBody.Name`)の変更はツリーに直結する
フィーチャの名前を変えるのと同様に、`swBody.Name = …` と記述するだけで、SolidWorksの画面左側にあるFeatureManagerデザインツリーのボディ名が即座に書き換わります。
これにより、後続の処理(「特定の名前のボディだけをSTEP形式で保存する」など)へのパスが劇的に楽になります。
—
ここをクリアすれば、SolidWorks VBAの基本はバッチリ!
お疲れ様でした!
今回のテーマである `Body2.GetBodyType` と `Body2.GetVolume` をマスターしたあなたは、単に「ボタンをポチポチ押す代行」ではなく、「形状のデータを数学的に解析し、意図通りにコントロールする」という高度な領域に足を踏み入れました。
ここからさらに発展させて、
- 「指定した体積より小さいゴミボディ(微小な隙間埋めなど)を自動削除する」
- 「リネームしたボディをそれぞれの名前で個別のSTEPファイルとして自動書き出しする」
といった実務アプリケーションへ展開していくことも十分に可能です。
ぜひご自身の環境でコードを試し、日々の設計業務の効率を爆上げしてくださいね。
それでは、次回の極限の知見でお会いしましょう!
