SolidWorks VBAマクロを「本物のアドイン」へ昇華させる! – 伝説のアーキテクトが紐解くCOMコンポーネントへの道
皆さん、こんにちは!SolidWorks VBAの深淵なる世界へようこそ。世界最高峰の業務自動化エンジニアとして、数々の自動化プロジェクトを成功に導いてきた私が、今回は皆さんのSolidWorks VBAスキルを次のレベルへと引き上げる、まさに「秘伝の技」をお伝えします。
「マクロの記録」から一歩踏み出し、SolidWorks起動時にリボンメニューに独自のボタンを配置し、常にそばであなたをサポートしてくれる「アドイン」を開発する。この壮大なステップに、ワクワクしませんか?
今回の記事では、VBAマクロの限界を超え、SolidWorksの力を最大限に引き出すアドイン開発への道筋を、初心者の方にも分かりやすく、そして経験者の方には「なるほど!」と思っていただけるような、本質的な解説と実践的なコード例を交えながら、魂を込めて紐解いていきます。
「ここをクリアすれば、SolidWorks VBAの基本はバッチリですよ」と、優しく、そして力強く、皆さんの背中を押させていただきます。さあ、伝説の始まりです!
1. なぜ「アドイン」なのか? VBAマクロとの決定的な違い
まず、なぜ私たちがVBAマクロの「その先」を目指すのか、その理由を明確にしましょう。
VBAマクロの限界:
- 実行の手間: 毎回マクロダイアログを開き、実行したいマクロを選択する手間がかかります。
- 常駐性の欠如: SolidWorksを起動しても、マクロは自動的に読み込まれません。
- UI統合の難しさ: リボンメニューにボタンを配置したり、独自のダイアログを洗練させたりするのが、VBA単体では非常に困難です。
- パフォーマンス: 大規模な処理や複雑な処理になると、実行速度や安定性に課題が生じることがあります。
アドイン(COMコンポーネント)の強み:
- 自動起動と常駐: SolidWorks起動時に自動的に読み込まれ、常に利用可能な状態になります。
- リボンメニューへの統合: 独自のボタンやタブをリボンメニューに配置し、直感的な操作を実現できます。
- 高度なUI/UX: カスタムダイアログやパネルを自由に設計し、ユーザーフレンドリーなインターフェースを提供できます。
- パフォーマンスと安定性: COMコンポーネントとして、より効率的で安定した処理が期待できます。
- 再利用性と保守性: コードが構造化され、他のアプリケーションとの連携も容易になります。
つまり、アドインは、単なる「自動化スクリプト」から、SolidWorksという強力なプラットフォームに「組み込まれた機能」へと進化させるための、まさに「本物」の形なのです。
2. アドイン開発への第一歩:COMコンポーネントの基礎知識
アドイン開発は、COM(Component Object Model)という技術に基づいています。難しそうに聞こえるかもしれませんが、基本的な考え方を理解すれば大丈夫です。
COMとは?
COMは、異なるプログラミング言語で書かれたコンポーネント同士が、互いに連携できるようにするためのMicrosoftの技術規格です。SolidWorksのアドインも、このCOMの仕組みを利用して、SolidWorks本体と通信しています。
COMコンポーネントの「正体」:
私たちが作成するアドインは、実際には「DLL(Dynamic Link Library)」や「EXE(実行ファイル)」といった形式の、COMに対応したプログラムファイルになります。SolidWorksは、このCOMコンポーネントを「呼び出して」機能を利用するのです。
VBAからCOMへ:言語の壁を越える
VBAマクロは、SolidWorksのVBAエディタ内で直接実行されます。一方、アドインは、VB.NETやC#といった、より強力な開発環境で作成されることが多いです。しかし、心配はいりません!COMの仕組みを理解することで、VBAからでも、あるいはVBAで培った知識を活かしてVB.NETなどへステップアップする道筋が見えてきます。
3. VBAマクロをアドイン化するための「思考プロセス」
さあ、いよいよ具体的なステップに入りましょう。ここでは、VBAマクロをアドイン化するための「考え方」を整理します。
3.1. マクロの「処理」を「機能」として切り出す
まずは、現在作成しているVBAマクロの「処理」を、独立した「機能」として捉え直すことが重要です。
例:
- 現在のマクロ: 「特定の部品を開き、寸法を修正し、図面を生成してPDFで保存する」
- アドイン化される機能:
- 「部品を開き、寸法を修正する機能」
- 「図面を生成する機能」
- 「PDFで保存する機能」
このように、処理を細かく分解し、それぞれの機能を独立したモジュールとして設計することで、後々、コードの再利用性や保守性が格段に向上します。
3.2. SolidWorks APIオブジェクトモデルとの対話方法を理解する
VBAマクロでは、`SldWorks`オブジェクトや`ModelDoc2`オブジェクトを直接参照して、SolidWorksの機能にアクセスしていました。アドイン開発でも、このAPIオブジェクトモデルとの「対話」は変わりません。
重要なオブジェクト:
- `SldWorks`: SolidWorksアプリケーション全体を表す、まさに「親玉」のようなオブジェクトです。アドインが最初に参照する対象となります。
- `ModelDoc2`: 開いているドキュメント(部品、アセンブリ、図面)を表します。
- `SelectionMgr`: 現在選択されているエンティティを取得するためのオブジェクトです。
APIの「呼び出し方」:
VBAマクロで `Application.ActiveDoc` と記述していたものが、アドインでは `swApp.ActiveDoc` のように、`SldWorks`オブジェクトのインスタンス(ここでは `swApp` とします)を介してアクセスする形になります。
3.3. COMアドインの「骨格」を理解する
COMアドインは、特定のインターフェースを実装する必要があります。最も基本的なのは `IConnect` インターフェースです。
`IConnect`インターフェースの役割:
- `OnConnection`: SolidWorksがアドインを読み込んだときに呼び出されます。ここで、リボンメニューにボタンを追加したり、初期設定を行ったりします。
- `OnDisconnection`: SolidWorksがアドインをアンロードするときに呼び出されます。ここで、リソースの解放など、後処理を行います。
この `OnConnection` イベントで、SolidWorksのUIにアクセスし、独自のボタンを配置していくことになります。
4. VBAマクロからVB.NETアドインへの「架け橋」 – 実践コード例
ここからは、実際にVBAマクロからVB.NETアドインへの移行をイメージするための、具体的なコード例を見ていきましょう。VB.NETは、VBAと文法が似ている部分も多く、VBAの知識がそのまま活かせます。
4.1. VBAマクロの例:「指定した寸法の値を変更する」
まずは、シンプルなVBAマクロの例です。
‘ VBAマクロ例: 特定の寸法値を変更する
Sub ChangeDimensionValue()
Dim swApp As Object ‘ SldWorks
Dim swModel As Object ‘ ModelDoc2
Dim swSelMgr As Object ‘ SelectionMgr
Dim swDimension As Object ‘ Dimension
Dim dimensionName As String
Dim newDimensionValue As Double
‘ SolidWorksアプリケーションオブジェクトを取得
Set swApp = Application.SldWorks
‘ アクティブなドキュメントを取得
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントがありません。”, vbExclamation
Exit Sub
End If
‘ 選択マネージャーを取得
Set swSelMgr = swModel.SelectionManager
‘ 選択されているエンティティを取得
Dim selectedObjects As Variant
selectedObjects = swSelMgr.GetSelectedObjects
‘ 選択されたオブジェクトが1つで、それが寸法であることを確認
If Not IsEmpty(selectedObjects) And UBound(selectedObjects) = 0 Then
Set swDimension = selectedObjects(0)
‘ オブジェクトが寸法かどうかをチェック (より厳密なチェックが必要な場合もあります)
If TypeName(swDimension) = “Dimension” Then
dimensionName = swDimension.GetName
newDimensionValue = InputBox(“新しい寸法値を入力してください (例: 50.5)”, “寸法値変更”, “50.5”)
If newDimensionValue <> 0 Then ‘ Cancelボタンでない場合
‘ 寸法値を変更 (単位系に注意)
‘ ここでの単位系は、SolidWorksの内部単位系に合わせる必要があります。
‘ 例えば、インチ系なら0.0393701、ミリ系なら1.0など。
‘ より安全なのは、SWの単位系を取得して計算することです。
Dim unitFactor As Double
unitFactor = GetSWUnitFactor(swModel) ‘ Helper function (後述)
If swDimension.SetValue2(newDimensionValue unitFactor) Then
swModel.ForceRebuild3 True ‘ 再構築
MsgBox dimensionName & ” の値を ” & newDimensionValue & ” に変更しました。”, vbInformation
Else
MsgBox “寸法の値を変更できませんでした。”, vbCritical
End If
End If
Else
MsgBox “選択されたオブジェクトは寸法ではありません。”, vbExclamation
End If
Else
MsgBox “変更したい寸法を1つだけ選択してください。”, vbExclamation
End If
Set swDimension = Nothing
Set swSelMgr = Nothing
Set swModel = Nothing
Set swApp = Nothing
End Sub
‘ SolidWorksの単位系に応じた係数を取得するヘルパー関数 (例)
Function GetSWUnitFactor(model As Object) As Double
Dim unit As Long
unit = model.Extension.GetUserPreferenceIntegerValue(swUserPreferenceIntegerValue_e.swUnitsLinear)
Select Case unit
Case swUnit_Millimeter: GetSWUnitFactor = 1.0
Case swUnit_Centimeter: GetSWUnitFactor = 10.0
Case swUnit_Meter: GetSWUnitFactor = 1000.0
Case swUnit_Inch: GetSWUnitFactor = 25.4 ‘ 1インチ = 25.4 mm
Case swUnit_Foot: GetSWUnitFactor = 25.4 12
‘ 他の単位系も必要に応じて追加
Case Else: GetSWUnitFactor = 1.0 ‘ デフォルトはmm
End Select
End Function
‘ — 定数定義 (VBAエディタで必要に応じて追加) —
‘ Private Const swUserPreferenceIntegerValue_e As Long = 13 ‘ Enum swUserPreferenceIntegerValue_e
‘ Private Const swUnitsLinear As Long = 1 ‘ Enum swLinearUnit_e
‘ Private Const swUnit_Millimeter As Long = 0
‘ Private Const swUnit_Centimeter As Long = 1
‘ Private Const swUnit_Meter As Long = 2
‘ Private Const swUnit_Inch As Long = 3
‘ Private Const swUnit_Foot As Long = 4
‘ Private Const swUnit_Kilometer As Long = 5
‘ Private Const swUnit_Mile As Long = 6
‘ Private Const swUnit_Micron As Long = 7
‘ Private Const swUnit_Nanometer As Long = 8
‘ Private Const swUnit_FootInch As Long = 9
‘ Private Const swUnit_Yard As Long = 10
‘ Private Const swUnit_MillimeterInch As Long = 11
‘ Private Const swUnit_Micrometer As Long = 12
‘ Private Const swUnit_Nanometer_Inch As Long = 13
‘ Private Const swUnit_Angstrom As Long = 14
‘ Private Const swUnit_Angstrom_Inch As Long = 15
‘ Private Const swUnit_Milliinch As Long = 16
‘ Private Const swUnit_Microinch As Long = 17
‘ Private Const swUnit_Nanoinch As Long = 18
‘ Private Const swUnit_Picometer As Long = 19
‘ Private Const swUnit_Picometer_Inch As Long = 20
‘ Private Const swUnit_Femtometer As Long = 21
‘ Private Const swUnit_Femtometer_Inch As Long = 22
‘ Private Const swUnit_Attometer As Long = 23
‘ Private Const swUnit_Attometer_Inch As Long = 24
‘ Private Const swUnit_Zeptometer As Long = 25
‘ Private Const swUnit_Zeptometer_Inch As Long = 26
‘ Private Const swUnit_Yoctometer As Long = 27
‘ Private Const swUnit_Yoctometer_Inch As Long = 28
‘ Private Const swUnit_Micrometer_Inch As Long = 29
‘ Private Const swUnit_Nanometer_Inch_New As Long = 30
‘ Private Const swUnit_Micrometer_Inch_New As Long = 31
‘ Private Const swUnit_Angstrom_Inch_New As Long = 32
‘ Private Const swUnit_Milliinch_New As Long = 33
‘ Private Const swUnit_Microinch_New As Long = 34
‘ Private Const swUnit_Nanoinch_New As Long = 35
‘ Private Const swUnit_Picometer_Inch_New As Long = 36
‘ Private Const swUnit_Femtometer_Inch_New As Long = 37
‘ Private Const swUnit_Attometer_Inch_New As Long = 38
‘ Private Const swUnit_Zeptometer_Inch_New As Long = 39
‘ Private Const swUnit_Yoctometer_Inch_New As Long = 40
‘ Private Const swUnit_Inch_mks As Long = 41
‘ Private Const swUnit_Foot_mks As Long = 42
‘ Private Const swUnit_Yard_mks As Long = 43
‘ Private Const swUnit_Kilometer_mks As Long = 44
‘ Private Const swUnit_Mile_mks As Long = 45
‘ Private Const swUnit_Micron_mks As Long = 46
‘ Private Const swUnit_Nanometer_mks As Long = 47
‘ Private Const swUnit_Picometer_mks As Long = 48
‘ Private Const swUnit_Femtometer_mks As Long = 49
‘ Private Const swUnit_Attometer_mks As Long = 50
‘ Private Const swUnit_Zeptometer_mks As Long = 51
‘ Private Const swUnit_Yoctometer_mks As Long = 52
‘ Private Const swUnit_Angstrom_mks As Long = 53
‘ Private Const swUnit_Milliinch_mks As Long = 54
‘ Private Const swUnit_Microinch_mks As Long = 55
‘ Private Const swUnit_Nanoinch_mks As Long = 56
‘ Private Const swUnit_Picometer_Inch_mks As Long = 57
‘ Private Const swUnit_Femtometer_Inch_mks As Long = 58
‘ Private Const swUnit_Attometer_Inch_mks As Long = 59
‘ Private Const swUnit_Zeptometer_Inch_mks As Long = 60
‘ Private Const swUnit_Yoctometer_Inch_mks As Long = 61
‘ Private Const swUnit_Micrometer_Inch_mks As Long = 62
‘ Private Const swUnit_Nanometer_Inch_mks As Long = 63
‘ Private Const swUnit_Angstrom_Inch_mks As Long = 64
‘ Private Const swUnit_Inch_ips As Long = 65
‘ Private Const swUnit_Foot_ips As Long = 66
‘ Private Const swUnit_Yard_ips As Long = 67
‘ Private Const swUnit_Kilometer_ips As Long = 68
‘ Private Const swUnit_Mile_ips As Long = 69
‘ Private Const swUnit_Micron_ips As Long = 70
‘ Private Const swUnit_Nanometer_ips As Long = 71
‘ Private Const swUnit_Picometer_ips As Long = 72
‘ Private Const swUnit_Femtometer_ips As Long = 73
‘ Private Const swUnit_Attometer_ips As Long = 74
‘ Private Const swUnit_Zeptometer_ips As Long = 75
‘ Private Const swUnit_Yoctometer_ips As Long = 76
‘ Private Const swUnit_Angstrom_ips As Long = 77
‘ Private Const swUnit_Milliinch_ips As Long = 78
‘ Private Const swUnit_Microinch_ips As Long = 79
‘ Private Const swUnit_Nanoinch_ips As Long = 80
‘ Private Const swUnit_Picometer_Inch_ips As Long = 81
‘ Private Const swUnit_Femtometer_Inch_ips As Long = 82
‘ Private Const swUnit_Attometer_Inch_ips As Long = 83
‘ Private Const swUnit_Zeptometer_Inch_ips As Long = 84
‘ Private Const swUnit_Yoctometer_Inch_ips As Long = 85
‘ Private Const swUnit_Micrometer_Inch_ips As Long = 86
‘ Private Const swUnit_Nanometer_Inch_ips As Long = 87
‘ Private Const swUnit_Angstrom_Inch_ips As Long = 88
‘ Private Const swUnit_Millimeter_inch_new As Long = 89
‘ Private Const swUnit_Centimeter_inch_new As Long = 90
‘ Private Const swUnit_Meter_inch_new As Long = 91
‘ Private Const swUnit_Inch_inch_new As Long = 92
‘ Private Const swUnit_Foot_inch_new As Long = 93
‘ Private Const swUnit_Yard_inch_new As Long = 94
‘ Private Const swUnit_Kilometer_inch_new As Long = 95
‘ Private Const swUnit_Mile_inch_new As Long = 96
‘ Private Const swUnit_Micron_inch_new As Long = 97
‘ Private Const swUnit_Nanometer_inch_new As Long = 98
‘ Private Const swUnit_Picometer_inch_new As Long = 99
‘ Private Const swUnit_Femtometer_inch_new As Long = 100
‘ Private Const swUnit_Attometer_inch_new As Long = 101
‘ Private Const swUnit_Zeptometer_inch_new As Long = 102
‘ Private Const swUnit_Yoctometer_inch_new As Long = 103
‘ Private Const swUnit_Angstrom_inch_new As Long = 104
‘ Private Const swUnit_Milliinch_inch_new As Long = 105
‘ Private Const swUnit_Microinch_inch_new As Long = 106
‘ Private Const swUnit_Nanoinch_inch_new As Long = 107
‘ Private Const swUnit_Picometer_Inch_inch_new As Long = 108
‘ Private Const swUnit_Femtometer_Inch_inch_new As Long = 109
‘ Private Const swUnit_Attometer_Inch_inch_new As Long = 110
‘ Private Const swUnit_Zeptometer_Inch_inch_new As Long = 111
‘ Private Const swUnit_Yoctometer_Inch_inch_new As Long = 112
‘ Private Const swUnit_Micrometer_Inch_inch_new As Long = 113
‘ Private Const swUnit_Nanometer_Inch_inch_new As Long = 114
‘ Private Const swUnit_Angstrom_Inch_inch_new As Long = 115
‘ SolidWorks API 定数 (swconst.chm などで確認)
‘ Public Const swSelMgr As Long = 2 ‘ SelectionManager
‘ Public Const swDimension As Long = 13 ‘ Dimension
コードのポイント:
- オブジェクトの取得: `Application.SldWorks` でSolidWorksアプリケーション本体を取得し、そこから `ActiveDoc` などでドキュメントを取得します。
- 選択オブジェクトの操作: `SelectionManager` を使って、ユーザーが選択したオブジェクトを取得します。
- 型チェック: `TypeName()` 関数で、取得したオブジェクトが期待する型(Dimensionなど)であるかを確認しています。
- 寸法値の変更: `SetValue2` メソッドで寸法値を変更します。ここで注意が必要なのが単位系です。 SolidWorksの内部単位系と、ユーザーが入力する値の単位系が異なる場合、変換係数 (`unitFactor`) を用いる必要があります。`GetSWUnitFactor` 関数は、そのためのヘルパー関数として例示しました。
- 再構築: `ForceRebuild3 True` で、変更をモデルに反映させます。
4.2. VB.NET アドインの「骨格」例
次に、VB.NETで作成するCOMアドインの基本的な構造を見てみましょう。
.net
‘ VB.NET アドイン例 (Visual Studioで作成)
‘ プロジェクトの種類: COM クラス ライブラリ
‘ 参照設定: SolidWorks xxxx Type Library (バージョンに合わせて選択)
Imports SolidWorks.Interop.sldworks
Imports SolidWorks.Interop.swpublished
Imports System.Runtime.InteropServices
‘ COMコンポーネントとして登録するための属性
Public Class Connect
Implements ISldWorks
‘ SolidWorks アプリケーションオブジェクト
Private swApp As SldWorks
‘ アドインのID (SolidWorksが管理するID)
Private cookie As Integer
‘ — ISldWorks インターフェースの実装 —
‘ OnConnection: SolidWorksがアドインを読み込んだときに呼び出される
Public Sub OnConnection(ByVal app As Object, ByVal connectMode As Integer, ByVal addInInst As Object, ByRef customPropertyMgr As Object) Implements ISldWorks.OnConnection
‘ Object型からSldWorks型にキャスト
swApp = DirectCast(app, SldWorks)
‘ アドインのCookieを取得 (SolidWorksが管理)
cookie = connectMode
‘ — ここでUIの追加や初期化処理を行う —
‘ 例: リボンメニューにボタンを追加
‘ AddRibbonButton()
‘ 例: フォームの初期化
‘ InitializeMyForm()
Console.WriteLine(“アドインが接続されました。”) ‘ デバッグ用
End Sub
‘ OnDisconnection: SolidWorksがアドインをアンロードするときに呼び出される
Public Sub OnDisconnection(ByVal disconnectMode As Integer, ByRef customPropertyMgr As Object) Implements ISldWorks.OnDisconnection
‘ — ここでリソースの解放などを行う —
‘ 例: イベントハンドラの解除
‘ RemoveEventHandlers()
‘ 例: UI要素の削除 (必要であれば)
‘ RemoveRibbonButton()
swApp = Nothing ‘ オブジェクト参照を解放
Console.WriteLine(“アドインが切断されました。”) ‘ デバッグ用
End Sub
‘ — ここに、VBAマクロで実装していた処理をメソッドとして実装 —
‘ 例: VBAマクロの「指定した寸法値を変更する」機能をVB.NETで実装
Public Sub ChangeDimensionValue()
If swApp Is Nothing Then Return
Dim swModel As ModelDoc2 = DirectCast(swApp.ActiveDoc, ModelDoc2)
If swModel Is Nothing Then
MessageBox.Show(“アクティブなドキュメントがありません。”, “エラー”, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Return
End If
Dim swSelMgr As SelectionMgr = DirectCast(swModel.SelectionManager, SelectionMgr)
Dim objects As Object() = DirectCast(swSelMgr.GetSelectedObjects, Object())
If objects IsNot Nothing AndAlso objects.Length = 1 Then
Dim swDimension As Dimension = TryCast(objects(0), Dimension)
If swDimension IsNot Nothing Then
Dim dimensionName As String = swDimension.GetName()
Dim newValueStr As String = InputBox(“新しい寸法値を入力してください (例: 50.5)”, “寸法値変更”, “50.5”)
If Not String.IsNullOrEmpty(newValueStr) Then
Dim newValue As Double
If Double.TryParse(newValueStr, newValue) Then
‘ VBAと同様に単位系に注意してSetValue2を呼び出す
‘ GetSWUnitFactor() のようなヘルパー関数もVB.NETで実装
Dim unitFactor As Double = GetSWUnitFactor(swModel)
If swDimension.SetValue2(newValue unitFactor) Then
swModel.ForceRebuild3(True)
MessageBox.Show($”{dimensionName} の値を {newValue} に変更しました。”, “成功”, MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MessageBox.Show(“寸法の値を変更できませんでした。”, “エラー”, MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
Else
MessageBox.Show(“無効な数値が入力されました。”, “エラー”, MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End If
Else
MessageBox.Show(“選択されたオブジェクトは寸法ではありません。”, “警告”, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End If
Else
MessageBox.Show(“変更したい寸法を1つだけ選択してください。”, “警告”, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End If
End Sub
‘ SolidWorksの単位系に応じた係数を取得するヘルパー関数 (VB.NET版)
Private Function GetSWUnitFactor(model As ModelDoc2) As Double
Dim unit As Integer = model.Extension.GetUserPreferenceIntegerValue(swUserPreferenceIntegerValue_e.swUnitsLinear)
Select Case unit
Case swUnit_Millimeter: Return 1.0
Case swUnit_Centimeter: Return 10.0
Case swUnit_Meter: Return 1000.0
Case swUnit_Inch: Return 25.4 ‘ 1インチ = 25.4 mm
Case swUnit_Foot: Return 25.4 12
‘ 他の単位系も必要に応じて追加
Case Else: Return 1.0 ‘ デフォルトはmm
End Select
End Function
‘ SolidWorks API 定数 (swconst.chm などで確認、または Imports SolidWorks.Interop.swpublished で利用可能)
‘ Public Enum swUserPreferenceIntegerValue_e
‘ swUnitsLinear = 1
‘ ‘ … 他の列挙体メンバー
‘ End Enum
‘ Public Enum swLinearUnit_e
‘ swUnit_Millimeter = 0
‘ ‘ … 他の列挙体メンバー
‘ End Enum
End Class
VB.NETコードのポイント:
- `Implements ISldWorks`: COMアドインとして必須のインターフェースを実装します。
- `OnConnection` / `OnDisconnection`: VBAの`AutoExec`や`AutoClose`に相当する、アドインのライフサイクルを管理するメソッドです。ここで、SolidWorksアプリケーションオブジェクト (`swApp`) を取得し、UIのカスタマイズ(ボタン配置など)を行います。
- `DirectCast` / `TryCast`: VBAの`Set`に相当しますが、型変換の際に使用します。`DirectCast`は、型が一致しない場合に実行時エラーとなります。`TryCast`は、型が一致しない場合に`Nothing`を返します。
- `MessageBox.Show`: VBAの`MsgBox`に相当します。
- `Double.TryParse`: 文字列をDouble型に変換する際に、エラーハンドリングを組み込んでいます。VBAでは`CDbl`などを使いますが、エラー処理が別途必要になります。
- `$””` (Interpolated Strings): 文字列の中に変数の値を埋め込むための、VB.NETの便利な機能です。
「なぜVB.NETなのか?」
VBAでもCOMアドインを作成することは可能ですが、開発環境の制約や、より複雑なUIや高度な処理の実装においては、Visual Studioのような統合開発環境(IDE)とVB.NET(またはC#)を使用する方が、圧倒的に効率的で、機能的にも優れています。VBAで培ったSolidWorks APIの知識は、VB.NETでもそのまま活かせますから、学習コストも比較的低いと言えます。
5. アドイン開発で遭遇しがちな「壁」とその乗り越え方
アドイン開発は、VBAマクロ開発とは異なる、いくつかの「壁」に直面することがあります。
5.1. COMコンポーネントの登録とアンインストール
作成したCOMコンポーネント(DLLファイル)は、SolidWorksから認識されるように「登録」する必要があります。
- 登録: `regasm.exe` というコマンドラインツールを使って、DLLファイルをシステムに登録します。
- アンインストール: `regasm.exe /unregister` コマンドで登録を解除します。
Visual Studioでは、プロジェクトのビルド時に自動的に登録・アンロードを管理する機能(`RegisterForComRegistration` / `UnregisterForComDeregistration`)も提供されており、開発中は非常に便利です。
【陥りやすいエラー】
- `regasm.exe` の実行パスが通っていない。
- 32bit版/64bit版の混同(SolidWorksのビット数と`regasm.exe`のビット数を合わせる必要があります)。
- DLLファイルが実行中に別のプロセスで使用されている(アンロードされていない)。
5.2. UIのカスタマイズ:リボンメニューへのボタン配置
アドインの醍醐味は、SolidWorksのUIに独自のボタンを配置できることです。
- `OnConnection`イベント: SolidWorksがアドインを読み込んだときに発生するこのイベント内で、SolidWorksのUIオブジェクトにアクセスし、新しいタブやボタンを追加します。
- CommandManager: SolidWorksのUI要素を管理するオブジェクトです。これを使って、リボンメニューのカスタマイズを行います。
【陥りやすいエラー】
- UI要素の追加・削除のタイミングが間違っている。
- ボタンに割り当てるコマンド(マクロやメソッド)が見つからない。
- UI要素の命名規則や構造を理解していない。
5.3. エラーハンドリングとデバッグ
アドインはSolidWorks本体と密接に連携するため、予期せぬエラーが発生すると、SolidWorks自体が不安定になることもあります。
- `On Error Resume Next` の乱用は避ける: VBAでもそうですが、アドイン開発では特に、エラーハンドリングを慎重に行う必要があります。
- `Try…Catch` ブロック: VB.NETでは、`Try…Catch`ブロックを使って、例外処理を効果的に行います。
- デバッグ出力: `Console.WriteLine` や、`Debug.Print` を使って、コードの実行状況を追跡します。Visual Studioのデバッグ機能は非常に強力です。
【陥りやすいエラー】
- API呼び出し時の引数が不正。
- オブジェクトが`Nothing`(Null)の状態でメソッドを呼び出している。
- APIの仕様変更や、バージョン間の互換性の問題。
6. まとめ:アドイン開発は、SolidWorks自動化の「次なるステージ」
VBAマクロをCOMアドインへと昇華させる旅は、確かに一歩踏み出すには勇気が必要かもしれません。しかし、その先には、より強力で、より洗練されたSolidWorksの活用法が待っています。
今回お伝えした内容は、アドイン開発のほんの入り口に過ぎません。しかし、この「思考プロセス」と「基本的な骨格」を理解していただければ、皆さんはもう、VBAマクロの記録係から卒業し、SolidWorksの機能を拡張する「開発者」への道を歩み始めることができます。
ここをクリアすれば、SolidWorks VBAの基本、そしてアドイン開発の基礎はバッチリですよ!
まずは、簡単なVBAマクロをVB.NETに移植することから始めてみましょう。Visual Studioの強力なデバッグ機能と、SolidWorks APIの豊富なドキュメント(`swconst.chm`など)を頼りに、一歩ずつ進んでいってください。
皆さんが、SolidWorksの自動化を通じて、より効率的で創造的な業務を実現できることを、心から願っています。
これからも、SolidWorks VBA、そしてアドイン開発の世界を、皆さんと一緒に探求していきましょう!
