【SolidWorks VBA】寸法拘束の自動化:IConstraintManagerが握るスケッチ崩壊の呪縛からの解放
開発現場で自動化ツールを構築する際、最も頭を悩ませる問題の一つが「プログラムで描画したスケッチの崩壊」だ。
座標計算を完璧に行ったはずなのに、いざフィーチャーを押し出そうとしたらジオメトリがねじれ、エラーでマクロが強制終了する――。この悪夢の原因は、スケッチ要素(線や円)をただ配置しただけで、「幾何拘束(Geometric Relations)」を与えていないことにある。
SolidWorks VBAにおいて、この幾何拘束を司る核心が `IConstraintManager` である。
今回は、実務の現場で「絶対にバグらない」堅牢なスケッチ自動化を実現するため、APIの裏側にあるオブジェクトの振る舞いと、実用的なプロダクションコードを網羅的に解説しよう。
—
1. なぜ「ただ描くだけのコード」は実務で使い物にならないのか?
多くの初学者が陥る罠は、`ISketchManager::CreateLine` や `CreateCircleByRadius` で図形を描画して満足してしまうことだ。
SolidWorksのスケッチエンジンは、外部から明示的な拘束を与えない限り、すべての要素を「自由度を持った状態」で保持する。つまり、後続の寸法変更やアセンブリの再構築(Rebuild)によって、線が勝手に移動し、意図しない形状に変形する。
現場で求められる「真の自動化」の要件
1. 一意の特定性: APIで生成したエンティティ(線や点)のポインタを確実につかむこと。
2. 選択コンテキストの排除: UIに頼らず、メモリ上で安全に拘束を付与すること。
3. エラーハンドリング: すでに拘束が存在する場合や、過剰拘束(Over-defined)になる状況を検知・回避すること。
これらをクリアするためには、`ModelDoc2` から `SelectionMgr`、そして `IConstraintManager` へ至るオブジェクトのライフサイクルを完全に理解しなければならない。
—
2. IConstraintManager アーキテクチャの核心
幾何拘束をプログラムから付与する場合、プロセスは常に以下の3ステップを踏む。
1. 対象エンティティの選択(Select): 拘束したい線や頂点をAPI経由でアクティブにする。
2. 拘束の追加(AddConstraint): `IModelDoc2::AddSketchedRelation` または `IConstraintManager` を用いて関係性を定義する。
3. 選択のクリア(ClearSelection): 次の処理への干渉を防ぐため、選択状態を必ずリセットする。
ここで重要なのは、SolidWorks APIの多くが「現在の選択セット(Selection Manager)」を暗黙の入力として受け取る設計になっている点だ。非同期やマルチスレッドを意識する必要はないが、「どのエンティティを選択状態にしてメソッドを叩くか」の順序を誤ると、意図しない場所に拘束がつき、マクロが沈黙する。
—
3. 【プロダクションコード】水平・垂直・一致拘束を自動付与する実践VBA
以下に、四角形(長方形)をプログラムで描き、4本の線に「水平・垂直」拘束を、コーナーの点に「一致(Coincident)」拘束を完璧な順序で付与する実用コードを提示する。
このコードは、エラーハンドリングとオブジェクトの解放を徹底した、そのまま現場の基幹システムに組み込める品質のスクリプトだ。
Option Explicit
‘ =========================================================================
‘ プロジェクト名: SketchConstraintAutomation
‘ 概要 : 4本の線分で構成される矩形を描画し、幾何拘束を自動付与する
‘ 前提条件: 新規部品ドキュメントが開いていること
‘ =========================================================================
Sub Main()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swSkMgr As SldWorks.SketchManager
Dim boolstatus As Boolean
‘ 1. アプリケーションおよびドキュメントの取得
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。”, vbCritical, “エラー”
Exit Sub
End If
‘ 2. スケッチモードの開始 (XY平面)
Set swSkMgr = swModel.SketchManager
swSkMgr.InsertSketch True
Dim swLine1 As SldWorks.SketchSegment
Dim swLine2 As SldWorks.SketchSegment
Dim swLine3 As SldWorks.SketchSegment
Dim swLine4 As SldWorks.SketchSegment
‘ 3. 矩形を構成する4つの線分を描画 (座標はメートル単位: 100mm = 0.1m)
‘ 下辺
Set swLine1 = swSkMgr.CreateLine(0, 0, 0, 0.1, 0, 0)
‘ 右辺
Set swLine2 = swSkMgr.CreateLine(0.1, 0, 0, 0.1, 0.05, 0)
‘ 上辺
Set swLine3 = swSkMgr.CreateLine(0.1, 0.05, 0, 0, 0.05, 0)
‘ 左辺
Set swLine4 = swSkMgr.CreateLine(0, 0.05, 0, 0, 0, 0)
‘ 描画キャッシュの反映と選択クリア
swModel.ClearSelection2 True
‘ 4. 幾何拘束の動的付与
‘ — 水平・垂直拘束の付与 —
boolstatus = ApplyGeometricConstraint(swModel, swLine1, swConstrainedLineHorizontal)
boolstatus = ApplyGeometricConstraint(swModel, swLine3, swConstrainedLineHorizontal)
boolstatus = ApplyGeometricConstraint(swModel, swLine2, swConstrainedLineVertical)
boolstatus = ApplyGeometricConstraint(swModel, swLine4, swConstrainedLineVertical)
‘ — 端点の一致(Coincident)拘束の付与 (閉じたループにするため) —
‘ ※実務ではスケッチセグメントの端点(ISketchPoint)を取得して一致させる
Dim swStartPt1 As SldWorks.SketchPoint
Dim swEndPt1 As SldWorks.SketchPoint
Dim swStartPt2 As SldWorks.SketchPoint
Set swStartPt1 = swLine1.GetStartPoint2()
Set swEndPt1 = swLine1.GetEndPoint2()
Set swStartPt2 = swLine2.GetStartPoint2()
‘ 線1の終点 と 線2の始点を一致させる
‘ (通常、座標が一致していれば自動結合されるが、明示的に拘束を与える場合)
‘ Select2の引数: Mark(1=選択), Append(True=複数選択)
swStartPt1.Select4 False, Nothing
swStartPt2.Select4 True, Nothing
‘ 一致拘束の追加
swModel.AddSketchedRelation swConstraintType_Coincident
swModel.ClearSelection2 True
‘ 5. スケッチの終了
swSkMgr.InsertSketch True
MsgBox “スケッチの自動拘束が正常に完了しました。”, vbInformation, “成功”
End Sub
‘ =========================================================================
‘ 汎用関数: 指定したエンティティに幾何拘束を付与するラッパー関数
‘ =========================================================================
Private Function ApplyGeometricConstraint(ByVal swModel As SldWorks.ModelDoc2, ByVal swEnt As Object, ByVal constraintType As Long) As Boolean
Dim swSelMgr As SldWorks.SelectionMgr
Set swSelMgr = swModel.SelectionManager
‘ 選択をクリア
swModel.ClearSelection2 True
‘ 対象エンティティをマーク1で選択
Dim swSelData As SldWorks.SelectData
Set swSelData = swSelMgr.CreateSelectData()
Dim swDispEnt As SldWorks.Entity
Set swDispEnt = swEnt
If swDispEnt.Select4(True, swSelData) Then
‘ 拘束の追加を実行
Dim res As Long
res = swModel.AddSketchedRelation(constraintType)
ApplyGeometricConstraint = (res > 0)
Else
ApplyGeometricConstraint = False
End If
swModel.ClearSelection2 True
End Function
—
4. データベース連携・外部ファイル入力における設計の注意点
Excelや外部データベース(SQL Server、SQLiteなど)からパラメータ(幅、高さ、穴径など)を読み込み、動的にモデルを生成するシステムを構築する場合、以下のアーキテクチャ上の罠に注意せよ。
1. 単位系の罠 (MKS vs MMGS)
SolidWorksのAPI内部処理は、例外なく「メートル法(MKS)」で動作する。
データベースやUIから「100」という数値を受け取った際、それをそのまま `100` として渡すと、100メートル(100,000mm)の巨大なモデルが生成され、ジオメトリ計算が破綻する。
必ず `0.1` のようにミリメートルをメートルに変換(`Value / 1000#`)するミドルウェア層をコード内に設けること。
2. 過剰拘束(Over-defined)の検知とトランザクション
外部DBからの不正な値(例: 幅を固定した上で、対角の寸法も矛盾した値で与えるなど)が入力された場合、`AddSketchedRelation` や寸法付与時にSolidWorksはエラーを吐くか、警告ダイアログを出してマクロが停止する。
これを防ぐため、バッチ処理型の自動化では以下の鉄則を守れ:
- 処理の最初で `swModel.ClearSelection2 True` を徹底する。
- 戻り値のステータス(成功したか否か)を必ず評価する。
- 失敗した場合は、直前の変更をロールバックするようなエラーハンドリング(`Err` オブジェクトの活用)を実装する。
—
5. チーフアーキテクトからの提言
寸法拘束の自動化は、単なる「コードの記述量」の問題ではない。それは「CADが空間をどう認識しているかという数学的モデルを、VBAのコード上に完全に再現する作業」である。
`IConstraintManager` と `AddSketchedRelation` を使いこなせるようになれば、人間が手動で行っていたルーチンワークの9割はコードに置き換えることができる。エラーに怯える日々を抜け出し、堅牢で美しい自動化アーキテクチャを君の手で構築してほしい。
