SolidWorks VBAを掌握する極限の知見
第4回:【穴ウィザード完全制賀】HoleWizardDefデータ構造体を用いた「深さ指定付きねじ穴」と「座ぐり加工」の完全プログラム生成
—
序:穴ウィザード自動化の深淵と、HoleWizardDefの真実
SolidWorksマクロの初学者が最初に直面する壁、そして中級者が最も深い絶望を味わう領域。それが「穴ウィザード(Hole Wizard)」のAPI制御である。
GUIであれば、JIS規格を選び、サイズをドロップダウンから選択し、深さを入力するだけで完結する直感的な操作も、APIの領域に踏み込んだ途端、その裏側にある複雑怪奇なデータ構造が牙を剥く。特に `FeatureManager.HoleWizard5` メソッド群や、それに紐づく `HoleWizardDef` データ構造体は、ドキュメントの記述が極めて稀薄であり、適切な型キャスト、Enumの理解、そしてCOMオブジェクトのライフサイクル管理を誤れば、容赦なくSOLIDWORKSを強制終了へと追い込む。
本稿では、レガシーなVBA環境であってもメモリリークを引き起こさず、JIS規格の「深さ指定付きねじ穴(タップ穴)」および「座ぐり(Counterbore)付き穴」を完全パラメータ駆動で生成する、プロダクション品質のコードベースをここに提示する。
—
1. 致命的な落とし穴:HoleWizardDefのアーキテクチャとメモリ管理
APIを通じて穴ウィザードを生成する場合、大まかに以下のステップを踏む。
1. アクティブなドキュメントから `FeatureManager` を取得する。
2. `FeatureManager.CreateDefinition(swDataDefinition_HoleWizard)` を呼び出し、`HoleWizardDef` インスタンスを取得する。
3. `HoleWizardDef` の各プロパティ(規格、タイプ、サイズ、深さ、端部条件など)に適切な値を代入する。
4. 対象面に対してスケッチ点を配置するか、既存のスケッチ点を選択した状態で `FeatureManager.FeatureCreation3`(または `InsertHoleWizard3`)を実行する。
ここで最も重要なのは、`CreateDefinition` によって生成されたCOMオブジェクトは、VBAのランタイム任せにしておくとメモリリークやCOM参照のゾンビ化を引き起こすという事実だ。処理の完遂後、あるいはエラー発生時には、確実に `Set` 変数を `Nothing` 解放し、メモリ上のポインタをクリーンアップしなければならない。シニアエンジニアであれば、エラーハンドリング(`On Error GoTo`)の網羅は当然の義務である。
—
2. 実装コード:JIS座ぐり穴・深さ指定タップ穴の完全生成ルーチン
以下に、実務の現場でそのまま流用可能な、極めて堅牢なVBAコードを示す。このコードは、M6のJIS規格ボルト用座ぐり穴と、深さ指定されたJISタップ穴を、指定された面上にプログラム的に生成するものである。
Option Explicit
‘ =========================================================================
‘ 模範解答:HoleWizardDefを用いた高精度穴ウィザード生成プロシージャ
‘ アーキテクト特権:エラーハンドリングとCOMオブジェクトの厳格な解放を実装
‘ =========================================================================
Public Sub CreateAdvancedHoleWizardExample()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swFeatMgr As SldWorks.FeatureManager
Dim swHoleDef As SldWorks.HoleWizardDef
Dim swFeat As SldWorks.Feature
‘ 1. アプリケーションおよびドキュメントの取得
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなパーツドキュメントが存在しません。”, vbCritical, “API Error”
Exit Sub
End If
If swModel.GetType <> swDocPART Then
MsgBox “このマクロはパーツドキュメントでのみ実行可能です。”, vbCritical, “API Error”
Exit Sub
End If
‘ エラーハンドリングの有効化(メモリリーク防止のため必ずクリーンアップを通す)
On Error GoTo ErrorHandler
Set swFeatMgr = swModel.FeatureManager
If swFeatMgr Is Nothing Then Err.Raise 1000, , “FeatureManagerの取得に失敗しました。”
‘ 2. HoleWizardDefオブジェクトの生成 (swDataDefinition_HoleWizard = 3)
Set swHoleDef = swFeatMgr.CreateDefinition(swDataDefinition_HoleWizard)
If swHoleDef Is Nothing Then Err.Raise 1001, , “HoleWizardDefのインスタンス生成に失敗しました。”
‘ 3. 穴ウィザード基本パラメータの設定
‘ 【重要】JIS規格を指定する場合、文字列のスペルや大文字小文字はSOLIDWORKSの内部データベースと完全に一致させる必要があります。
With swHoleDef
.HoleType = swUD_HoleType_Counterbore ‘ 座ぐり穴 (Counterbore)
‘ ※タップ穴の場合は swUD_HoleType_TappedHole を指定し、下穴・ねじ深さを設定します。
.Standard = 5 ‘ 5 = JIS (規格インデックスはバージョンにより異なるため注意)
.FastenerType = “Hexagon Head Bolt” ‘ 締結部品タイプ
.Size = “M6” ‘ 呼び径 M6
‘ 貫通ではなく「盲穴(Blind)」としての深さ設定
.EndCondition = swEndCondBlind ‘ 端部条件:ブラインド(深さ指定)
.Depth = 0.02 ‘ 全体深さ: 20mm (単位:メートル)
‘ 座ぐり特有のパラメータ設定 (Counterbore Dimensions)
‘ 標準値からオーバーライドする場合に設定
.CounterBoreDiameter = 0.011 ‘ 座ぐり直径: 11mm
.CounterBoreDepth = 0.0064 ‘ 座ぐり深さ: 6.4mm
‘ 角度指定 (必要に応じて)
.HeadClearance = 0 ‘ ヘッドクリアランス
End With
‘ 4. ターゲットとなる面(平面)が事前に選択されていることが前提
‘ ※実運用では swModel.Extension.SelectByID2 等で面をあらかじめ選択状態にしておくこと
‘ 5. フィーチャの生成実行
Set swFeat = swFeatMgr.FeatureCreation3(swHoleDef)
If swFeat Is Nothing Then
Err.Raise 1002, , “穴ウィザードフィーチャの生成に失敗しました。パラメータまたは選択面を確認してください。”
End If
‘ 正常終了時の処理
swModel.ForceRebuild3 True
MsgBox “JIS座ぐり穴の生成に成功しました。”, vbInformation, “Success”
CleanUp:
‘ 【極限の知見】COMオブジェクトの明示的解放
‘ 参照カウンタを確実にデクリメントし、VBAメモリ空間の肥大化を防ぐ
Set swHoleDef = Nothing
Set swFeatMgr = Nothing
Set swFeat = Nothing
Set swModel = Nothing
Set swApp = Nothing
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“説明: ” & Err.Description, vbCritical, “Critical Error”
Resume CleanUp
End Sub
—
3. シニアエンジニアが押さえるべき「3つの魔境」と回避策
上記のコードを実務の巨大なアセンブリ文脈や、レガシーなVB.NET外接アドインへ移植する際、必ず遭遇する「仕様の罠」が存在する。チーフアーキテクトとしての知見から、その解決策をここに記す。
① JIS規格文字列とインデックスの不一致問題
`swHoleDef.Standard = 5` のように数値をハードコーディングしている箇所があるが、これはSolidWorksのバージョン(2022, 2023, 2024…)や、インストールされている規格ファイルの言語設定(日本語/英語)によって、内部IDがシフトすることがある。
- 極限の知見: 可能な限り、マクロ記録機能(Macro Recorder)を一度走らせ、生成されたC#またはVBAコードから正しいEnum値や文字列リテラルを動的に抽出、または定数クラスとして一元管理するアーキテクチャを構築せよ。
② スケッチ点の事前配置の義務
穴ウィザードは、単に `FeatureCreation3(swHoleDef)` を呼ぶだけでは生成されない。「どこに穴を開けるのか」という2次元座標(スケッチ点)が、対象面上にアクティブに存在している状態、あるいはあらかじめ選択されている状態でなければ、APIは沈黙するかエラーを吐く。
- 極限の知見: プログラムから完全に自動化する場合、ターゲット面を `Extension.SelectByID2` で選択した後、一時的な2Dスケッチを開き (`InsertSketch2`), `CreatePoint` で点を打ってから `HoleWizardDef` を適用するという一連のトランザクションをコード内で完結させる必要がある。
③ 単位系(SI単位系 vs ドキュメント単位系)の罠
SolidWorks APIの内部計算は、例外なくすべて「メートル法(MKS: Meter, Kilogram, Second)」で処理される。
ユーザーがドキュメントプロパティで「ミリメートル(mm)」を選択していようとも、VBAコード内では `0.02`(=20mm)のようにメートル換算した値を渡さなければならない。ここをミリ単位の数値(`20`)で渡してしまうと、突如として直径数メートルのモンスター級の穴が生成され、PCがフリーズする原因となる。
—
結:システム間連携を見据えた堅牢性の追求
今回解説した `HoleWizardDef` の制御技術は、単なるVBAのマクロ自動化に留まらない。ERPやPDM(SOLIDWORKS PDM)からのBOMデータ、あるいはCSV/JSON形式の穴加工リストを読み込み、数千種類あるパーツの穴あけ工程を完全自動バッチ処理するためのコアエンジンとなる。
安易なコードのコピペで済ませるのではなく、オブジェクトのライフサイクル管理、厳格なエラーハンドリング、そしてAPI固有の単位系の制約を理解した者だけが、真の「SolidWorks自動化の支配者」となることができる。
妥協なきコードで、レガシーな設計業務の壁を打ち破れ。
