【入門編】【フィレット・面取り】GetEdgesメソッドによるボディ全周エッジの網羅的取得と動的フィレット適用エラーの回避法 – SolidWorks VBA解析バイブル

スポンサーリンク

こんにちは!SolidWorks自動化の現場で、日々泥臭くも美しいマクロを書き続けている先輩エンジニアです。

マクロの記録ボタンを押して、ポチポチとフィレットをつけてみたはいいものの……いざ他のモデルで動かしたら「エッジが見つかりません」と容赦なくエラーが出て悶絶した、そんな経験はありませんか?

「マクロの記録」が吐き出すコードは、いわば「その瞬間の固定された世界」を切り取っただけのもの。モデルの形状が変われば、エッジの内部ID(名前)もガラリと変わるため、そのままでは使い物になりません。

今回は、SolidWorks VBAの真骨頂である「動的なエッジ取得(GetEdges)」をマスターし、どんな形状のモデルが来ても華麗に全周フィレットをキメる、実務直結のテクニックを伝授します。ここをクリアすれば、あなたのマクロ開発スキルは一気にプロの領域へジャンプアップしますよ!

1. なぜ「マクロの記録」のフィレットは失敗するのか?

まず、敵を知ることから始めましょう。
「マクロの記録」でフィレットフィーチャを作成すると、大体以下のようなコードが出力されます。

‘ 【マクロの記録が生成する危なっかしいコードの例】
boolstatus = swModel.Extension.SelectByID2(“Edge1<1>“, “EDGE”, 0, 0, 0, False, 0, Nothing, 0)
boolstatus = swModel.Extension.SelectByID2(“Edge2<1>“, “EDGE”, 0, 0, 0, True, 0, Nothing, 0)
‘ フィレット実行…

ここで指定されている `”Edge1<1>“` という文字列、これがエッジの固有名(名前)です。
SolidWorksは、モデルの形状が少しでも変わると、エッジの内部番号を振り直します。そのため、前回動いたコードが、翌日には「そんなエッジはない」と冷たくエラーを吐く原因になるのです。

本物のエンジニアのアプローチ

私たちが目指すべきは、名前に依存するのではなく、「今そこにあるソリッドボディから、生きているエッジをプログラムの力で直接釣り上げる(取得する)」という動的なアプローチです。

2. ボディからエッジを網羅的に取得する:GetEdgesの魔法

SolidWorksのAPIには、ボディ(`Body2`オブジェクト)が持つすべての面やエッジを配列として取得するメソッドが用意されています。それが `GetEdges` です。

これを使えば、モデルの形状が変わろうとも、その瞬間に存在するエッジを漏れなく網羅的にキャッチできます。

全周フィレット自動化の全体像

今回のマクロの流儀はこうです。
1. アクティブなパーツドキュメントから、対象となるソリッドボディを取得する。
2. そのボディから `GetEdges` メソッドですべてのエッジを配列として取得する。
3. 取得したエッジの配列をそのままフィレットの引数にブチ込む!

言葉で言うのは簡単ですが、実務では「鋭利な角(許容されるエッジ)」と「削ってはいけないエッジ」の選別や、「エラーの回避」という現実の壁が立ちはだかります。次項のコードで、そのすべてを解決していきましょう。

3. 【実践コード】動的エッジ取得による一括フィレットマクロ

それでは、実務でそのまま使える堅牢なコードを公開します。VBAの標準モジュールに貼り付けて実行してみてください。

‘ ==============================================================================
‘ 担当:先輩エンジニア
‘ 概要:ソリッドボディからGetEdgesで全エッジを動的に取得し、一括フィレットを適用する
‘ ==============================================================================
Sub ApplyDynamicFillet()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swPart As SldWorks.PartDoc
Dim swBody As SldWorks.Body2
Dim swBodyArr As Variant
Dim swEdgeArr As Variant
Dim swFeatMgr As SldWorks.FeatureManager
Dim i As Long

‘ 1. アプリケーションとドキュメントの取得
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. パーツ内の最初のソリッドボディを取得
‘ ※マルチボディの場合はループ処理が必要ですが、今回はメインボディを対象とします
swBodyArr = swPart.GetBodies2(swSolidBody, True)
If IsEmpty(swBodyArr) Then
MsgBox “ソリッドボディが見つかりません。”, vbCritical
Exit Sub
End If
Set swBody = swBodyArr(0)

‘ 3. 【核心】GetEdgesメソッドでボディから全てのエッジ配列を取得!
swEdgeArr = swBody.GetEdges

If IsEmpty(swEdgeArr) Then
MsgBox “エッジを取得できませんでした。”, vbCritical
Exit Sub
End If

‘ 4. エッジを一括選択状態にする(フィレットフィーチャの入力用)
‘ 事前にクリア
swModel.ClearSelection2 True

Dim swEntity As SldWorks.Entity
Dim boolstatus As Boolean

‘ 取得したエッジを一つずつ「マーク=1(フィレット用)」で選択していく
For i = LBound(swEdgeArr) To UBound(swEdgeArr)
Set swEntity = swEdgeArr(i)
‘ Mark = 1 はフィレットフィーチャが要求する選択マークです
boolstatus = swEntity.Select4(True, 1)
Next i

‘ 5. フィレットフィーチャの実行(半径 = 2.0mm と仮定)
Set swFeatMgr = swModel.FeatureManager

‘ 引数:半径, 伝播(True), 保持形状(0), …
Dim swFeat As SldWorks.Feature
Set swFeat = swFeatMgr.FeatureFillet3( _
2.0 / 1000#, _ ‘ フィレット半径(メートル単位!ここ重要)
swFilletType_ConstantRadius, _
swFilletPropagate_Circular, _
swFilletKeepFeatures_None, _
False, 0, 0)

‘ 6. 後処理
If Not swFeat Is Nothing Then
MsgBox “全周フィレットの適用に成功しました!”, vbInformation, “完了”
Else
MsgBox “フィレットの生成に失敗しました。ジオメトリが干渉している可能性があります。”, vbExclamation, “エラー”
swModel.ClearSelection2 True
End If

End Sub

4. ここで差がつく!プロが教える「3つの罠」と回避テクニック

上記のコードを動かすにあたり、SolidWorks API特有の「ハマりどころ」をいくつか解説しておきます。ここを知っているかいないかで、エンジニアとしての格が分かれます。

① 単位系は常に「メートル(m)」であれ!

APIの引数に渡す寸法値は、ドキュメントの単位(mmやinch)に関わらず、すべて「メートル(m)」でなければなりません。
コード内で `2.0 / 1000#` としているのはそのためです。ここを `2.0` のまま渡すと、半径2メートルの巨大なモンスターフィレットが生成され、確実にエラーかフリーズを引き起こします。絶対に忘れないでください。

② すべてのエッジを選ぶとエラーになるケース(動的エラー回避)

`GetEdges` は、そのボディを構成するすべてのエッジを容赦なく持ってきます。
もしモデル内に「鋭利すぎてフィレットが絶対に破綻する微小なエッジ」や「自己交差を起こすエッジ」が含まれている場合、`FeatureFillet3` はエラーを返し、フィーチャ全体が失敗します。

【実践的な回避策】
もし特定のエッジでエラーが出る場合は、`GetEdges` で取得した配列をループする際に、エッジの長さ(`ICurve::GetLength` など)や、隣接する面の角度を判定し、「小さすぎるエッジ」や「丸めると破綻しそうなエッジ」を配列から除外するフィルタリング処理を入れます。これが現場で生き抜くためのロバスト(堅牢)なコード設計です。

③ 選択時の「Mark(マーク)」の重要性

コード内で `swEntity.Select4(True, 1)` という記述をしています。
この第二引数の `1` は、SolidWorksに対して「これはフィレットの対象エッジとして選択していますよ」と教えるための選択マークです。APIでフィーチャを作る際、このマークが正しくないと「何を選んでいいか分かりません」とAPIに拒絶されます。

5. おわりに

お疲れ様でした!今回は `GetEdges` を使った動的なエッジ取得と、全周フィレットの自動化について解説しました。

「マクロの記録」の呪縛から逃れ、APIのオブジェクト指向的なアプローチ(ボディからエッジを剥き出しにして操作する)を理解できたなら、あなたはもう初心者ではありません。

現場の設計者たちが何時間もかけて手動でポチポチやっているフィレット付けを、一瞬で、しかもどんな形状変更にも耐えうるロジックで自動化してしまう――。これこそが、私たちVBAエンジニアの醍醐味です。

ぜひ、あなたの業務の自動化にもこの知見を取り入れてみてください。「ここをこう改変したいんだけど、どうすればいい?」といった疑問があれば、いつでもまた私を頼ってくださいね。応援しています!

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