【入門編】【上級プロ】クラスモジュールを活用した「アセンブリ合致ビルダー」のオブジェクト指向設計:保守性の高い再利用可能なVBAライブラリの構築 – SolidWorks VBA解析バイブル

スポンサーリンク

こんにちは!SolidWorksの自動化の世界へようこそ。
マクロの記録ボタンを押して生成されたコードを眺めて、「なんだか同じような処理がズラリと並んでいて、後から修正するのが大変だな…」と感じたことはありませんか?

特にアセンブリの合致(Mate)定義は厄介です。部品が増えれば増えるほどコードが縦に長くなり、どの部品とどの面が結びついているのか、後から見るとまるで暗号のようになってしまいますよね。

今回は、そんな地獄のようなコードから抜け出し、「まるで専用の洗練されたAPIを使っているかのように」直感的にアセンブリを組み立てられるクラスモジュールを使ったオブジェクト指向設計の世界へあなたをご案内します。

ここをクリアすれば、あなたのVBAスキルは間違いなくプロの領域に到達します。一緒にスマートな設計手法をマスターしていきましょう!

—

なぜ、アセンブリの合致コードはスパゲッティ化するのか?

標準的なマクロの記録で合致を作ると、以下のようなコードが生成されます。

‘ 標準マクロの記録が吐き出すコードのイメージ
Dim boolstatus As Boolean
boolstatus = swModel.Extension.SelectByID2(“Face1@Part1-1”, “FACE”, 0, 0, 0, True, 1, Nothing, 0)
boolstatus = swModel.Extension.SelectByID2(“Face2@Part2-1”, “FACE”, 0, 0, 0, True, 1, Nothing, 0)
Dim swMate As SldWorks.Mate2
Set swMate = swModel.AddMate3(0, 0, False, 0, 0, 0, 0, 0, 0, 0, 0, False, boolstatus)

これを数十回繰り返すとどうなるでしょう?

  • 面の名前(`Face1@Part1-1` など)が変わっただけでエラーが爆発する。
  • 「どの部品とどの部品をどう固定したっけ?」という全体像が追えない。
  • メンテナンスしようにも、どこを触ればいいか分からない(通称:スパゲッティコード)。

これを解決するのが、「クラスモジュール」によるカプセル化と「メソッドチェーン」という設計思想です。

—

究極の解決策:アセンブリ合致ビルダーの設計

今回作成するのは、`AssemblyBuilder` というカスタムオブジェクトです。
これを使うと、実際のVBAコードは以下のように書けるようになります。

‘ 【将来的な理想のコード:これが書けるようになります!】
Dim builder As New AssemblyBuilder
builder.Initialize “C:\Assemblies\MyAssembly.sldasm”

‘ 部品を配置して、流れるようなメソッドチェーンで合致を定義
builder.AddPart(“Base”, “C:\Parts\base.sldprt”, 0, 0, 0) _
.AddPart(“Cover”, “C:\Parts\cover.sldprt”, 0, 0, 100) _
.AddMate(“Cover”, “TopFace”, “Base”, “BottomFace”, swMateType_Concentric) _
.SaveAndClose;

どうですか?英語の文章を読むかのように、何をやっているのかが一目瞭然ですよね。この夢のような仕組みを、一緒に実装していきましょう。

—

ステップ1:クラスモジュールの作成(心臓部の実装)

それでは、SolidWorksのVBAエディタ(VBE)を開いて作業を始めます。

1. VBEのメニューから `[挿入]` > `[クラス モジュール]` をクリックします。
2. プロパティウィンドウで、このクラスの名称(オブジェクト名)を `AssemblyBuilder` に変更します。

ここに、SolidWorksのAPI(`SldWorks.ModelDoc2` や `SldWorks.AssemblyDoc`)を操作するロジックをすべて閉じ込めます(カプセル化)。

以下のコードを `AssemblyBuilder` クラスの中に貼り付けてください。

‘ ==========================================
‘ クラス名: AssemblyBuilder
‘ 概要: アセンブリの新規作成と合致定義をカプセル化するビルダー
‘ ==========================================
Option Explicit

Private swApp As SldWorks.SldWorks
Private swModel As SldWorks.ModelDoc2
Private swAssm As SldWorks.AssemblyDoc

‘ 1. 初期化:アセンブリを新規作成する
Public Sub Initialize()
Set swApp = CreateObject(“SldWorks.Application”)
‘ 空の新規アセンブリを作成 (テンプレートは標準のものを使用)
Set swModel = swApp.NewDocument(“”, 2, 0, 0) ‘ 2 = アセンブリテンプレートの一般的なインデックス
Set swAssm = swModel
End Sub

‘ 2. 部品を配置するメソッド(自分自身(Me)を返すことでメソッドチェーンを実現!)
Public Function AddPart(ByVal componentName As String, ByVal filePath As String, ByVal x As Double, ByVal y As Double, ByVal z As Double) As AssemblyBuilder
Dim swComp As SldWorks.Component2
Dim transform As SldWorks.MathTransform

‘ コンポーネントの挿入
Set swComp = swAssm.AddComponent5(filePath, 0, “”, False, “”, x, y, z)

If swComp Is Nothing Then
MsgBox “部品の挿入に失敗しました: ” & filePath, vbCritical
End If

‘ メソッドチェーンをつなぐために「自分自身」を返す
Set AddPart = Me
End Function

‘ 3. 2つの部品の面を合致させるメソッド
Public Function AddMate(ByVal compName1 As String, ByVal faceName1 As String, ByVal compName2 As String, ByVal faceName2 As String, ByVal mateType As Long) As AssemblyBuilder
Dim boolstatus As Boolean

‘ 面の選択(選択バッファのクリアを忘れずに!)
swModel.ClearSelection2 True

‘ 1つ目の面の選択
boolstatus = swModel.Extension.SelectByID2(faceName1 & “@” & compName1, “FACE”, 0, 0, 0, True, 1, Nothing, 0)
‘ 2つ目の面の選択
boolstatus = swModel.Extension.SelectByID2(faceName2 & “@” & compName2, “FACE”, 0, 0, 0, True, 1, Nothing, 0)

‘ 合致の実行 (swMateType_Concentric = 同心円, swMateType_Coincident = 一致 など)
Dim swMate As SldWorks.Mate2
Set swMate = swModel.AddMate3(mateType, 0, False, 0, 0, 0, 0, 0, 0, 0, 0, False, boolstatus)

swModel.ClearSelection2 True

‘ こちらも自分自身を返す
Set AddMate = Me
End Function

💡 ここがエンジニアの知見:メソッドチェーンのカラクリ

`Function` の戻り値に `As AssemblyBuilder` を指定し、最後に `Set AddMate = Me` と書いています。これで、`.AddPart().AddMate().AddMate()` のように、ドットつなぎで連続して命令を実行できるようになります。これがVBAを劇的にモダンにする秘訣です。

—

ステップ2:標準モジュールから呼び出す

クラスの準備ができたら、次は通常の標準モジュール(`Module1` など)から、このビルダーを呼び出してみましょう。

‘ ==========================================
‘ 標準モジュール: MainModule
‘ ==========================================
Option Explicit

Sub RunAssemblyAutomation()
‘ ビルダーのインスタンスを生成
Dim builder As New AssemblyBuilder

‘ 1. アセンブリの新規作成
builder.Initialize

‘ 2. 部品の配置 (※実際のファイルパスに書き換えてください)
‘ ※あらかじめC:\Temp\などに適当な部品を用意しておいてください
builder.AddPart(“BasePart”, “C:\Temp\Base.sldprt”, 0, 0, 0) _
.AddPart(“PinPart”, “C:\Temp\Pin.sldprt”, 0, 0, 0)

‘ 3. 合致の定義(例:円柱面同士の同心円合致)
‘ ※モデル上の実際の面名( CylFace1 など)に合わせてください
‘ builder.AddMate “PinPart”, “CylFace1”, “BasePart”, “CylFace2”, 1 ‘ 1 = 同心円(Concentric)

MsgBox “アセンブリの自動構築が完了しました!”, vbInformation
End Sub

—

陥りやすいエラーと回避の極意

SolidWorks APIを扱う上で、初心者が必ずハマる「罠」がいくつかあります。これを知っておくだけで、無駄なデバッグ時間を何時間も節約できます。

1. 選択バッファのゴミ問題 (`ClearSelection2`)

  • 症状: 2つ目の面を選ぼうとしたとき、なぜか1つ目の選択が解除されたり、予期せぬジオメトリが選択されて合致エラーになる。
  • 原因: SolidWorksは選択状態をメモリ(選択リスト)に保持し続けます。前の処理の選択が残ったまま次の `SelectByID2` を実行すると、意図しないマルチセレクトになってしまいます。
  • 対策: クラスコード内にも書いた通り、処理の最初と最後には必ず `swModel.ClearSelection2 True` を挟むことを鉄則にしてください。

2. 面の名前(ComponentName@PartName)の不一致

  • 症状: `SelectByID2` が `False` を返し、面が選択できない。
  • 原因: 画面上のフィーチャー名(例:「ボス-押し出し1」など)ではなく、APIが認識している内部的な面名(Face1, Face2…)や、アセンブリ内でのインスタンス名(`Part1-1`)を指定する必要があります。
  • 対策: 最初は、マクロの記録機能を使ってSolidWorksが生成する正しい文字列を確認し、それをクラスへ渡す引数として設計するようにしましょう。

—

まとめ:保守性の高いVBAライブラリへ向けて

今回は、クラスモジュールを活用した「アセンブリ合致ビルダー」の設計手法について解説しました。

  • スパゲッティコードの排除: 複雑なAPI呼び出しをクラスの中に隠蔽(カプセル化)する。
  • 直感的な操作性: メソッドチェーンを用いて、流れるようなコード記述を実現する。
  • 安定性の確保: 選択バッファのクリアなど、SolidWorks特有のクセをクラス内で吸収する。

この設計手法をマスターすれば、あなたの書くマクロは単なる「その場しのぎの自動化スクリプト」から、チームで使い回せる「堅牢なエンジニアリング・ライブラリ」へと生まれ変わります。

ここをクリアしたあなたなら、もうSolidWorks VBAの基本はバッチリです!ぜひ自分の環境でも試して、このスマートな記述の心地よさを体感してみてくださいね。それでは、次回の高度な自動化の世界でお会いしましょう!

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