SolidWorks VBAの真髄:注記操作の最適化による「設計自動化」の深淵
設計現場において、図面(Drawing)の表題欄修正ほど生産性を削ぐ作業はない。数千枚の図面管理を担うエンジニアにとって、手作業による注記更新は「ミスを誘発するための儀式」に過ぎない。
今日は、SolidWorks APIを使い倒し、図面注記を自在に操るための「エンジニアリングの勘所」を伝授する。公式リファレンスをなぞるような初学者のための解説ではない。メモリ管理と再帰処理、そして堅牢なエラーハンドリングを前提とした、実戦で生き残るためのコードだ。
—
1. オブジェクトモデルの「正しい」歩き方
SolidWorks APIにおいて、`Note`オブジェクトへの到達はしばしば「迷宮」となる。`ModelDoc2`から`View`、そして`Annotation`へと辿るプロセスで、多くの開発者はメモリリークや未定義オブジェクトへのアクセスによるクラッシュを経験する。
核心:なぜ Annotation オブジェクトを直接叩くのか
`Note`オブジェクトを操作する際、単に `GetFirstAnnotation` を繰り返すのは愚策だ。図面内の注記は `View` に属するものと、シート自体に属するもの(シートフォーマット)が混在している。これを区別し、かつ最適に走査するための設計思想が重要となる。
2. 実践:表題欄を一括書き換えする堅牢な実装
以下に、メモリを汚さず、かつ確実に特定の注記を捕捉・更新するコードを示す。ポイントは「再帰的な走査」と「オブジェクトの解放」だ。
Option Explicit
‘ 伝説的なエンジニアは、定数をハードコードせず、常に管理可能な形にする
Private Const TARGET_NOTE_NAME As String = “DRAWING_TITLE”
Public Sub UpdateDrawingNotes()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
‘ 型チェック:図面以外での実行を防ぐ(防御的プログラミング)
If swModel Is Nothing Or swModel.GetType <> swDocDRAWING Then
MsgBox “図面を開いてください。”, vbCritical
Exit Sub
End If
Set swDraw = swModel
‘ シートのループ処理
Dim vSheets As Variant
Dim i As Long
vSheets = swDraw.GetSheetNames
For i = 0 To UBound(vSheets)
swDraw.ActivateSheet vSheets(i)
‘ シート内の全注記を走査
ProcessAnnotations swDraw
Next i
‘ 明示的な解放:VBAのガベージコレクションを信用してはならない
Set swDraw = Nothing
Set swModel = Nothing
Set swApp = Nothing
End Sub
Private Sub ProcessAnnotations(swDraw As SldWorks.DrawingDoc)
Dim swView As SldWorks.View
Dim swAnn As SldWorks.Annotation
Dim swNote As SldWorks.Note
‘ シートの最初のビュー(シート自体)を取得
Set swView = swDraw.GetFirstView
Do While Not swView Is Nothing
Set swAnn = swView.GetFirstAnnotation
Do While Not swAnn Is Nothing
‘ 型チェック:注記オブジェクトのみを抽出
If swAnn.GetType = swAnnotationNote Then
Set swNote = swAnn.GetSpecificAnnotation
‘ 名前による判定(注記プロパティで名前を設定しておくのがプロの流儀)
If swNote.GetName = TARGET_NOTE_NAME Then
swNote.SetText “改訂:2023-10-27”
End If
Set swNote = Nothing
End If
Set swAnn = swAnn.GetNext
Loop
Set swView = swView.GetNextView
Loop
End Sub
—
3. シニアエンジニアが意識すべき「極限の知見」
メモリとライフサイクル
VBA環境において、オブジェクト変数を `Set = Nothing` で解放するのは基本中の基本だが、真の最適化は「ループ内でのオブジェクト生成を最小化すること」にある。`GetNext` メソッドを多用する場合、中間オブジェクトの参照を保持しすぎないよう注意が必要だ。大規模アセンブリや複雑な図面では、このわずかな差が数分間の処理時間短縮に繋がる。
システム間連携:カスタムプロパティとの同期
もしあなたがPLM(製品ライフサイクル管理)システムやERPと連携させるなら、`Note`の値を直接書き換えるのではなく、`ModelDoc2.CustomInfo` を更新し、注記側を「カスタムプロパティへのリンク」として設定しておくべきだ。
- 注記側: `$PRP:”DrawingNumber”`
- VBA側: `swModel.AddCustomInfo3 “”, “DrawingNumber”, swCustomInfoText, “NEW-VALUE”`
これにより、図面の変更が他のシステムと常に同期され、不整合の温床を根絶できる。
Windows APIの呼び出し(上級編)
もし、SolidWorksのAPIでは届かない「Windowsのダイアログ操作」や「特殊なメモリ操作」が必要な場合は、`Declare PtrSafe` を用いたWin32 APIの呼び出しを検討せよ。しかし、それは「最後の手段」だ。SolidWorksが提供する `IModelDocExtension::CustomPropertyManager` で解決できない課題は、APIの限界ではなく、設計構造の欠陥であることが多い。
—
結論:自動化は「設計」である
自動化スクリプトを書くことは、コーディングではなく「設計」である。
どんなに汚いコードでも動けば良いと考えるのは、レガシーを増産するだけのシステム管理者だ。真のエンジニアは、将来のメンテナンスコスト、SolidWorksのバージョンアップ時の追従性、そして何より、そのシステムを使う設計者が直感的に運用できるインターフェースを設計する。
貴殿のシステムが、堅牢な基盤の上に築かれることを期待している。不明な点があれば、またいつでも深淵へ問いに来るがいい。
