【入門編】【初心者向け】アセンブリ内の全コンポーネント名とファイルパスをイミディエイトウィンドウに出力する – SolidWorks VBA解析バイブル

スポンサーリンク

【SolidWorks VBA入門】アセンブリ構造を丸裸に!全コンポーネント名とファイルパスを瞬時に把握する秘訣

皆さん、こんにちは!業務自動化の最前線でSOLIDWORKSと向き合い続けてきたチーフアーキテクトです。
SOLIDWORKSを日々お使いの皆さんの中には、「マクロの記録」機能を使って、ちょっとした定型作業を自動化してみた、という経験をお持ちの方もいるかもしれませんね。それは素晴らしい第一歩です!

でも、そこから一歩踏み出して、「アセンブリの構成をプログラムで自在に操りたい」「特定の条件を満たす部品だけを抽出したい」 と思ったことはありませんか?
その扉を開くための、最初の、そして最も重要な鍵となるのが、アセンブリ内のコンポーネントを網羅的に走査し、その情報を取得することです。

今回の記事では、【初心者向け】として、アクティブなアセンブリドキュメント内の全コンポーネント(構成部品)の名前とファイルパスを、VBAのイミディエイトウィンドウに出力する方法を、一つずつ丁寧に解説していきます。
ここをクリアすれば、SOLIDWORKS VBAの基本はバッチリですよ。さあ、一緒に一歩踏み出しましょう!

—

なぜアセンブリの構造把握が重要なのか?

SOLIDWORKSのアセンブリは、複数の部品(パーツ)やサブアセンブリが組み合わさってできています。私たちが画面上で見ているのは、その最終的な形状ですが、VBAで自動化を行う際には、内部でSOLIDWORKSがどのようにそれらの部品を管理しているかを理解することが非常に重要です。

例えば、

  • 特定の色が設定されている部品だけを抽出したい
  • 特定のカスタムプロパティを持つ部品の材質を変更したい
  • ある部品がアセンブリ内のどこで使われているかを知りたい

といった要求は、すべてアセンブリのコンポーネント構造をプログラムで走査できる能力にかかっています。
今回は、その第一歩として、すべてのコンポーネントの「名前」と「ファイルパス」を取得してみましょう。これは、アセンブリを構成する「設計のDNA」を読み解くようなものです。

—

SOLIDWORKS APIの核心:`IComponent2`オブジェクト

SOLIDWORKS VBAでアセンブリ内の部品にアクセスする際、私たちは主に`IComponent2`というオブジェクトを扱います。
「Component」という言葉が示す通り、これはアセンブリを構成する「構成部品」そのものを表すオブジェクトです。なぜ`2`が付いているのか? と疑問に思う方もいるかもしれませんね。これはAPIのバージョンを示しており、SOLIDWORKSの進化に合わせて機能が追加された際に、互換性を保ちながら新しい機能を提供する目的でバージョン番号が付与されています。現在は`IComponent2`を使うのが一般的です。

この`IComponent2`オブジェクトには、その構成部品に関する様々な情報が詰まっています。今回使うのは、以下の2つのプロパティです。

  • `Name2`: アセンブリ内で表示されるコンポーネントのインスタンス名(例: `Part1<1>`, `SubAssy<2>`)。これは、同じ部品ファイルが複数回挿入されていても、それぞれ異なる名前を持ちます。
  • `PathName`: そのコンポーネントが参照している部品ファイルまたはサブアセンブリファイルのフルパス(例: `C:\Projects\MyProject\Part1.SLDPRT`)。

これらの情報を取得して、イミディエイトウィンドウに出力するのが今回のゴールです。

—

実践!VBAコードを書いてみよう

それでは、実際にVBAコードを書いてみましょう。

1. VBAエディタを開く

SOLIDWORKSを開き、アセンブリドキュメントを開いた状態で、以下の手順でVBAエディタを開きます。

  • SOLIDWORKSメニューバーの `ツール(T)` -> `マクロ(M)` -> `新規マクロ(N)` を選択。
  • 適当な名前(例: `GetComponentInfo.swp`)を付けて保存します。
  • VBAエディタが開いたら、左側の「プロジェクトエクスプローラー」ウィンドウで、`VBAProject (GetComponentInfo.swp)`の下にある`Module1`をダブルクリックします。

2. コードの準備

`Module1`に以下のコードをコピー&ペーストしてください。各行の意味は後ほど詳しく解説します。

Option Explicit

Sub GetAllComponentInfo()

‘ ■ 1. SOLIDWORKSアプリケーションへの接続とドキュメントの取得
Dim swApp As SldWorks.SldWorks ‘ SOLIDWORKSアプリケーションオブジェクト
Dim swModel As SldWorks.ModelDoc2 ‘ アクティブなドキュメントオブジェクト
Dim swAssy As SldWorks.AssemblyDoc ‘ アセンブリドキュメントオブジェクト

‘ SOLIDWORKSアプリケーションへの接続を試みます
Set swApp = Application.SldWorks

‘ アクティブなドキュメントを取得します
Set swModel = swApp.ActiveDoc

‘ ドキュメントが開いているか、アセンブリドキュメントであるかをチェックします
If swModel Is Nothing Then
MsgBox “SolidWorksドキュメントが開かれていません。”, vbCritical
Exit Sub
End If

If swModel.GetType <> swDocumentTypes_e.swDocAssembly Then
MsgBox “アクティブなドキュメントはアセンブリではありません。”, vbCritical
Exit Sub
End If

‘ ModelDoc2オブジェクトをAssemblyDocオブジェクトに型変換します
‘ これにより、アセンブリ固有のメソッドやプロパティにアクセスできるようになります
Set swAssy = swModel

‘ ■ 2. アセンブリ内の全コンポーネントを取得
Dim vComponents As Variant ‘ コンポーネントの配列を格納する変数
Dim swComp As SldWorks.Component2 ‘ 各コンポーネントオブジェクトを格納する変数

‘ アセンブリの全トップレベルコンポーネントを取得します。
‘ Trueを指定すると、非表示/抑制状態のコンポーネントも含め、すべてのコンポーネントを取得します。
‘ GetComponentsメソッドは、配列としてコンポーネントを返します。
vComponents = swAssy.GetComponents(True)

‘ コンポーネントが一つもない場合(空のアセンブリなど)のチェック
If IsEmpty(vComponents) Then
MsgBox “このアセンブリにはコンポーネントがありません。”, vbInformation
Exit Sub
End If

‘ ■ 3. 各コンポーネントの情報を取得してイミディエイトウィンドウに出力
Debug.Print “——————————————————–”
Debug.Print “アセンブリ名: ” & swModel.GetTitle
Debug.Print “——————————————————–”
Debug.Print “インスタンス名 (ファイルパス)”
Debug.Print “——————————————————–”

‘ 取得したコンポーネントの配列を一つずつループ処理します
For Each swComp In vComponents
‘ コンポーネントのインスタンス名とファイルパスをイミディエイトウィンドウに出力します
Debug.Print swComp.Name2 & ” (” & swComp.PathName & “)”
Next swComp

Debug.Print “——————————————————–”
Debug.Print “処理が完了しました。”
Debug.Print “——————————————————–”

End Sub

3. コードの解説

一つずつ、コードの意味を見ていきましょう。

ステップ1: SOLIDWORKSアプリケーションへの接続とドキュメントの取得

Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssy As SldWorks.AssemblyDoc

Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc

If swModel Is Nothing Then ‘ …エラーチェック
If swModel.GetType <> swDocumentTypes_e.swDocAssembly Then ‘ …エラーチェック

Set swAssy = swModel ‘ 型変換

  • `Dim` ステートメントで、必要なオブジェクト変数を宣言しています。
  • `swApp`: SOLIDWORKSアプリケーションそのものを表す最上位オブジェクトです。
  • `swModel`: 現在開いているドキュメント(部品、アセンブリ、図面いずれか)を表す汎用的なオブジェクトです。
  • `swAssy`: アセンブリドキュメントに特化したオブジェクトです。
  • `Set swApp = Application.SldWorks` で、現在実行中のSOLIDWORKSインスタンスに接続します。これはVBAからSOLIDWORKSを操作するための出発点です。
  • `Set swModel = swApp.ActiveDoc` で、SOLIDWORKSで現在アクティブになっているドキュメントを取得します。
  • 重要なのは、その後のエラーチェックです。
  • `If swModel Is Nothing Then`: ドキュメントが一つも開かれていない場合、`swModel`は`Nothing`になります。これをチェックして、エラーを避けます。
  • `If swModel.GetType <> swDocumentTypes_e.swDocAssembly Then`: 開いているドキュメントがアセンブリではない場合(例えば、部品や図面の場合)も処理を中断します。`GetType`メソッドはドキュメントの種類を返します。
  • `Set swAssy = swModel`: ここがポイントです!`swModel`は汎用的な`ModelDoc2`型ですが、アセンブリ固有の操作を行うためには、`AssemblyDoc`型として扱う必要があります。SOLIDWORKS APIでは、このように上位の型から下位の型へ「型変換」(正確にはインターフェースの再割り当て)を行うことがよくあります。これにより、`swAssy`変数を通じてアセンブリ特有の機能(例: コンポーネントの取得)にアクセスできるようになります。

ステップ2: アセンブリ内の全コンポーネントを取得

Dim vComponents As Variant
Dim swComp As SldWorks.Component2

vComponents = swAssy.GetComponents(True)

If IsEmpty(vComponents) Then ‘ …エラーチェック

  • `Dim vComponents As Variant`: ここで`Variant`型を使っているのは、`GetComponents`メソッドがコンポーネントの配列を返すためです。`Variant`型は、様々なデータ型(この場合はオブジェクトの配列)を格納できます。
  • `Dim swComp As SldWorks.Component2`: 後でループ処理を行う際に、配列から取り出される各コンポーネントを一時的に格納するための変数です。
  • `vComponents = swAssy.GetComponents(True)`: ここが核心です! `AssemblyDoc`オブジェクトの`GetComponents`メソッドを呼び出して、アセンブリ内のすべてのコンポーネントを取得します。
  • 引数に`True`を指定すると、非表示や抑制されているコンポーネントも含めて、アセンブリ内の全てのコンポーネントが取得されます。`False`にすると、表示されているコンポーネントのみが対象になります。
  • `If IsEmpty(vComponents) Then`: コンポーネントが一つもない空のアセンブリの場合に備えて、配列が空ではないかチェックします。

ステップ3: 各コンポーネントの情報を取得してイミディエイトウィンドウに出力

Debug.Print “——————————————————–”
‘ …ヘッダー出力

For Each swComp In vComponents
Debug.Print swComp.Name2 & ” (” & swComp.PathName & “)”
Next swComp

‘ …フッター出力

  • `Debug.Print` は、VBAエディタの「イミディエイトウィンドウ」にテキストを出力するための命令です。プログラムのデバッグや、今回のように情報をリストアップする際に非常に便利です。
  • `For Each swComp In vComponents … Next swComp`: これは、配列`vComponents`の要素を最初から最後まで一つずつ順番に取り出し、`swComp`変数に代入しながらループ処理を行うための構文です。SOLIDWORKS APIで複数のオブジェクトを扱う際によく使われる非常に強力なループです。
  • ループの中で、`swComp.Name2`と`swComp.PathName`を使って、各コンポーネントのインスタンス名とファイルパスを取得し、それらを`Debug.Print`でイミディエイトウィンドウに出力しています。

—

コードの実行方法と結果の確認

1. アセンブリを開く: SOLIDWORKSで、適当なアセンブリドキュメントを開いてください。
2. VBAエディタに戻る: 先ほど開いたVBAエディタに戻ります。
3. イミディエイトウィンドウを表示: VBAエディタのメニューバーから `表示(V)` -> `イミディエイトウィンドウ(I)` を選択してください。通常、VBAエディタの下部に白いウィンドウが表示されます。
4. マクロを実行: VBAエディタのツールバーにある `実行` ボタン(緑色の再生マーク)をクリックするか、`F5` キーを押します。`GetAllComponentInfo`というマクロが選択されていることを確認して実行してください。

正しく実行されると、イミディエイトウィンドウに以下のような形式で、アセンブリ内の全コンポーネントの情報が出力されます。

——————————————————–
アセンブリ名: MyAssembly.SLDASM
——————————————————–
インスタンス名 (ファイルパス)
——————————————————–
Part1<1> (C:\Users\Public\Documents\SOLIDWORKS\Samples\tutorial\api\assembly\Part1.SLDPRT)
Part2<1> (C:\Users\Public\Documents\SOLIDWORKS\Samples\tutorial\api\assembly\Part2.SLDPRT)
SubAssembly<1> (C:\Users\Public\Documents\SOLIDWORKS\Samples\tutorial\api\assembly\SubAssembly.SLDASM)
-> Part3<1> (C:\Users\Public\Documents\SOLIDWORKS\Samples\tutorial\api\assembly\Part3.SLDPRT)
-> Part4<1> (C:\Users\Public\Documents\SOLIDWORKS\Samples\tutorial\api\assembly\Part4.SLDPRT)
——————————————————–
処理が完了しました。
——————————————————–

注: 上記の出力例では、サブアセンブリ内のコンポーネントはインデントして表示していますが、今回のコードではトップレベルのコンポーネント(サブアセンブリ自体も含む)のみを走査しています。サブアセンブリの内部まで走査するには、再帰処理が必要になりますが、それはまた別の機会に!

—

ここがポイント!一歩先の理解

今回のコードはシンプルに見えますが、SOLIDWORKS APIを扱う上で非常に重要な概念が詰まっています。

1. `GetComponents`と`EnumComponents`、そしてパフォーマンス

今回は`GetComponents`メソッドを使って、アセンブリ内のすべてのコンポーネントを一度に配列として取得しました。これは、コンポーネントの数がそれほど多くないアセンブリであれば非常に効率的で分かりやすい方法です。
しかし、数千、数万というコンポーネントを持つ大規模なアセンブリを扱う場合、一度にすべてのオブジェクトをメモリ上にロードする`GetComponents`は、パフォーマンスのボトルネックになる可能性があります。

そのような「極限」の状況では、`IAssemblyDoc.EnumComponents`というメソッドを使うことがあります。これは、コンポーネントを配列として一括で返すのではなく、コンポーネントを一つずつ順に列挙する「列挙子(Enumerator)」を返すメソッドです。これにより、必要なコンポーネントのオブジェクトだけをメモリにロードし、不要になったらすぐに解放するといった、よりメモリ効率の良い処理が可能になります。
初心者の方が最初からそこまで意識する必要はありませんが、SOLIDWORKS APIには、状況に応じて最適な方法を選ぶための選択肢が用意されている、ということを心の片隅に置いておくと、将来的に役立つでしょう。オブジェクトのライフサイクルとメモリ管理は、大規模な自動化を考える上で避けては通れない道なのです。

2. オブジェクト変数と`Nothing`の重要性

コードの冒頭で何度も`If swModel Is Nothing Then`のようなチェックを行いましたね。これは、オブジェクト変数が「何も参照していない状態」である`Nothing`ではないことを確認する、非常に重要な処理です。
SOLIDWORKS APIのメソッドは、期待通りのオブジェクトを返せない場合(例: ドキュメントが開いていない、指定したフィーチャーが見つからないなど)に`Nothing`を返すことがよくあります。この`Nothing`のままオブジェクトのプロパティやメソッドにアクセスしようとすると、VBAは「オブジェクト変数またはWithブロック変数が設定されていません。」という実行時エラーを発生させます。
これは、初心者が最も頻繁に遭遇するエラーの一つです。オブジェクトを扱う際には、必ずそのオブジェクトが正しく取得できているか(`Nothing`ではないか)をチェックする習慣をつけましょう。これにより、堅牢で安定したマクロを作成できます。

—

よくある落とし穴と解決策

  • 「実行時エラー ’91’: オブジェクト変数またはWithブロック変数が設定されていません。」
  • 原因: 最も多いのは、`swApp.ActiveDoc`が`Nothing`を返したにもかかわらず、その後のコードで`swModel`のプロパティにアクセスしようとした場合です。または、アクティブなドキュメントがアセンブリでなかったために、`swAssy`が正しく設定されなかった場合も考えられます。
  • 解決策: 上記コードにあるように、`swModel Is Nothing` や `swModel.GetType` で、オブジェクトが正しく取得できているか、また期待する種類のドキュメントであるかを必ずチェックしましょう。
  • VBAエディタで「参照設定エラー」が表示される
  • 原因: SOLIDWORKSのタイプライブラリへの参照が正しく設定されていない可能性があります。
  • 解決策: VBAエディタのメニューバーから `ツール(T)` -> `参照設定(R)…` を選択します。表示されるダイアログで、`SOLIDWORKS Type Library` と `SOLIDWORKS Constant Type Library` にチェックが入っていることを確認してください。もし見つからない場合は、`参照(B)…` ボタンからSOLIDWORKSのインストールフォルダ(通常 `C:\Program Files\SOLIDWORKS Corp\SOLIDWORKS`)を探し、`SldWorks.dll` と `swconst.dll` を手動で選択します。

—

まとめと次のステップ

今回は、SOLIDWORKS VBAを使ってアセンブリ内の全コンポーネントのインスタンス名とファイルパスをイミディエイトウィンドウに出力する方法を学びました。

  • `SldWorks.SldWorks`でSOLIDWORKSアプリケーションに接続
  • `ModelDoc2`から`AssemblyDoc`への型変換
  • `IAssemblyDoc.GetComponents`で全コンポーネントを配列として取得
  • `For Each`ループと`IComponent2`オブジェクトの`Name2`、`PathName`プロパティで情報を取得し、`Debug.Print`で出力

この知識は、SOLIDWORKS VBAを使いこなす上でのまさに「基礎の基礎」であり、ここをクリアすれば、あなたはSOLIDWORKS APIの基本をバッチリ掌握したと言えるでしょう。

次のステップとしては、

  • 特定のファイルパスを持つコンポーネントだけを抽出する
  • コンポーネントの表示状態(非表示/表示)を切り替える
  • 特定のカスタムプロパティ値を取得・設定する

といった応用へと進んでみてください。今回の基礎が、きっとあなたの強力な武器となるはずです。

これからもSOLIDWORKS VBAの知見を深めて、皆さんの業務がよりスムーズに、より創造的になるよう、お手伝いできれば幸いです。頑張ってください!

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