【テクニカル・上級編】【スケッチ自動化】CreateLine2とCreateCircleByRadius2を組み合わせた2次元基本形状のプログラム作図 – SolidWorks VBA解析バイブル

スポンサーリンク

【SolidWorks VBAを掌握する極限の知見】スケッチ自動化の真髄:CreateLine2とCreateCircleByRadius2が織り示す高速ジオメトリ生成

世に氾濫するVBA解説書や生成AIの出力は、決まって「マクロの記録」をそのまま引き延ばしたような冗長なコードを吐き出す。`swApp.ActiveDoc`を乱発し、エラーハンドリングを怠り、COMオブジェクトの参照カウントの概念すらない。そんなコードが大規模な社内CAD自動化システムの現場でどうなるか――メモリリーク、突然のSolidWorksの沈黙(クラッシュ)、そして無限ループ。実務に耐えうるシステムなど構築できるはずがない。

私は長年、数千部品を抱える重厚長大なお客様の自動化基盤を構築してきた。
今回は、その現場の最前線で培った「スケッチ自動化における極限の知見」を公開する。テーマは、`CreateLine2`と`CreateCircleByRadius2`を駆使した2次元基本形状のプログラム作図だ。

単に線と円を描くだけではない。「どのコンテキストでスケッチを開き、どのように座標系を捉え、COMの寿命をどうコントロールするか」。その深淵に迫る。

1. 現場のエンジニアが陥る「3大アンチパターン」

まず、未熟なコードがなぜ現場で破綻するのか、そのメカニズムを明らかにしておく。

1. ドキュメントコンテキストの暗黙的依存
`ActiveDoc`に頼るコードは、裏で別のウィンドウがアクティブになった瞬間に誤作動を起こす。明確なオブジェクト変数をスコープ内に保持し、ポインタの有効性を常に担保せよ。
2. スケッチモードのライフサイクル無視
「スケッチを開いた状態」と「閉じている状態」のステートマシンを無視してメソッドを叩くと、APIは静かにエラーを返す(あるいは無視する)。
3. メモリリークとCOM解放の軽視
VBAのガベージコレクションは遅延実行される。ループ内でCOMオブジェクトを生成・破棄しないコードを書くことは、時限爆弾を抱えているのと同じだ。

2. 座標計算ロジックとAPIの正しい呼び出し順序

SolidWorks APIにおけるスケッチ描画は、「アクティブなスケッチ平面(ModelDoc2)」に対して行う。
`CreateLine2`は「始点(X, Y, Z)から終点(X, Y, Z)」へ線分を生成し、`CreateCircleByRadius2`は「中心(X, Y, Z)と半径」から円を生成する。

ここで注意すべきは、APIが受け取る引数はすべて「メートル(m)」単位であるという点だ。UI上で「mm」で見ている数値そのままを放り込ければ、意図したサイズの1000倍の巨大なジオメトリが生成され、ズームアウトの限界を超えて消失する。実務では必ず単位変換マクロ(ミリメートル → メートル)を挟むのが鉄則である。

3. 【実戦投入可能】堅牢なスケッチ自動生成コード

以下に、実務の現場で即座に使えるプロダクション品質のVBAコードを提示する。エラーハンドリング、オブジェクトの明示的解放、単位系の正規化を網羅した完全版だ。

Option Explicit

‘ —————————————————————–
‘ @Title: パラメトリック2D基本形状自動作図エンジン
‘ @Description: ミリ単位の指定値からメートル系APIへ安全に変換し、スケッチを構築する
‘ @Author: Chief Architect
‘ —————————————————————–
Sub ExecuteAdvancedSketchAutomation()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swSketchMgr As SldWorks.SketchManager
Dim boolstatus As Boolean

‘ 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

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

‘ 2. 処理速度向上のための画面描画・再計算抑制(パフォーマンス最適化)
swModel.Extension.UseExtraColorsForDrawing = False
boolstatus = swModel.Extension.SetUserPreferenceToggle(swUserPreferenceToggle_e.swViewDisplayHideAllTypes, True)

‘ 3. 基準平面(今回は「前視 / Front Plane」)の選択とスケッチ挿入
boolstatus = swModel.Extension.SelectByID2(“前方”, “PLANE”, 0, 0, 0, False, 0, Nothing, 0)
If Not boolstatus Then
MsgBox “基準平面「前方」が見つかりません。”, vbCritical
GoTo CleanUp
End If

Set swSketchMgr = swModel.SketchManager
swSketchMgr.InsertSketch True

‘ 4. 座標定義とジオメトリ生成ロジック(単位系:ミリメートルをメートルに変換: / 1000#)
‘ 【要件】原点を起点とした 100mm x 50mm の長方形フレームと、中央に半径 20mm の穴を描画する
Dim scaleFactor As Double
scaleFactor = 0.001 ‘ mm to m

Dim x1 As Double, y1 As Double, z1 As Double
Dim x2 As Double, y2 As Double, z2 As Double

‘ 4-1. 外形線分の描画 (CreateLine2)
‘ 下辺: (0,0) -> (100,0)
Call CreateSafeLine(swSketchMgr, 0# scaleFactor, 0# scaleFactor, 0#, 100# scaleFactor, 0# scaleFactor, 0#)
‘ 右辺: (100,0) -> (100,50)
Call CreateSafeLine(swSketchMgr, 100# scaleFactor, 0# scaleFactor, 0#, 100# scaleFactor, 50# scaleFactor, 0#)
‘ 上辺: (100,50) -> (0,50)
Call CreateSafeLine(swSketchMgr, 100# scaleFactor, 50# scaleFactor, 0#, 0# scaleFactor, 50# scaleFactor, 0#)
‘ 左辺: (0,50) -> (0,0)
Call CreateSafeLine(swSketchMgr, 0# scaleFactor, 50# scaleFactor, 0#, 0# scaleFactor, 0# scaleFactor, 0#)

‘ 4-2. 中心に円を描画 (CreateCircleByRadius2)
‘ 中心座標: (50, 25), 半径: 20mm
Dim centerX As Double, centerY As Double, centerZ As Double, radius As Double
centerX = 50# scaleFactor
centerY = 25# scaleFactor
centerZ = 0#
radius = 20# scaleFactor

Dim swSketchCircle As SldWorks.SketchSegment
Set swSketchCircle = swSketchMgr.CreateCircleByRadius2(centerX, centerY, centerZ, radius)

If swSketchCircle Is Nothing Then
MsgBox “円の生成に失敗しました。”, vbExclamation
End If

‘ 5. スケッチの正常終了とコミット
swSketchMgr.InsertSketch True

CleanUp:
‘ 6. メモリとビューの状態復元(リソースリーク防止)
Set swSketchCircle = Nothing
Set swSketchMgr = Nothing
Set swModel = Nothing
Set swApp = Nothing

MsgBox “スケッチの自動作図が正常に完了しました。”, vbInformation
End Sub

‘ —————————————————————–
‘ 補助関数: 安全な線分生成ラッパー
‘ —————————————————————–
Private Sub CreateSafeLine(sketchMgr As SldWorks.SketchManager, x1 As Double, y1 As Double, z1 As Double, x2 As Double, y2 As Double, z2 As Double)
Dim swSegment As SldWorks.SketchSegment
Set swSegment = sketchMgr.CreateLine2(x1, y1, z1, x2, y2, z2)
If swSegment Is Nothing Then
‘ ログ出力や例外処理をここに拡張可能
Debug.Print “Warning: Line creation failed at (” & x1 & “,” & y1 & “) to (” & x2 & “,” & y2 & “)”
End If
Set swSegment = Nothing
End Sub

4. チーフアーキテクトが教える「現場の知恵」

上記のコードを実務の基幹システムやPDM/PLM連携モジュールに組み込む際、さらに次の要件を考慮すべきだ。

1. 形状の拘束(Relations / Dimensions)の扱い

今回紹介した `CreateLine2` や `CreateCircleByRadius2` は「幾何学的な描画」を行うだけであり、「完全定義(Fully Defined)」状態にはならない(アンダーコンストラクション状態)
厳密な設計品質が求められる環境では、この後に `ISketchManager::AddDimension` や拘束条件付与API(`IModelDoc2::AddRelation`)をシーケンシャルに呼び出し、寸法駆動設計(Parametric Design)の要件を満たす必要がある。

2. COMオブジェクトの参照解放の徹底

VBA環境下において、ローカル変数として宣言されたSolidWorks APIオブジェクトはプロシージャ終了時に解放されるが、巨大なループや例外発生時のメモリ断片化(Heap Fragmentation)を防ぐため、上記コードのように明示的に `Set xxx = Nothing` を記述する習慣を徹底してほしい。これが数千回連続実行されるバッチ処理でのクラッシュを防ぐ唯一の防壁となる。

結び

自動化の本質は、手作業の模倣ではない。「手作業では到底なし得ない圧倒的な速度と正確性で、数学的なデジタル空間を支配すること」にある。
今回解説したスケッチ自動化の骨組みをベースに、自社の業務要件に合わせたパラメータ駆動エンジンを構築してほしい。妥協なきコードだけが、あなたのシステムを永遠の安定稼働へと導くのだ。

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