【入門編】【上級プロ向け】レガシーSolidWorks APIバージョン差異(2018〜2024+)を動的バインディングで完全に吸収するラッパー – SolidWorks VBA解析バイブル

スポンサーリンク
スポンサーリンク

「マクロの記録」を卒業しよう。SolidWorks APIのバージョン差異を支配する、プロフェッショナルのための動的バインディング戦略

こんにちは。現場で自動化ツールを設計しているエンジニアの皆さん、今日も設計業務の効率化に奮闘していますね。

「マクロの記録」ボタンを押し、書き出されたコードを少しずつ書き換えていく……。これは素晴らしい第一歩です。でも、もしあなたが「自分の作ったツールが、隣の席の人の(バージョンの違う)SolidWorksで動かない!」という問題に直面したなら、それはあなたが「エンジニア」から「アーキテクト(設計者)」へと進化すべきタイミングが来たことを意味しています。

今日は、多くの初級者が陥る「参照設定の罠」を回避し、2018年から最新の2024以降まで、あらゆるSolidWorks環境で安定稼働させるための「動的バインディングを用いたラッパー構造」について、その極意を伝授します。

ここをクリアすれば、あなたの作るツールは「壊れにくい、プロの道具」へと昇華しますよ。

1. なぜ、あなたのマクロは「バージョン違い」に弱いのか?

まず、敵を知ることから始めましょう。SolidWorks VBAには、大きく分けて2つの「繋ぎ方(バインディング)」があります。

① 参照設定を使う「事前バインディング (Early Binding)」

マクロの画面の [ツール] → [参照設定] で `SldWorks 20XX Type Library` にチェックを入れる方法です。

  • メリット: コードを書いている最中に「入力候補(インテリセンス)」が出るので、開発が非常に楽。動作も高速。
  • デメリット: バージョンの壁にぶち当たる。 2024で開発したツールを2018の環境で動かそうとすると、「参照不可」のエラーが出て、実行すらできません。

② 参照設定を使わない「事後バインディング (Late Binding)」

すべてのオブジェクトを `Object` 型として宣言する方法です。

  • メリット: 参照設定が不要。SolidWorksのバージョンが何であれ、実行時にその場でオブジェクトを探して繋ぎにいくため、エラーになりにくい。
  • デメリット: 入力候補が出ない。また、定数(`swDocDRAWING` など)が使えなくなる。

プロの現場では、この両方の「いいとこ取り」をした「ラッパー(包み紙)」を作ることが求められます。

2. 陥りやすい落とし穴:消えた「定数」の謎

事後バインディング(Late Binding)に移行しようとした初心者が必ず直面するエラーがあります。それは、「定数が定義されていません」というエラーです。

例えば、図面を開くコードを書こうとして、こう書いてしまう。

' 事前バインディングなら動くが、事後バインディングだとエラーになる例
Set swModel = swApp.OpenDoc6("C:\test.slddrw", swDocDRAWING, ...)

`swDocDRAWING` という言葉は、SolidWorksのライブラリの中に定義されている「定数」です。参照設定を外してしまうと、VBAは「`swDocDRAWING`って何のこと?」と戸惑ってしまいます。

これを解決するには、「自分自身で定数の値を定義しておく」か、「ラッパーの中で定数を管理する」必要があるのです。

3. 【実践】プロフェッショナル・ラッパーの実装

では、実際に「どのバージョンのSolidWorksでも動く、図面操作用ラッパー」を設計してみましょう。
ここでは、「クラスモジュール」という機能を使います。これが、複雑な処理を隠蔽し、メインのプログラムをスッキリさせる魔法の箱になります。

ステップ1:クラスモジュールの作成

VBAエディタで [挿入] → [クラスモジュール] を選択し、名前を `clsSWManager` に変更してください。

' --- クラス名: clsSWManager ---
Option Explicit

' 参照設定を使わないため、定数を自前で定義する(ここがプロの仕事!)
' これにより、どのバージョンのSolidWorksでもこの値が共通して使える
Public Const swDocDRAWING As Long = 3
Public Const swDocPART As Long = 1
Public Const swDocASSEMBLY As Long = 2

Private pSwApp As Object ' SolidWorks Applicationを保持

' --- SolidWorksへの接続を確立するメソッド ---
Public Function Connect() As Boolean
    Dim swApp As Object
    On Error Resume Next
    ' 既に起動しているSolidWorksを取得
    Set swApp = GetObject(, "SldWorks.Application")
    
    If swApp Is Nothing Then
        ' 起動していなければ、新しく起動を試みる
        Set swApp = CreateObject("SldWorks.Application")
    End If
    On Error GoTo 0
    
    If Not swApp Is Nothing Then
        Set pSwApp = swApp
        pSwApp.Visible = True
        Connect = True
    Else
        Connect = False
    End If
End Function

' --- 図面ファイルを開くラッパーメソッド ---
' バージョンによるAPIの微妙な挙動の違いを、この中で吸収する
Public Function OpenDrawing(filePath As String) As Object
    Dim swModel As Object
    If pSwApp Is Nothing Then Exit Function
    
    ' OpenDoc6 メソッドを動的呼び出し
    ' 引数: ファイル名, 型, オプション, 設定, エラーコード, 通知
    ' ※事後バインディングなので、引数はすべて型を意識して渡す
    Set swModel = pSwApp.OpenDoc6(filePath, swDocDRAWING, 0, "", 0, 0)
    
    Set OpenDrawing = swModel
End Function

' --- プロパティ: SolidWorks Application本体へのアクセス ---
Public Property Get SwApp() As Object
    Set SwApp = pSwApp
End Property

ステップ2:メインプログラムからの呼び出し

次に、標準モジュールに実際の処理を書きます。見てください、メインのコードがどれほど「図面操作」という本質的な目的だけに集中できているかを。

' --- 標準モジュール ---
Option Explicit

Sub Main()
    Dim swMgr As New clsSWManager ' 自作したラッパーを呼び出す
    Dim swModel As Object
    Dim filePath As String
    
    filePath = "C:\Temp\MyDrawing.slddrw" ' テスト用のパス
    
    ' 1. SolidWorksへの接続(バージョン差異を気にせず実行!)
    Debug.Print "SolidWorksに接続中..."
    If Not swMgr.Connect() Then
        MsgBox "SolidWorksを起動できませんでした。", vbCritical
        Exit Sub
    End If
    
    ' 2. 図面を開く(ラッパー経由なので安全)
    Debug.Print "図面を開いています..."
    Set swModel = swMgr.OpenDrawing(filePath)
    
    If swModel Is Nothing Then
        MsgBox "図面を開けませんでした。パスを確認してください。", vbExclamation
        Exit Sub
    End If
    
    ' 3. ここから本来やりたい「図面操作」のロジック
    MsgBox "図面「" & swModel.GetTitle & "」の読み込みに成功しました!", vbInformation
    
    ' 後片付け(オブジェクトの解放)
    Set swModel = Nothing
    Set swMgr = Nothing
End Sub

4. なぜこの構造が「最強」なのか?(エンジニアの視点)

このコードが、なぜ単なる「マクロの記録」を超えているのか。その理由は3つあります。

① 疎結合(Loosely Coupled)

メインの `Main` サブルーチンは、SolidWorksがどうやって起動するか、定数が何番なのかを知る必要がありません。ただ `swMgr.Connect` を呼ぶだけ。もし将来、SolidWorksの起動方法が変わったとしても、修正するのは `clsSWManager` だけで済みます。

② 堅牢性(Robustness)

`OpenDoc6` のような重要なメソッドをクラス内に閉じ込めることで、エラーハンドリング(`On Error`)を一箇所に集約できます。これにより、予期せぬエラーでマクロが爆発するのを防ぎます。

③ 保守性(Maintainability)

「2024からAPIが変わって、図面シートの取得方法が変わった」という事態が起きたとき、あなたはクラスの中身を書き換えるだけで、既存のすべてのマクロを修正することなく、一括で対応可能になります。

最後に:一歩先へ進むあなたへ

「動的バインディングを使うと、少し動作が遅くなるのでは?」と心配する方もいるかもしれません。確かに、厳密な意味では、実行時にメソッドを探すコストがかかります。

しかし、考えてみてください。「0.01秒の速度」と「どのPCでも動く信頼性」、どちらが業務自動化において価値があるでしょうか?

多くの場合、後者です。

最初は、この「ラッパーを作る」という作業は面倒に感じるかもしれません。でも、一度この構造を手に入れれば、あなたはもう「バージョンエラーに怯える初心者」ではありません。環境に左右されない、真の自動化エンジニアです。

ここをクリアすれば、SolidWorks VBAの基本はバッチリですよ。さあ、自信を持って、次のコードを書き始めてください!

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