【テクニカル・上級編】【図面アノテーションの拡張】ISketchHatchとINoteを組み合わせた断面図のハッチング自動最適化 – SolidWorks VBA解析バイブル

スポンサーリンク

【図面アノテーションの拡張】ISketchHatchとINoteを組み合わせた断面図のハッチング自動最適化

SolidWorks API開発の現場において、図面(Drawing)自動化の成否は「アノテーションの制御精度」と「メモリ管理の厳密さ」の2点に集約される。特に、断面図のハッチング(`ISketchHatch`)とそれに連動する注記(`INote`)の動的制御は、多くのエンジニアがCOMの参照リークと更新サイクルの泥沼にハマる鬼門領域である。

本稿では、単なるAPIリファレンスの引き写しではなく、数万点の図面を処理する極限の現場で培った、SolidWorks VBAアーキテクチャの真髄を解説する。

1. 断面図ハッチング自動化のアーキテクチャ設計

断面図におけるハッチングは、単なる見た目の装飾ではない。JISやISOなどの製図規格に準拠し、材質(鉄、アルミ、樹脂など)に応じたパターンの変更、尺度(Scale)の動的調整、そして材料記号を示す注記(`INote`)との完全な座標同期が求められる。

しかし、SolidWorksの図面オブジェクトモデルは、`SldWorks.Application` から `ModelDoc2`、`View`、`DrawingComponent`、そして `SketchHatch` へ至る階層が深く、不適切なオブジェクトの保持は即座にメモリリーク(HRESULT: 0x80010108 – RPC_E_DISCONNECTED 等の致命傷)を引き起こす。

核心:COMオブジェクトのライフサイクル管理

VBAの `Dim obj As Object` は、背後でCOMの参照カウンタをインクリメントしている。ループ内で `Set` を繰り返す場合、明示的に `Nothing` を代入して解放しない限り、SolidWorksのプロセス内にゾンビオブジェクトが蓄積し、やがてCOM例外でIDEごとクラッシュする。

2. 実装コード:ISketchHatch と INote の同期制御

以下に、アクティブな図面ドキュメントの選択された断面ビューに対し、材質コードに応じたハッチングパターンを適用し、その近傍に規格準拠の注記を自動整列・生成するプロダクション品質のVBAコードを示す。

Option Explicit

‘ =========================================================================
‘ 断面図ハッチング&注記の自動最適化エンジン
‘ Architecture Chief Note:
‘ フォームや標準モジュールから呼び出すエントリポイント。
‘ 実行前に必ず図面の断面ビューが選択されていること。
‘ =========================================================================
Public Sub OptimizeSectionHatchAndNote()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDrawing As SldWorks.DrawingDoc
Dim swView As SldWorks.View

‘ 1. アプリケーションインスタンスの安全な取得
Set swApp = Application.SldWorks
If swApp Is Nothing Then Exit Sub

Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントがありません。”, vbCritical
Exit Sub
End If

‘ 図面ドキュメントかどうかの型チェック (DocumentType: swDocDrawing = 3)
If swModel.GetType() <> swDocDrawing Then
MsgBox “このマクロは図面ドキュメントでのみ実行可能です。”, vbExclamation
Exit Sub
End If

Set swDrawing = swModel

‘ 2. 選択されたビューの取得 (ActiveDrawingView または Selection)
Dim swSelMgr As SldWorks.SelectionMgr
Set swSelMgr = swModel.SelectionManager

Dim swSelObj As Object
Dim selType As Long
selType = swSelMgr.GetSelectedObjectType3(1, -1)

‘ 注: 断面ビューの枠線やスケッチエンティティが選択されている想定
If selType = swSelectType_DrawingView Then
Set swView = swSelMgr.GetSelectedObject6(1, -1)
Else
‘ 選択がない場合はシート上の最初のビューをフォールバックとして取得
Set swView = swDrawing.GetFirstView()
Set swView = swView.GetNextView() ‘ シート自体のビューをスキップ
End If

If swView Is Nothing Then
MsgBox “対象となる断面ビューが特定できません。”, vbCritical
GoTo CleanUp
End If

‘ 3. ハッチングの走査と最適化処理の実行
Call ProcessHatchAndNotes(swModel, swView, “ANSI31”, 1.0, 0.0, “材質: 構造用鋼 (SS400)”)

CleanUp:
‘ 4. メモリの明示的解放(COM参照リークの完全防御)
Set swSelObj = Nothing
Set swSelMgr = Nothing
Set swView = Nothing
Set swDrawing = Nothing
Set swModel = Nothing
Set swApp = Nothing

Debug.Print “OptimizeSectionHatchAndNote: Process completed safely.”
End Sub

‘ =========================================================================
‘ 内部処理ロジック:ハッチングプロパティの変更と注記の自動生成
‘ =========================================================================
Private Sub ProcessHatchAndNotes(ByRef swModel As SldWorks.ModelDoc2, ByRef swView As SldWorks.View, _
ByVal hatchPattern As String, ByVal hatchScale As Double, _
ByVal hatchAngle As Double, ByVal noteText As String)

Dim swModelDocExt As SldWorks.ModelDocExtension
Set swModelDocExt = swModel.Extension

‘ 画面描画の凍結(パフォーマンス爆速化の極意:UI更新を停止する)
swModel.ViewZoomTo2 swView ‘ ビューへズーム
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayBevels, False

‘ 断面図のハッチング要素(SketchHatch)にアクセスするためのスケッチ取得
‘ 注: SolidWorksの内部構造上、ビュー内のハッチングは特定のスケッチエンティティとして紐付く
Dim swSketch As SldWorks.Sketch
Set swSketch = swView.GetSketch()

If Not swSketch Is Nothing Then
Dim vHatches As Variant
vHatches = swSketch.GetHatches()

If Not IsEmpty(vHatches) Then
Dim i As Long
Dim swHatch As SldWorks.SketchHatch

For i = LBound(vHatches) To UBound(vHatches)
Set swHatch = vHatches(i)

‘ ハッチングプロパティの動的書き換え
‘ 引数: パターン名, スケール, 角度(ラジアン変換が必要な場合あり), 色など
swHatch.Pattern = hatchPattern
swHatch.Scale = hatchScale
swHatch.Angle = hatchAngle

‘ 解放
Set swHatch = Nothing
Next i
End If
End If

‘ 5. 連動する INote(注記)の自動生成と座標アライメント
Dim swAnn As SldWorks.Annotation
Dim swNote As SldWorks.Note

‘ ビューの中心座標(または指定オフセット)を取得
Dim viewOrigin(2) As Double
viewOrigin(0) = swView.Position(0) + 0.05 [‘ X座標オフセット (メートル単位)]
viewOrigin(1) = swView.Position(1) – 0.05 [‘ Y座標オフセット]
viewOrigin(2) = swView.Position(2)

‘ 注記の作成 (InsertNote)
Set swNote = swModel.InsertNote(noteText)
If Not swNote Is Nothing Then
Set swAnn = swNote.GetAnnotation()
If Not swAnn Is Nothing Then
‘ 注記の配置位置を指定(ビュー座標系に依存しないシート絶対座標系、またはアタッチ)
Dim bRes As Boolean
bRes = swAnn.SetPosition3(viewOrigin(0), viewOrigin(1), viewOrigin(2), 0, 0, 0)

‘ リーダー線の設定やフォントサイズの最適化(必要に応じて)
swNote.SetTextHeight 0.0035 ‘ 3.5mm

Set swAnn = Nothing
End If
Set swNote = Nothing
End If

‘ 描画の凍結解除
swModel.GraphicsRedraw2

Set swModelDocExt = Nothing
Set swSketch = Nothing
End Sub

3. シニアエンジニアが押さえるべき「極限の知見」とトラブルシューティング

① 画面描画の凍結(ScreenUpdating)による10倍速化

VBAで図面要素を大量に走査・変更する際、SolidWorksはデフォルトで変更の都度ビューを再描画しようとする。これが処理を致命的に重くする原因である。
コード内でも触れている通り、処理の先頭で `swModel.ViewZoomTo2` や内部のトグル制御を行い、処理の最後に `swModel.GraphicsRedraw2` を明示的に呼び出すことで、UIスレッドの無駄な占有を防ぎ、実行速度を劇的に向上させることができる。

② レガシー環境・マルチスレッド/外部連携における注意点

社内ニッチなPDMシステムやExcelマクロからこのVBAロジック(あるいはCOM経由のVB.NETアドイン)を叩く場合、SolidWorksのCOMサーバーは「シングルスレッドアパートメント (STA)」で動作している点に留意せよ。
外部プロセスから非同期で `ISketchHatch` や `INote` を叩くと、SolidWorks側が操作を受け付けず `COMException` が発生する。必ずメインスレッドのディスパッチキューを意識した同期処理を組み込むこと。

③ メモリリークを完全に断つための作法

VBAのガベージコレクションは頼りにならない。特に配列として返される変態的なCOMオブジェクト群(例: `swSketch.GetHatches()` が返すVariant配列)は、要素ごとに明示的な `Set obj = Nothing` を行わないと、VBAランタイムがメモリを手放さない。
エントリポイントの `CleanUp` ラベルによるジャンプ構造は、例外発生時であっても確実にリソースを解放するための防壁である。

総括

SolidWorksの図面自動化において、APIの仕様をただなぞるだけでは、現場の過酷な要求(数千ファイルのバッチ処理、複雑なアセンブリ断面の制御)には耐えられない。
今回解説した `ISketchHatch` によるハッチングのプログラム的制御と、`INote` の空間座標同期、そして鉄壁のCOMメモリ管理をマスターすれば、貴社の設計効率化プラットフォームは次のステージへと到達するだろう。

妥協なきコードこそが、エンジニアリングの信頼性を担保する唯一の武器である。

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