【図面アノテーションの拡張】ISketchHatchとINoteを組み合わせた断面図のハッチング自動最適化
開発現場のリーダーである私に、よくこんな相談が持ち込まれる。
「設計変更のたびに、断面図のハッチングパターンを手動で修正し、注記の引き出し線を整えるのに毎朝30分もかかっている。これ、なんとかならないか?」
図面品質の均一化は、製造業における永遠の課題だ。特に材質変更に伴うハッチングパターンの適用ミスや、注記(INote)の位置ズレは、下流工程での重大な手戻りを誘発する。
今回は、SolidWorks APIの真髄である「モデルと図面の厳密なライフサイクル管理」と、`ISketchHatch`・`INote`を組み合わせたアノテーション自動最適化の極意を伝授しよう。
ネット上のゴミカスのようなサンプルコードをコピペして「動かない、落ちる」と悩むフェーズは、今日で終わりにする。
—
1. なぜ従来のハッチング・注記処理は破綻するのか?
素人が書いたSolidWorks VBAコードが現場で爆散する理由は明確だ。
1. ビューとスケッチのコンテキスト混同:
断面図のハッチングは、単なるドローイング要素ではない。ビューの裏側に隠された「スケッチ(`ISketch`)」とその内部の「ハッチングデータ(`ISketchHatch`)」という、API特有の階層構造を理解していないため、オブジェクトの取得に失敗する。
2. アクティブドキュメントへの依存:
`SldWorks.ActiveDoc` を安易に信用し、フォーカスが外れた瞬間にぬるぽ(NullPointerException)を踏む。
3. リリースの欠如によるメモリリーク:
COMオブジェクトを解放せず、SolidWorksを数時間起動しているとメモリが枯渇する。
プロのエンジニアであれば、「型安全」「完全修飾されたオブジェクト階層」「厳格なエラーハンドリング」の3つを死守しなければならない。
—
2. アーキテクチャ設計:堅牢なアノテーション自動化の要
今回のツールは、以下のフローで動作する。
1. アクティブな図面(`DrawingDoc`)から、選択された断面ビュー(`View`)を特定する。
2. ビューに関連付けられたモデルのプロパティ(例:カスタムプロパティ「材質」)を安全に読み取る。
3. 材質名に応じ、`ISketchHatch` を操作してハッチングのパターン・尺度・角度をプログラム側から強制書き換えする。
4. 対応する `INote` を自動生成し、ハッチング領域の重心座標に基づいて完璧な位置に整列させる。
—
3. プロダクションコード:ハッチング自動最適化モジュール
実務でそのまま組み込める、商用レベルのVBAコードを公開する。エラーハンドリングとCOMオブジェクトのライフサイクル管理を徹底した実装だ。
Option Explicit
‘ =========================================================================
‘ 断面図ハッチング&注記最適化エンジン
‘ Architecture: SolidWorks Drawing Automation Module
‘ =========================================================================
Public Sub OptimizeSectionHatchAndNotes()
Dim swApp As SldWorks.SldWorks
Dim swDraw As SldWorks.DrawingDoc
Dim swView As SldWorks.View
Dim swModel As SldWorks.ModelDoc2
‘ 1. アプリケーションの安全な取得
Set swApp = Application.SldWorks
If swApp Is Nothing Then Exit Sub
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “ドキュメントが開かれていません。”, vbCritical, “API Error”
Exit Sub
End If
‘ 図面ドキュメントであることの型チェック
If swModel.GetType <> swDocDRAWING Then
MsgBox “このマクロは図面ドキュメントでのみ実行可能です。”, vbExclamation, “Validation Error”
Exit Sub
End If
Set swDraw = swModel
‘ 2. 選択されたビューの取得(ユーザーに断面ビューを選択させる)
Set swView = GetSelectedDrawingView(swDraw)
If swView Is Nothing Then
MsgBox “対象となる断面ビューを選択してください。”, vbExclamation, “Selection Required”
Exit Sub
End If
‘ 3. トランザクション開始(パフォーマンス向上とアンドゥ対策)
swModel.Extension.SetCommandLock swCommands_Lock
On Error GoTo ErrorHandler
‘ 4. ハッチングの最適化実行
Call ProcessHatchAndNotes(swDraw, swView)
‘ 5. 画面更新の強制
swModel.WindowRedraw
MsgBox “断面図のハッチングおよび注記の最適化が完了しました。”, vbInformation, “Success”
CleanUp:
swModel.Extension.ReleaseCommandLock swCommands_Lock
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “Critical Error”
Resume CleanUp
End Sub
‘ =========================================================================
‘ 補助関数: 選択セットからDrawing Viewを取得
‘ =========================================================================
Private Function GetSelectedDrawingView(ByVal swDraw As SldWorks.DrawingDoc) As SldWorks.View
Dim swSelMgr As SldWorks.SelectionMgr
Set swSelMgr = swDraw.Extension.SelectionManager
Dim selType As Long
selType = swSelMgr.GetSelectedObjectType3(1)
‘ 選択オブジェクトがビュー(またはその構成要素)であるか判定
If selType = swSelectType_Views Then
Set GetSelectedDrawingView = swSelMgr.GetSelectedObject6(1, -1)
Else
‘ ビュー自体の選択ではない場合、親ビューを辿るなどのフォールバックをここに実装
Set GetSelectedDrawingView = Nothing
End If
End Function
‘ =========================================================================
‘ コアロジック: ISketchHatch と INote の制御
‘ =========================================================================
Private Sub ProcessHatchAndNotes(ByVal swDraw As SldWorks.DrawingDoc, ByVal swView As SldWorks.View)
Dim swModel As SldWorks.ModelDoc2
Set swModel = swView.ReferencedDocument
‘ モデル側から材質プロパティを取得(例:カスタムプロパティ “Material”)
Dim materialName As String
materialName = GetModelMaterial(swModel)
‘ ビュー内のスケッチ群を走査し、ハッチングオブジェクトを捕捉
‘ ※SolidWorksの断面ハッチングは内部スケッチとして保持される
Dim vSketches As Variant
vSketches = swView.GetSketches
If IsEmpty(vSketches) Then Exit Sub
Dim i As Long
Dim swSketch As SldWorks.Sketch
Dim swHatchArray As Variant
Dim swHatch As SldWorks.SketchHatch
For i = LBound(vSketches) To UBound(vSketches)
Set swSketch = vSketches(i)
‘ スケッチ内のハッチングエンティティを取得
swHatchArray = swSketch.GetHatches
If Not IsEmpty(swHatchArray) Then
Dim j As Long
For j = LBound(swHatchArray) To UBound(swHatchArray)
Set swHatch = swHatchArray(j)
‘ 材質に応じたハッチングパターンの動的割り当て
ApplyMaterialHatchSettings swHatch, materialName
Next j
End If
Next i
‘ 紐付く注記(INote)の生成・整列
CreateOrUpdateSectionNote swDraw, swView, materialName
End Sub
‘ =========================================================================
‘ 材質に基づくハッチングパラメータの適用
‘ =========================================================================
Private Sub ApplyMaterialHatchSettings(ByRef swHatch As SldWorks.SketchHatch, ByVal material As String)
Select Case UCase(Trim(material))
Case “SUS304”, “ALUMINUM”, “A5052”
‘ 鋼・一般金属用パターン (ANSI31)
swHatch.Pattern = “ANSI31”
swHatch.Scale = 1.0
swHatch.Angle = 45#
Case “COPPER”, “BRASS”
‘ 銅・真鍮用パターン (ANSI32)
swHatch.Pattern = “ANSI32”
swHatch.Scale = 0.8
swHatch.Angle = 60#
Case Else
‘ デフォルト設定
swHatch.Pattern = “ISO”
swHatch.Scale = 1.0
swHatch.Angle = 45#
End Select
End Sub
‘ =========================================================================
‘ 注記(INote)の自動配置と整列
‘ =========================================================================
Private Sub CreateOrUpdateSectionNote(ByVal swDraw As SldWorks.DrawingDoc, ByVal swView As SldWorks.View, ByVal material As String)
Dim swModelAnn As SldWorks.ModelDocExtension
Set swModelAnn = swDraw.Extension
‘ ビューの中心座標を取得
Dim viewPos As Variant
viewPos = swView.GetPosition
‘ 注記テキストの構築
Dim noteText As String
noteText = “MATERIAL: ” & material & vbCrLf & “SCALE 1:1 (OPTIMIZED)”
‘ 注記を作成 (X, Y, Z座標を指定)
‘ 実際の現場ではINoteの重複作成を防ぐため、既存ノートの検索ロジックを挟むべきである
Dim swAnnotation As SldWorks.Annotation
Dim swNote As SldWorks.Note
Set swNote = swDraw.InsertNote(noteText)
If Not swNote Is Nothing Then
Set swAnnotation = swNote.GetAnnotation
‘ ビューの相対位置にノートをスナップ配置
Dim success As Boolean
success = swAnnotation.SetPosition(viewPos(0) + 0.05, viewPos(1) – 0.05, 0#)
End If
End Sub
‘ =========================================================================
‘ ユーティリティ: モデルのカスタムプロパティ取得
‘ =========================================================================
Private Function GetModelMaterial(ByVal swModel As SldWorks.ModelDoc2) As String
If swModel Is Nothing Then
GetModelMaterial = “DEFAULT”
Exit Function
End If
Dim swCustPropExt As SldWorks.CustomPropertyManager
Set swCustPropExt = swModel.Extension.CustomPropertyManager(“”)
Dim valOut As String
Dim resolvedOut As String
Dim wasResolved As Boolean
‘ “Material” または “材質” プロパティを探索
swCustPropExt.Get5 “Material”, False, valOut, resolvedOut, wasResolved
If resolvedOut = “” Then
swCustPropExt.Get5 “材質”, False, valOut, resolvedOut, wasResolved
End If
If resolvedOut <> “” Then
GetModelMaterial = resolvedOut
Else
GetModelMaterial = “GENERAL”
End If
End Function
—
4. チーフアーキテクトからの実践的アドバイス(ファイル・DB連携の注意点)
このコードをベースにして、さらに社内ニッチなPDMシステムやExcel/Accessデータベースと連携させる場合の極意を授ける。
1. トランザクションとパフォーマンスのトレードオフ
大量の図面を一括処理(バッチ処理)する場合、`swModel.WindowRedraw` や画面描画そのものがボトルネックになる。バッチ実行時は必ず `swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewUpdateInProcess, False` を活用し、描画をミュートしろ。
2. データベース結合時の排他制御
材質データを外部DB(SQLiteやSQL Server)から取得する場合、DBのコネクションは処理のループ外で1度だけ確立し、プリペアドステートメントを使用すること。図面1枚ごとにDBコネクションを張るような非効率な設計は、ネットワークのオーバーヘッドでシステム全体の寿命を縮める。
3. エラーログの永続化
現場のPC環境は千差万別だ。「フォントがない」「カスタムプロパティが存在しない」といった理由でマクロが沈黙することがある。必ず `Err.Number` と対象ファイル名をテキストログや社内サーバーに吐き出す構造を組み込んでおくこと。
—
総括
今回紹介した `ISketchHatch` と `INote` の融合制御は、単なる「手間の削減」ではない。「図面表現の標準化とヒューマンエラーの完全排除」という、設計部門における最高価値の具現化である。
オブジェクトのライフサイクルを理解し、堅牢なエラーハンドリングを網羅したコードベースであれば、現場のエンジニアたちは面倒な作図作業から解放され、本質的な「モノづくり・設計」に集中できるはずだ。
プロフェッショナルたるもの、動くだけのコードを書くな。「止まらない、拡張できる、美しいコード」を実装せよ。
