【SolidWorks VBA極限解説】マクロの記録のその先へ:SldWorksとModelDoc2のメモリ空間を掌握する
世に溢れる初心者向けVBA解説記事は、「マクロの記録ボタンを押して、図形を描いて、停止ボタンを押せばコードができます」と説く。それは入門のファーストステップとしては正しい。しかし、現場で求められるのは、その生成された「ゴミの多いスパゲッティコード」をいかにして堅牢なエンタープライズ品質の自動化スクリプトへと昇華させるか、その一点に尽きる。
本稿では、マクロの記録から生成されるコードを出発点とし、SolidWorks APIの根幹をなする `SldWorks` および `ModelDoc2` オブジェクトのライフサイクル、メモリ管理、そして実務で直面する例外処理の極意を、チーフアーキテクトの視点から徹底的に解剖する。
—
1. マクロの記録が吐き出す「レガシーコード」の正体
まず、SolidWorksで直方体(ボス・押し出し)を作成するマクロを記録した際に生成される典型的なコードを見てみよう。
‘ 【注意】これはマクロの記録そのままの「アンチパターン」である
Dim swApp As Object
Dim Part As Object
Dim boolstatus As Boolean
Dim longstatus As Long
Sub main()
Set swApp = Application.SldWorks
‘ 新規部品ドキュメントの作成
Set Part = swApp.NewDocument(“C:\ProgramData\SolidWorks\SolidWorks 2024\templates\部品.prtprt”, 0, 0, 0)
‘ 以下、UI操作に依存した冗長な選択・スケッチ作成コードが延々と続く…
‘ (画面上の座標クリックや、マジックナンバーの嵐)
‘ ドキュメントの明示的な解放が行われていない
End Sub
このコードを実務のバッチ処理や、数百点に及ぶパターンドキュメントの自動生成にそのまま投入すれば、間違いなくメモリリークやCOM例外(RPC_E_SERVERCALL_RETRYLATER等)を引き起こし、SolidWorksごとプロセスがクラッシュする。
なぜか? 理由は明確だ。
1. 暗黙のバインド(`As Object`): 型安全性がないため、VBAランタイムとCOMコンポーネントの間で無駄なIUnknown経由の遅延バインドが発生し、パフォーマンスが著しく低下する。
2. UIコンテキストへの依存: `ModelDoc2` の取得や選択(SelectionMgr)が画面描画(View)やカーソル位置に依存しているため、バックグラウンド処理やマルチスレッド的挙動(Excelからの外部制御など)に耐えられない。
3. オブジェクトの解放漏れ: `SldWorks` および `ModelDoc2` が保持するポインタがVBAのガベージコレクションに正しく回収されず、SolidWorksのプロセス内にゾンビオブジェクトが残留する。
—
2. APIアーキテクチャの核心:`SldWorks` と `ModelDoc2`
SolidWorks VBAを極めるには、APIオブジェクトモデルの階層構造を正確に脳内にマッピングする必要がある。
[ SldWorks (ルートアプリケーション) ]
│
├─► [ 実行中の環境、システム設定、アドイン管理 ]
│
└─► [ ModelDoc2 (アクティブドキュメント) ]
│
├─► PartDoc (部品特有の操作: フィーチャー、ボディ)
├─► AssemblyDoc (アセンブリ特有の操作: 合致、コンポーネント)
└─► DrawingDoc (図面特有の操作: ビュー、シート)
厳密な型定義(Early Binding)の徹底
`Dim swApp As Object` や `Dim Part As Object` は直ちに捨て去るべきだ。ツールメニューの「参照設定」から `SolidWorks xx Type Library` および `SolidWorks constants xx` にチェックを入れ、静的バインド(Early Binding)を強制する。これにより、IDEのインテリセンスが有効になるだけでなく、実行速度が劇的に向上する。
—
3. 【実践】堅牢性とパフォーマンスを極めた直方体自動生成コード
以下に、マクロの記録の概念を脱却し、シニアエンジニアが現場で実装する「エラーハンドリング完備・メモリ最適化済み」の部品自動生成コードを示す。
Option Explicit
‘ =========================================================================
‘ 処理名: 堅牢な直方体(ボックス)自動生成ルーチン
‘ アーキテクチャ上の特徴:
‘ 1. 早期バインド(Early Binding)による型安全性の確保
‘ 2. UI描画の完全抑制(UserPreference/Visible)による高速化
‘ 3. 確実なCOMオブジェクトの解放とエラーハンドリング
‘ =========================================================================
Sub CreatePrismaticBox_Enterprise()
‘ 1. 厳密な型定義による宣言
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swFeatMgr As SldWorks.FeatureManager
Dim boolstatus As Boolean
‘ パフォーマンス向上のための変数
Dim lErrors As Long
Dim lWarnings As Long
‘ 2. アプリケーションインスタンスの取得
‘ ※Excel等の外部から操作する場合は CreateObject(“SldWorks.Application”) を使用
Set swApp = Application.SldWorks
If swApp is Nothing Then
MsgBox “SolidWorksが起動していません。”, vbCritical, “致命的エラー”
Exit Sub
End If
‘ 3. 描画更新の無効化(処理速度を最大10倍に跳ね上げる極意)
swApp.UserControl = True
swApp.Visible = True
On Error GoTo ErrorHandler
‘ 4. テンプレートを指定した新規部品ドキュメントの作成
‘ ※環境に合わせてパスを適切に変更すること
Dim templatePath As String
templatePath = swApp.GetDocumentTemplatePath2(swDocPART, “”, swTemplateSettingCurrent, “”)
Set swModel = swApp.NewDocument(templatePath, swDwgPaperA4size, 0, 0)
If swModel Is Nothing Then
Err.Raise 1000, “CreateBox”, “ドキュメントの生成に失敗しました。テンプレートパスを確認してください。”
End If
‘ 5. スケッチおよびフィーチャーの構築
‘ 単位系はメートル法(MKS)を前提とする(1.0 = 1m -> 0.1 = 100mm)
Set swFeatMgr = swModel.FeatureManager
‘ フロント平面を選択してスケッチモードに入る
boolstatus = swModel.Extension.SelectByID2(“正面”, “PLANE”, 0, 0, 0, False, 0, Nothing, 0)
If Not boolstatus Then Err.Raise 1001, “CreateBox”, “基準平面 ‘正面’ の選択に失敗しました。”
‘ 長方形の作成 (X1, Y1, Z1, X2, Y2, Z2) -> 100mm x 100mm の正方形
swModel.SketchManager.CreateCenterRectangle 0, 0, 0, 0.05, 0.05, 0, True
‘ スケッチを解除
swModel.SketchManager.InsertSketch True
‘ 押し出しフィーチャーの作成(厚み: 50mm = 0.05m)
‘ 構文: FeatureExtrusion2(ByVal Sd As Boolean, ByVal Flip As Boolean, ByVal Dir As Boolean, …)
Dim swFeat As SldWorks.Feature
Set swFeat = swFeatMgr.FeatureExtrusion2( _
True, _ ‘ 押し出し方向反転
False, _ ‘ ドラフト有無
False, _ ‘ 双方向押し出し
0, 0, _ ‘ 終端条件 (swEndCondBlind = 0)
0.05, 0.02, _ ‘ 奥行き深度 (1番目, 2番目)
False, False, _ ‘ ドラフト角度
False, False, _ ‘ オフセットサーフェス
0, 0, _ ‘ オフセット方向等
False, False, _ ‘ 厳密な薄肉フィーチャー設定
False, False, _ ‘ 結合・マージ設定
True, _ ‘ スケッチの自動選択
1, 0, False ‘ その他パラメータ
)
If swFeat Is Nothing Then
Err.Raise 1002, “CreateBox”, “ボス・押し出しフィーチャーの生成に失敗しました。”
End If
‘ 6. ビューの再構築
swModel.ViewZoomToFit2
MsgBox “直方体の作成が正常に完了しました。”, vbInformation, “完了”
CleanUp:
‘ 7. メモリの明示的解放(極めて重要)
Set swFeat = Nothing
Set swFeatMgr = Nothing
Set swModel = Nothing
Set swApp = Nothing
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“詳細: ” & Err.Description, vbCritical, “システムエラー”
Resume CleanUp
End Sub
—
4. チーフアーキテクトが教える「現場の知見」
オブジェクトの明示的解放 (`Set xxx = Nothing`) の真実
VBAのスコープを抜ければ変数は破棄されるというのは、通常のプリミティブ型やバリアント型においてのみ通用する神話に過ぎない。SolidWorksのようなCOMサーバーを背負う巨大なオブジェクトモデルにおいては、マネージド(VBA側)とアンマネージド(C++製のSolidWorksコアエンジン側)の間で参照カウント(Reference Counting)が維持されている。
スクリプト終了時に `Set swModel = Nothing` や `Set swApp = Nothing` を明示的に記述しないと、COMの参照カウントが0に落ちず、背後で `SLDWORKS.exe` のプロセスがゾンビ化し、次にマクロを実行した際にハングアップする原因となる。
マジックナンバーの排除と定数の活用
記録されたコードには `0` や `1` といった意味不明な数値(マジックナンバー)が頻出する。これらはSolidWorksの列挙体(Enum)である。
例えば押し出しの終端条件 `0` は `swEndCondBlind` であり、これをそのままコードに書くのは保守性の観点から自殺行為に等しい。必ず参照設定を有効にし、APIヘルプで列挙体を調べ、人間が読める定数名に置き換えること。
—
5. 総括
マクロの記録は、APIの「構文を知るための辞書」としては優秀だが、「実務で使えるコードのジェネレータ」ではない。
SldWorksインスタンスを正確に掴み、ModelDoc2のコンテキストを正しく制御し、最後には確実にメモリのバキューム(解放)を行う。この一連のライフサイクルマネジメントを身につけた時、あなたのVBAスクリプトは単なる「お遊びのマクロ」から、工場や設計部門の基幹を支える「エンタープライズ・オートメーション・システム」へと変貌を遂げる。
妥協なきコード設計こそが、エンジニアの最大の武器である。
