こんにちは!SolidWorks VBAの世界へようこそ。
マクロの記録ボタンを押して自動生成されたコードを眺めるだけの日々は、もうおしまいです。今日からあなたも、SolidWorksの内部構造を意のままに操る「アセンブリ・コントローラー」になりましょう。
大規模なアセンブリを扱っていて、こんな絶望感を味わったことはありませんか?
「開くだけでコーヒーが何杯も飲めるほど時間がかかる…」
「特定の検証のために、一部のサブアセンブリだけを一時的に消したり固定したりしたいのに、手動だとマウスをクリックするだけで気が狂いそうになる…」
大丈夫。ここをクリアすれば、あなたのSolidWorks VBAスキルはマクロ記録のレベルを完全に卒業し、プロのエンジニア領域へと到達します。今日は、アセンブリの「生死(抑制)」と「自由度(固定)」をプログラムから支配する極意を、優しく、そして徹底的に伝授しますね。
—
1. アセンブリ構造を支配する「2大巨頭」を知る
SolidWorksのアセンブリを開くとき、メモリ上には「どのパーツが、どこに配置されているか」というツリー構造(親子関係)が展開されます。これをコードから操作するときに絶対に避けて通れないのが、以下の2つのオブジェクトです。
1. `SldWorks.ModelDoc2` (ドキュメントの神様)
- 今開いているファイルそのものを表します。ファイルの保存や画面の再描画など、全体を統括します。
2. `SldWorks.Component2` (パーツ・サブアセンブリの分身)
- アセンブリの中に組み込まれている「個々の部品のインスタンス」を表します。「お前、ちょっと隠れろ(抑制)」とか「動くな(固定)」と命令を送る相手は、この `Component2` です。
マクロの記録では部品名がベタ書きされてしまいますが、実務では「アセンブリの中から目的のコンポーネントを名前で、あるいはループでスマートに見つけ出す」のがエンジニアの流儀です。
—
2. 抑制(Suppression)と固定(IsFixed)の正体
今回主役となるメソッドとプロパティの正体を、少しだけ深掘りしておきましょう。ここを知っているだけで、他の人がハマるエラーを華麗に回避できます。
① `IComponent2.SetSuppression2` (生死のコントロール)
コンポーネントの状態には主に以下の3つがあります。
- 完全解決 (Resolved):メモリにフル読み込み。重いけど編集できる。
- 軽量 (Lightweight):主要なデータだけ読み込み。軽い。
- 抑制 (Suppressed):メモリから一時的に除外。存在しないも同然になり、爆速で軽くなる。
`SetSuppression2` を使うことで、この状態を自由自在に変えられます。大規模モデルの軽量化検証には欠かせません。
② `IComponent2.IsFixed` (自由度のコントロール)
アセンブリに配置された部品は、初期状態ではプラプラと動いてしまう(あるいは位置が定まっていない)ことがあります。これを「ここに固定せよ!」と釘付けにするのが `IsFixed` です。
—
3. 【実践】サブアセンブリを動的制御するVBAコード
それでは、実際の現場でそのまま使える実用コードを見てみましょう。
このスクリプトは、アクティブなアセンブリ内から指定した名前のサブアセンブリ(またはパーツ)を検索し、「非抑制(表示)にして位置を固定」、あるいは「抑制(非表示・メモリ解放)」へと動的に切り替えるものです。
Option Explicit
Sub ControlAssemblyComponent()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssDoc As SldWorks.AssemblyDoc
Dim swRootComp As SldWorks.Component2
Dim targetComp As SldWorks.Component2
‘ 1. アプリケーションとアクティブドキュメントの取得
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 swAssDoc = swModel
‘ 2. ルートコンポーネント(最上位アセンブリ自身)の取得
Set swRootComp = swAssDoc.GetRootComponent3(True)
If swRootComp Is Nothing Then
MsgBox “ルートコンポーネントを取得できませんでした。”, vbCritical
Exit Sub
End If
‘ —————————————————-
‘ 3. 制御したいコンポーネントの名前を指定(※ご自身の環境に合わせて変更してください)
‘ —————————————————-
Dim targetCompName As String
targetCompName = “SubAssembly_A-1” ‘ 例:サブアセンブリのインスタンス名
‘ 再帰的(ツリーの奥底まで)にコンポーネントを探索
Set targetComp = FindComponent(swRootComp, targetCompName)
If targetComp Is Nothing Then
MsgBox “指定されたコンポーネントが見つかりません: ” & targetCompName, vbExclamation
Exit Sub
End If
‘ —————————————————-
‘ 4. 高度な状態管理の実行
‘ —————————————————-
On Error GoTo ErrorHandler
‘ 【アクションA】まずは確実に「非抑制(Resolved)」に戻す
‘ 引数: swComponentResolved (2)
Dim ret As Long
ret = targetComp.SetSuppression2(swComponentResolved)
If ret = 0 Then
MsgBox “抑制状態の変更に失敗しました。”, vbCritical
Exit Sub
End If
‘ 【アクションB】位置を固定する(IsFixed = True)
‘ ※注意: コンポーネントが固定をサポートしていない場合もあります
targetComp.IsFixed = True
‘ 画面を強制再描画して変更を反映
swModel.EditRebuild3
MsgBox “コンポーネント [” & targetCompName & “] を非抑制にし、位置を固定しました!”, vbInformation
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical
End Sub
‘ ====================================================
‘ ヘルパー関数: 子孫コンポーネントを再帰的に探索する
‘ ====================================================
Function FindComponent(ByVal parentComp As SldWorks.Component2, ByVal searchName As String) As SldWorks.Component2
Dim vChildren As Variant
Dim i As Long
Dim childComp As SldWorks.Component2
Dim foundComp As SldWorks.Component2
vChildren = parentComp.GetChildren
If IsEmpty(vChildren) Then Exit Function
For i = LBound(vChildren) To UBound(vChildren)
Set childComp = vChildren(i)
‘ コンポーネント名(ファイル名やインスタンス名)をチェック
‘ 例: “SubAssembly_A-1” のような名前と一致するか
If UCase(childComp.Name2) = UCase(searchName) Then
Set FindComponent = childComp
Exit Function
End If
‘ さらに下の階層(孫アセンブリなど)を再帰探索
Set foundComp = FindComponent(childComp, searchName)
If Not foundComp Is Nothing Then
Set FindComponent = foundComp
Exit Function
End If
Next i
Set FindComponent = Nothing
End Function
—
4. 陥りやすい罠と、プロが教える回避テクニック
このコードを実際に現場で動かすとき、初心者が必ずと言っていいほどハマる「3つの罠」があります。先回りしてクリアしておきましょう。
罠1:名前の指定ミス(インスタンス名 vs ファイル名)
`childComp.Name2` が指すのは、ツリーに表示されている「インスタンス名(例: SubAssembly_A-1)」です。ファイル名(SubAssembly_A.sldasm)そのものではないケースが多いため、FeatureManagerデザインツリーに表示されている通りの名前を正確に指定してください。
罠2:抑制されたコンポーネントからの子孫探索
一度「抑制(Suppressed)」されたサブアセンブリの内部にあるパーツは、メモリ上から姿を消しているため、通常の `GetChildren` では取得できません。
「まずは親を非抑制にしてから、子を操作する」という順番を守ることが、バグを防ぐ鉄則です。先ほどのサンプルコードが、まさにこの順番(先に `SetSuppression2(swComponentResolved)` を実行)を厳守しているのはそのためです。
罠3:処理後の画面更新忘れ
APIでアセンブリの構造や状態をごっそり書き換えた後、画面が真っ白のまま固まったり、古い表示が残ったりすることがあります。コードの最後には必ず `swModel.EditRebuild3`(または `ForceRebuild3`)を挟んで、SolidWorksに「画面を今の最新状態に描き直せ!」と指示を出してあげましょう。
—
最後に:ここをクリアすれば、基本はバッチリ!
お疲れ様でした!`IComponent2.SetSuppression2` と `IsFixed` を組み合わせることで、あなたは手動での果てしないクリック作業から解放され、数千パーツある大規模アセンブリの検証をプログラム一本でコントロールする権利を手に入れました。
「重いアセンブリをプログラムでサクッと軽量化して、必要な部分だけを検証する」
これができるようになると、設計・解析の自動化の幅が一気に広がります。
ぜひ、ご自身の環境のモデルでこのコードを試してみてくださいね。あなたのSolidWorksライフが、もっとスマートでエキサイティングなものになりますように!
