こんにちは!SolidWorks自動化の現場で泥臭く、かつ優雅にシステムを組み上げている先輩エンジニアです。
「マクロの記録」ボタンを押して、ポチポチと部品を配置して……おめでとうございます、あなたはすでにSolidWorks VBAの第一歩を踏み出しました。でも、そろそろこんな壁にぶぶ当たっていませんか?
- 「合致(Mate)をプログラムで組もうとしたら、面やエッジのIDが変わってエラー連発だよ……」
- 「数千個のボルトを配置するのに、合致を使ったら再計算が重すぎてPCがフリーズしそう……」
そうなんです。SolidWorksの標準機能である「合致」は、人間が手動でアセンブリを組むには非常に優秀ですが、VBAから大量の部品を高速制御するには、実はあまりに向いていないのです。
そこで今回は、世界最高峰の自動化エンジニアたちがこっそり使っている秘密兵器、`IComponent2` インターフェースと「変形マトリクス(Transform)」による座標変換の世界へあなたを招待します。
ここをクリアすれば、合致のしがらみから解放され、数学の力で部品の位置と姿勢を自由自在に操れるようになりますよ。しっかりついてきてくださいね!
—
1. なぜ「合致(Mate)」を使わず「マトリクス演算」なのか?
まず、アセンブリ内での部品の位置は、すべて 4×4 の同次変換行列(Transform) で管理されています。
通常、私たちは「この面とこの面を一致させる」という合致フィーチャーを作成して位置を決めますが、これは内部で方程式を解くため、部品が増えるほどSolidWorksの再計算(Rebuild)負荷が爆発的に跳ね上がります。
一方、マトリクス(行列)を直接書き換える手法は、純粋な座標計算(平行移動と回転)だけをダイレクトに部品に適用するため、圧倒的な高速処理が可能です。さらに、「存在しない面」や「CAD上の基準点」を気にする必要が一切なくなるため、エラーの起きない強靭なコードが書けるようになります。
—
2. 魔法のインターフェース `IComponent2` の正体
SolidWorks VBAにおいて、アセンブリ内の「部品(構成部品)」を指し示す最も重要なオブジェクトが `IComponent2` です。
このオブジェクトは、いわば「空間に漂う部品の操り人形」です。この人形に対して、
- 「お前の名前は何だ?」(`Name2`)
- 「今、空間のどこにいるんだ?」(`Transform2`)
- 「そこに移動しろ!」(`SetTransform2`)
という命令を与えることで、部品を思い通りの場所に瞬間移動させることができます。
—
3. 【実践】VBAで部品をマトリクス移動させるコード
それでは、実際にアクティブなアセンブリ内の特定の部品を指定し、マトリクスを使って「X方向に 100mm 移動、Z軸周りに 45度回転」させる実用コードを見てみましょう。
開発の現場でそのままコピペして検証できるように、丁寧なコメントをつけています。
Option Explicit
Sub MoveComponentByTransform()
‘ =========================================================================
‘ 目的: IComponent2 と Transform を使用して、合致を使わずに部品を移動・回転する
‘ 前提: 活性化されたアセンブリが開いており、対象の部品名がアセンブリ内に存在すること
‘ =========================================================================
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAsskDoc As SldWorks.AssemblyDoc
Dim swComp As SldWorks.Component2
Dim swMathUtil As SldWorks.MathUtility
Dim swTransform As SldWorks.MathTransform
‘ アプリケーションとドキュメントの取得
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
‘ ドキュメントが開かれていない、またはアセンブリではない場合は終了
If swModel Is Nothing Then
MsgBox “ドキュメントが開かれていません。”, vbCritical
Exit Sub
End If
If swModel.GetType <> swDocASSEMBLY Then
MsgBox “アクティブなドキュメントがアセンブリではありません。”, vbCritical
Exit Sub
End If
Set swAsskDoc = swModel
Set swMathUtil = swApp.GetMathUtility
‘ — 【重要】操作したい部品のインスタンス名を指定 —
‘ ※「部品名-1」はFeatureManagerデザインツリーに表示されている名前を指定してください
Dim targetCompName As String
targetCompName = “Plate_A-1” ‘ ご自身の環境の部品名に変更してください
‘ IComponent2 の取得
Set swComp = swAsskDoc.GetComponentByName(targetCompName)
If swComp Is Nothing Then
MsgBox “指定された部品が見つかりません: ” & targetCompName, vbCritical
Exit Sub
End If
‘ =========================================================================
‘ 1. 現在のトランスフォーム(位置・姿勢)を取得
‘ =========================================================================
Set swTransform = swComp.Transform2
If swTransform Is Nothing Then
‘ まだ一度も位置が決まっていない(固定されている等)場合は単位行列を取得
Set swTransform = swMathUtil.CreateTransform(Empty)
End If
‘ =========================================================================
‘ 2. 移動量・回転量の定義(数学ユーティリティを使用)
‘ =========================================================================
‘ 平行移動ベクトル(X, Y, Z)単位はメートル (Meter) ! SolidWorks APIの基本単位はメートルです!
Dim vTranslation(2) As Double
vTranslation(0) = 0.1 ‘ X方向に +100mm
vTranslation(1) = 0.0 ‘ Y方向に 0mm
vTranslation(2) = 0.0 ‘ Z方向に 0mm
Dim swTranslationVec As SldWorks.MathVector
Set swTranslationVec = swMathUtil.CreateVector(vTranslation)
‘ 回転軸と角度の定義(Z軸周りに 45度回転)
Dim vRotAxis(2) As Double
vRotAxis(0) = 0#
vRotAxis(1) = 0#
vRotAxis(2) = 1# ‘ Z軸
Dim swRotAxisVec As SldWorks.MathVector
Set swRotAxisVec = swMathUtil.CreateVector(vRotAxis)
Dim radAngle As Double
radAngle = 45 (Atn(1) 4) / 180 ‘ 45度をラジアンに変換
‘ =========================================================================
‘ 3. マトリクスの合成(既存の姿勢に移動・回転を掛け合わせる)
‘ =========================================================================
‘ 回転を適用
Dim swRotTransform As SldWorks.MathTransform
Set swRotTransform = swMathUtil.CreateTransformRotateAxis(swRotAxisVec, radAngle)
Set swTransform = swTransform.Multiply(swRotTransform)
‘ 平行移動を適用
Set swTransform = swTransform.Multiply(swMathUtil.CreateTransform(vTranslation))
‘ =========================================================================
‘ 4. コンポーネントに新しいマトリクスを適用
‘ =========================================================================
Dim boolstatus As Boolean
boolstatus = swComp.SetTransform2(swTransform)
‘ 画面を強制再描画
swModel.EditRebuild3
If boolstatus Then
MsgBox “マトリクス演算による部品の移動が完了しました!”, vbInformation
Else
MsgBox “部品の移動に失敗しました。固定(Fix)が解除されているか確認してください。”, vbExclamation
End If
End Sub
—
4. 現場で絶対にハマる「3大トラップ」と回避策
このマトリクス操作をマスターする上で、多くのエンジニアが涙を流すポイントがあります。先回りして回避策を伝授しておきますね。
トラップ1: 「単位系がミリメートルではなくメートル(m)」
SolidWorksのAPI内部(MathUtilityなど)は、すべて「メートル(m)」で計算されます。
コード内で `0.1` と書いた場合、それは100mmを意味します。「あれ?部品が宇宙の彼方に吹っ飛んだ!」という時は、だいたい単位の勘違い(mmとmの混同)が原因です。
トラップ2: 「部品が『固定(Fix)』されている」
アセンブリ内で部品が「固定」フューチャーになっていると、`SetTransform2` メソッドは冷酷に無視されます(あるいはエラーになります)。
プログラムで動かす前に、対象の部品は「浮動(Float)」状態にしておくか、コード内で `swComp.IsFixed = False` と明示的に解除してあげる必要があります。
トラップ3: 「アセンブリのコンテキスト(ルートからの階層)」
今回のサンプルはルートアセンブリ直下の部品を想定していますが、サブアセンブリ(アセンブリの中のアセンブリ)の奥深くにある部品を動かす場合、パスの指定や相対マトリクスの考慮が必要になります。まずはルート直下の部品で動作を完全に理解してから、多重アセンブリへ応用していきましょう。
—
5. おわりに:ここをクリアすれば、あなたはもう中級者を超えている
お疲れ様でした!今回は `IComponent2` と変形マトリクスによるアセンブリ制御の核心に迫りました。
「合致に頼らず、数学でCAD空間を支配する」――この感覚が掴めると、何万点もあるプラント設計の自動化や、パラメータを変更するだけで瞬時に形状が再配置される夢のようなジェネレーティブ・デザインツールを、あなた自身の手でVBAで作れるようになります。
「ここ、どういうことだろう?」と疑問に思ったら、遠慮なくコメント欄などで質問してくださいね。あなたのSolidWorks自動化ライフが、最高にエキサイティングなものになることを応援しています!
