こんにちは!SolidWorksの自動化の世界へようこそ。
これまで「マクロの記録」ボタンを押して生成されたコードを繋ぎ合わせたり、グローバル変数があちこち飛び交うスパゲッティ状のVBAコードに頭を悩ませたりしていませんか?
「動くには動くけれど、部品の構成を変えた途端にエラーが出る……」
「どこを直したらいいのか自分でも分からない……」
そんなレガシーな開発スタイルから脱却し、「保守性・拡張性・再利用性」を極限まで高めたモダンなアセンブリ自動化フレームワークへ移行するための手法を、今日はたっぷりとお伝えします。
ここをクリアすれば、あなたも単なる「マクロ記録の使い手」から、設計意図をコードで完全にコントロールする「真のSolidWorks自動化エンジニア」への階段を確実に登ることができますよ。温かく導きますので、一緒に一歩ずつ進んでいきましょう!
—
1. なぜレガシーなVBAコードは破綻するのか?
従来のVBAマクロにありがちなアンチパターンを見てみましょう。
- すべての処理がひとつの巨大な `Sub` プロシージャに書かれている(1000行超えの怪物コード)。
- `SldWorks.ModelDoc2` や `SldWorks.AssemblyDoc` が至る所でグローバルに取得され、どれがどのドキュメントを指しているか分からない。
- エラーハンドリングが適当で、合致(Mate)の失敗時にSolidWorksごとフリーズする。
これでは、少し仕様が変わっただけでコード全体を書き直す羽目になります。ここで導入するのが 「クラスモジュール(Class Module)」 を使ったオブジェクト指向アプローチです。
アセンブリ自動化におけるオブジェクト指向とは、「部品(コンポーネント)」や「合致(メイト)」をひとつの『モノ(オブジェクト)』としてカプセル化することに他なりません。
—
2. フレームワーク全体の設計思想
今回構築する「アセンブリ自動化フレームワーク」は、以下の3層構造(レイヤー)で設計します。
1. エントリーポイント(標準モジュール): ユーザーからの実行を受け付け、全体のフローを制御する。
2. ビジネスロジック(クラスモジュール): アセンブリの生成、部品の挿入、合致の定義といった「振る舞い」をカプセル化する。
3. ラッパー・ユーティリティ: SolidWorks APIの煩雑なエラー処理や型変換を隠蔽する。
今回は、この中核を担う「アセンブリビルダー・クラス」と「合致マネージャー・クラス」の実装に焦点を当てます。
—
3. 実践!モダン・リファクタリングコード
お待たせしました。ここからが本番です。
開発環境(VBAエディタ)を開き、標準モジュールに加えてクラスモジュールを新しく追加してください。
ステップ1: コンポーネント操作を抽象化するクラスの作成
クラスモジュール名を `ClsAssemblyBuilder` とします。このクラスに、アセンブリの新規作成と部品配置の責任を持たせます。
‘ =================================================================
‘ クラス名: ClsAssemblyBuilder
‘ 概要: アセンブリの新規作成と構成部品の挿入をカプセル化するクラス
‘ =================================================================
Option Explicit
Private swApp As SldWorks.SldWorks
Private swModel As SldWorks.ModelDoc2
Private swAssy As SldWorks.AssemblyDoc
‘ イニシャライザ(クラス生成時に呼ばれる)
Private Sub Class_Initialize()
Set swApp = Application.SldWorks
End Sub
‘ アセンブリを新規作成するメソッド
Public Function CreateNewAssembly() As Boolean
On Error GoTo ErrorHandler
‘ 空白のアセンブリテンプレートを指定して新規作成
‘ ※環境に合わせてテンプレートパスを調整してください
Set swModel = swApp.NewDocument(“”, 2, 0, 0) ‘ 2 = アセンブリドキュメントの一般的なタイプ
If swModel Is Nothing Then
MsgBox “アセンブリの新規作成に失敗しました。”, vbCritical
CreateNewAssembly = False
Exit Function
End If
Set swAssy = swModel
CreateNewAssembly = True
Exit Function
ErrorHandler:
MsgBox “CreateNewAssemblyでエラーが発生しました: ” & Err.Description, vbCritical
CreateNewAssembly = False
End Function
‘ 指定した部品をアセンブリに挿入するメソッド
Public Function InsertComponent(ByVal fullPath As String, ByVal x As Double, ByVal y As Double, ByVal z As Double) As SldWorks.Component2
On Error GoTo ErrorHandler
Dim swComp As SldWorks.Component2
Dim transform As SldWorks.MathTransform
If swAssy Is Nothing Then
MsgBox “アセンブリが初期化されていません。”, vbExclamation
Exit Function
End If
‘ 部品をアセンブリ内に配置
Set swComp = swAssy.AddComponent5(fullPath, 0, “”, False, “”, x, y, z)
If swComp Is Nothing Then
MsgBox “部品の挿入に失敗しました: ” & fullPath, vbExclamation
End If
Set InsertComponent = swComp
Exit Function
ErrorHandler:
MsgBox “InsertComponentでエラーが発生しました: ” & Err.Description, vbCritical
Set InsertComponent = Nothing
End Function
‘ 外部からモデルを取得するためのプロパティ
Public Property Get ModelDoc() As SldWorks.ModelDoc2
Set ModelDoc = swModel
End Property
ステップ2: 難解な合致(Mate)処理をエレガントに隠蔽する
次に、合致(Mate)の定義をカプセル化するクラス `ClsMateManager` を作成します。SolidWorksの合致API(`AddMate5` など)は引数が非常に多く、レガシーコードではバグの温床になりがちです。ここをスマートにラップしましょう。
‘ =================================================================
‘ クラス名: ClsMateManager
‘ 概要: 面やエッジ同士の合致関係を安全に定義するクラス
‘ =================================================================
Option Explicit
Private swModel As SldWorks.ModelDoc2
‘ 参照するドキュメントをセット
Public Sub Initialize(ByVal model As SldWorks.ModelDoc2)
Set swModel = model
End Sub
‘ 一致(Coincident)合致を直感的に定義するメソッド
Public Function AddCoincidentMate(ByVal entityName1 As String, ByVal entityName2 As String) As Boolean
On Error GoTo ErrorHandler
If swModel Is Nothing Then Exit Function
‘ 選択クリア
swModel.ClearSelection2 True
‘ 注意: 実務ではエンティティ名やセレクションマークを使った確実な選択ロジックをここに記述します
‘ ここではフレームワークの構造を示すため、簡略化した概念コードを記載しています。
Dim mateRet As Long
mateRet = swModel.AddMate3(1, 0, False, 0, 0, 0, 0, 0, 0, 0, 0, False, 0)
‘ ※ 実際のAPI(AddMate5等)では適切な引数とエラーハンドリングが必要です
AddCoincidentMate = (mateRet = 0) ‘ 0なら成功などのステータス判定
Exit Function
ErrorHandler:
MsgBox “AddCoincidentMateでエラーが発生しました: ” & Err.Description, vbCritical
AddCoincidentMate = False
End Function
ステップ3: 標準モジュールからの優雅な呼び出し
フレームワークの準備ができたら、実行用の標準モジュール(例: `MainModule`)はこれだけスッキリと書けるようになります。これがオブジェクト指向の醍醐味です!
‘ =================================================================
‘ 標準モジュール: MainModule
‘ 概要: フレームワークを利用してアセンブリを構築するエントリーポイント
‘ =================================================================
Option Explicit
Sub BuildMyAssemblyFramework()
‘ 1. アセンブリビルダーのインスタンス化
Dim assyBuilder As New ClsAssemblyBuilder
‘ 2. アセンブリの新規作成
If Not assyBuilder.CreateNewAssembly() Then Exit Sub
‘ 3. 部品の動的配置(パスはご自身の環境に合わせて変更してください)
Dim basePartPath As String
Dim boltPartPath As String
basePartPath = “C:\CADData\BasePlate.sldprt”
boltPartPath = “C:\CADData\HexBolt.sldprt”
Dim baseComp As SldWorks.Component2
Dim boltComp As SldWorks.Component2
Set baseComp = assyBuilder.InsertComponent(basePartPath, 0, 0, 0)
Set boltComp = assyBuilder.InsertComponent(boltPartPath, 0, 0, 50)
‘ 4. 合致マネージャーによる関係性の定義
Dim mateManager As New ClsMateManager
mateManager.Initialize assyBuilder.ModelDoc
‘ ここで定義したメソッドを呼び出して合致を組む
‘ mateManager.AddCoincidentMate “Face1@BasePlate”, “Face1@HexBolt”
MsgBox “アセンブリの自動構築が正常に完了しました!”, vbInformation
End Sub
—
4. 陥りやすいエラーと回避の極意
ここまでのコードを実装するにあたり、SolidWorks API特有の「罠」にいくつか注意する必要があります。
1. 選択のクリア忘れ (`ClearSelection2`)
- 現象: 前の処理で選択されていたエンティティが残り続け、意図しない場所が合致されてしまう。
- 対策: APIを呼ぶ前、および選択操作の前後には必ず `swModel.ClearSelection2 True` を挟む習慣をつけましょう。
2. コンポーネントの外部参照切れ
- 現象: 挿入する部品のファイルパスが間違っていると、`AddComponent5` が `Nothing` を返し、その後の処理でヌルポインタ例外(オブジェクト変数が設定されていません)が発生する。
- 対策: クラス側で必ず `If swComp Is Nothing Then` のガード節を設け、どのファイルでロードに失敗したかをログに出力させます。
—
まとめ:ここをクリアすれば、基本はバッチリ!
いかがでしたでしょうか?
今回は、レガシーなVBAプロシージャをクラスモジュールベースの「アセンブリ自動化フレームワーク」へリファクタリングする手法を解説しました。
- 「手続きの羅列」から「オブジェクトの協調」への頭の切り替え
- 処理の責任をクラスごとに分割する(カプセル化)
- エラーや複雑なAPIを内部に隠蔽する
この3つを意識するだけで、あなたの書くSolidWorks VBAコードの品質は見違えるほど劇的に向上します。「動けばいいや」のコードから卒業し、拡張性に満ちた美しい自動化ライフを今日から始めましょう。
ここをクリアできれば、あなたのSolidWorks VBAスキルは間違いなく中級者から「上級プロ」の領域に達しています。ぜひ、ご自身のプロジェクトでも試してみてくださいね!
