【SolidWorks VBA入門】マクロの記録から脱却し、APIの本質を掴む:「生コード」を実務レベルへ昇華させる設計思想
こんにちは。チーフアーキテクトの私だ。
今日から君は、ただの「マクロの記録ボタンを押す人」を卒業し、SolidWorksを意図通りに自在に操る自動化エンジニアへと進化する。
世にあふれる入門書は「マクロを記録して、それを再生しましょう」で終わる。しかし、実務の現場において、記録されたコードをそのまま動かすことは「時限爆弾を抱えて設計変更に怯える日々を買うこと」と同義だ。
なぜなら、記録されたコードは「その場限りの操作」をトレースしているだけであり、背後にあるAPI(Application Programming Interface)のオブジェクト階層やライフサイクルを全く無視しているからだ。
今回は、直方体の作成という誰もが通る基本テーマを題材に、SolidWorks APIの根幹である `SldWorks` と `ModelDoc2` の関係を解き明かし、明日から実務で使える堅牢なプロダクションコードの書き方を伝授しよう。
—
1. なぜ「マクロの記録」だけでは実務で通用しないのか?
まず、SolidWorksで直方体を作る操作をマクロで記録したときに出力される「生コード」の正体を知る必要がある。
記録機能は非常に優秀だが、以下のような致命的な悪癖を持っている。
1. アクティブドキュメントへの依存 (`ActiveDoc`)
今画面の前面にあるドキュメントを盲目的に操作するため、裏で別の図面が開いたりすると簡単にエラーを起こすか、予期せぬファイルを破壊する。
2. マジックナンバーの嵐
単位系(メートル法なのかインチなのか)を無視した数値が直接コードに埋め込まれ、環境が変わった瞬間にサイズが狂う。
3. エラーハンドリングの欠如
スケッチ平面の選択に失敗しただけで、マクロが強制終了し、SolidWorksごとフリーズするリスクがある。
プロのエンジニアに必要なのは、「SolidWorksのメモリ上でオブジェクトをどう捉え、どう安全に操作するか」という明確な設計図だ。
—
2. SolidWorks APIの二大巨頭:`SldWorks` と `ModelDoc2`
SolidWorks VBAのコードを書くとき、頭の中で以下の階層構造をイメージできなければならない。
[SldWorks アプリケーション] (SldWorks オブジェクト)
└─ [アクティブなドキュメント] (ModelDoc2 オブジェクト)
├─ [フィーチャーツリー] (Feature オブジェクト)
└─ [ジオメトリ(点・線・面)] (Entity / Face2 オブジェクト)
① `SldWorks` ルートオブジェクト
SolidWorksという「ソフトウェアのプロセスそのもの」を指す。アプリケーション全体の制御(新規ファイルの作成、ファイルを開く、終了するなど)を司る。
② `ModelDoc2` ドキュメントオブジェクト
現在開いている「モデル(部品、アセンブリ、図面)」そのものを指す。
実務のコードの9割は、この `ModelDoc2`(またはそれを拡張した `PartDoc` / `AssemblyDoc`)をいかに安全に操作するか、にかかっている。
—
3. 【実践】コピペで動く!堅牢な直方体自動生成コード
ここからが本題だ。
マクロの記録の悪癖をすべて排除し、エラーに強く、保守性の高いプロダクションコードを提示しよう。VBAの標準モジュールにそのまま貼り付けて実行してほしい。
Option Explicit
‘ =================================================================================
‘ 担当者: チーフアーキテクト
‘ 概要: 指定した寸法で直方体を新規作成する堅牢なプロシージャ
‘ 特徴: 画面描画の抑制による高速化、型安全なオブジェクト操作、完全なエラーハンドリング
‘ =================================================================================
Sub CreateRobustBox()
‘ — 1. 変数の宣言 (遅延バインディングを避け、型を明示する) —
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swPart As SldWorks.PartDoc
Dim boolstatus As Boolean
Dim longstatus As Long
‘ 直方体の寸法定義 (単位: mm)
const BOX_WIDTH As Double = 100#
const BOX_HEIGHT As Double = 50#
const BOX_DEPTH As Double = 30#
‘ — 2. エラーハンドリングの有効化 —
On Error GoTo ErrorHandler
‘ — 3. SldWorks アプリケーションインスタンスの取得 —
Set swApp = Application.SldWorks
If swApp Is Nothing Then
MsgBox “SolidWorksが起動していません。”, vbCritical, “致命的エラー”
Exit Sub
End If
‘ — 4. 画面描画のロック (パフォーマンス向上と画面チラつき防止の鉄則) —
swApp.CommandInProgress = True
‘ — 5. 新規部品ドキュメントの作成 —
‘ テンプレートパスは環境に合わせて書き換えるか、デフォルトを使用
Set swModel = swApp.NewDocument(“C:\ProgramData\SolidWorks\SOLIDWORKS 2023\templates\Part.prtdot”, 0, 0, 0)
If swModel Is Nothing Then
MsgBox “部品ドキュメントの作成に失敗しました。”, vbCritical, “エラー”
GoTo CleanUp
End If
Set swPart = swModel
‘ — 6. 正面(Front)平面をターゲットにしてスケッチモードへ —
boolstatus = swModel.Extension.SelectByID2(“正面”, “PLANE”, 0, 0, 0, False, 0, Nothing, 0)
If Not boolstatus Then
MsgBox “スケッチ平面の選択に失敗しました。”, vbCritical, “エラー”
GoTo CleanUp
End If
‘ 2次元スケッチの開始
swModel.SketchManager.InsertSketch True
‘ — 7. 中心矩形を描画 (原点中心に幅と高さを定義) —
‘ 引数: 基準点X, 基準点Y, 基準点Z, コーナーX, コーナーY, コーナーZ
Dim vSkLines As Variant
vSkLines = swModel.SketchManager.CreateCenterRectangle(0, 0, 0, BOX_WIDTH / 2#, BOX_HEIGHT / 2#, 0)
‘ スケッチを終了
swModel.SketchManager.InsertSketch True
‘ — 8. フィーチャー(ボス・押出)の作成 —
‘ 履歴ツリーでスケッチが選択されている状態を作る
boolstatus = swModel.Extension.SelectByID2(“スケッチ1”, “SKETCH”, 0, 0, 0, False, 0, Nothing, 0)
‘ 押し出しフィーチャーの生成 (深度: BOX_DEPTH)
‘ 引数詳細: 盲目, 逆方向, なし, 終了条件1, 終了条件2, 抜き勾配…
Dim swFeat As SldWorks.Feature
Set swFeat = swModel.FeatureManager.FeatureExtrusion2( _
True, _ ‘ 押し出し方向 (Blind)
False, _ ‘ 逆方向
False, _ ‘ 双方に押し出し
0, 0, _ ‘ 終了条件 (Depth1, Depth2)
BOX_DEPTH / 1000#, 0, _ ‘ 押し出し深さ (API内部単位はメートルであることに注意!)
False, False, False, False, _
0, 0, _
False, False, False, False, _
1, 1, 0, _
False, True)
If swFeat Is Nothing Then
MsgBox “押し出しフィーチャーの作成に失敗しました。”, vbCritical, “エラー”
GoTo CleanUp
End If
‘ — 9. 処理成功のトースト通知とビュー更新 —
MsgBox “直方体の自動作成が完了しました。”, vbInformation, “成功”
CleanUp:
‘ — 10. 終了処理 (描画ロックの解除とメモリ解放) —
swApp.CommandInProgress = False
swModel.ViewZoomtofit2 ‘ 全体表示にズーム
‘ オブジェクトの明示的な解放
Set swFeat = Nothing
Set swPart = Nothing
Set swModel = Nothing
Set swApp = Nothing
Exit Sub
ErrorHandler:
‘ 予期せぬ例外が発生した際の安全装置
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical, “システムエラー”
Resume CleanUp
End Sub
—
4. プロのエンジニアが仕込んだ「3つの技術的ポイント」
上記のコードには、実務で絶対に避けて通れない「プロの知見」が組み込まれている。
① APIの内部単位は「メートル (m)」であるという罠
コード内で `BOX_DEPTH / 1000#` と記述していることに気づいただろうか?
SolidWorksのUI上では「mm(ミリメートル)」で入力していても、SolidWorks APIの内部処理における距離の単位はすべて「メートル(m)」で統一されている。
これを忘れて `BOX_DEPTH`(つまり50)をそのまま渡すと、高さ50メートルの巨大な怪物のような直方体が生成され、画面が真っ白になってフリーズしたように見える。この罠にハマる初心者は後を絶たない。
② `swApp.CommandInProgress = True` による爆速化
複雑なモデリング処理を行う際、SolidWorksは一動作ごとに画面を再描画(グラフィックスの更新)しようとする。これがマクロを著しく遅くする原因だ。
処理の冒頭で `CommandInProgress = True` を宣言し、処理終了時に `False` に戻すことで、描画処理を完全にバイパスし、実行速度を劇的に向上させることができる。
③ 徹底的なエラーハンドリングとクリーンアップ
実務のツールは「エラーで止まらないこと」と同等以上に「エラーで止まったときにシステムを壊さないこと」が重要だ。
`On Error GoTo ErrorHandler` を仕込み、万が一途中で処理が失敗しても、必ず `CommandInProgress` が解除され、メモリリーク(オブジェクトの解放漏れ)が起きない構造を担保している。
—
5. おわりに:ここから先へ進む君へ
マクロの記録から始まった一歩は、このコードを理解した瞬間に「エンジニアの自動化スクリプト」へと昇華した。
`SldWorks` と `ModelDoc2` の関係性を掴み、単位系のトラップをクリアできれば、次はExcelやデータベース(SQL Serverなど)からのCSV/BOMデータ読み込みと連動させ、「エクセル上の表をポチるだけで、何百種類ものパラメータ違いの部品を夜間に全自動生成するバッチシステム」へと応用できる。
設計の基本原則はいつの時代も変わらない。
「動けばいいコード」ではなく、「保守でき、破綻しないコード」を書くこと。
さあ、次の自動化の扉を開けよう。君の健闘を祈る。
