【Architect’s Insight】図面ビューの表示モードを支配せよ:堅牢な描画制御の実装戦略
多くのエンジニアが「マクロの記録」から自動化の第一歩を踏み出す。しかし、そこから一歩も進めず、現場で使い物にならない「動けばいいだけのツール」を量産してしまう。
今回のテーマは、SolidWorks図面における「ビューごとの表示スタイル(シェーディング、隠線、ワイヤーフレーム等)の個別制御」だ。
一見、単純なAPIの呼び出しに見えるだろう。しかし、大量のビューを持つ複雑な図面に対して、場当たり的なコードを投げれば、メモリの不整合や処理速度の著しい低下、最悪の場合はアプリケーションのクラッシュを招く。
本記事では、単なる「コードの書き方」ではなく、プロフェッショナルとして「いかにバグを排除し、計算資源を最適に使い、保守性の高い設計を行うか」という設計思想(アーキテクチャ)を伝授する。
1. 陥りやすい「素人レベル」の設計ミス
まず、初心者が書きがちなコードの構造を批判的に検討しよう。
' ❌ アンチパターン:典型的な「動けばいいだけ」のコード
Sub BadExample()
Dim swApp As SldWorks.SldWorks
Set swApp = Application.SldWorks
Dim swModel As SldWorks.ModelDoc2
Set swModel = swApp.ActiveDoc
Dim swDraw As SldWorks.DrawingDoc
Set swDraw = swModel
Dim v As Variant
Dim swView As SldWorks.View
' 全てのビューをループして、無理やり全部シェーディングにする
For Each v In swDraw.GetViews ' ※実際にはGetViewsというメソッドは存在しない(正しくはGetFirstViewから辿る)
Set swView = v
swView.SetDisplayMode 3 ' 魔法の数字(リテラル)の使用
Next
End Sub
なぜこのコードは「ゴミ」なのか?
1. オブジェクトの型チェックが皆無: `ActiveDoc` が図面(Drawing)でない場合、即座にランタイムエラーで落ちる。
2. APIの理解不足: SolidWorksのViewオブジェクトの走査は、`GetFirstView` から `GetNextView` を辿るリンクドリスト構造である。`For Each` で適当に回せるものではない。
3. マジックナンバーの乱用: `SetDisplayMode 3` の「3」が何を意味するか、コードを読んだ者に伝わらない。保守性が皆無だ。
4. パフォーマンスへの無配慮: ビューのスタイルを変更するたびに、SolidWorksはグラフィックスの再構築を試みる。大量のビューがある場合、描画更新の制御を行わないと、処理時間は指数関数的に増大する。
2. プロダクション・グレードの設計思想
プロのエンジニアとして、以下の3点を設計の柱に据える。
① 型の安全性とバリデーション
「入力が正しい」という前提を捨てろ。対象が図面か? ファイルは開いているか? ビューは存在するか? これらを徹底的に検証する。
② 列挙型(Enum)による可読性の確保
APIの定数は、必ず意味のある名前で定義するか、SolidWorksが提供する列挙型を使用せよ。
③ 描画更新のバッチ処理
スタイル変更は「一括」で行う。一回変更するたびに画面を更新させるのではなく、すべての変更を終えてから、最後に一度だけリフレッシュさせるのが鉄則だ。
3. 実践:堅牢なビュー制御エンジンの実装
以下に、そのままプロダクション環境に投入できるレベルのコードを示す。このコードは、特定の条件(例えば「等角投影図ならシェーディング、直交投影図なら隠線」)に基づいてビューを制御するロジックを組み込めるように設計している。
Option Explicit
' ==============================================================================
' Module: DrawingViewController
' Description: 図面ビューの表示スタイルを高度に制御するためのモジュール
' ==============================================================================
''' <summary>
''' 指定した図面内のビューに対して、表示モードを一括制御する。
''' </summary>
Public Sub ApplySmartViewStyles()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
On Error GoTo ErrorHandler
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
' 1. バリデーション: ドキュメントが開かれているか、かつ図面ドキュメントか
If swModel Is Nothing Then
MsgBox "エラー: ドキュメントが開かれていません。", vbCritical
Exit Sub
End If
If swModel.GetType <> swDocDRAWING Then
MsgBox "エラー: アクティブなドキュメントが図面ではありません。", vbCritical
Exit Sub
End If
Set swDraw = swModel
' 2. グラフィックス更新の抑制(パフォーマンス最適化)
' 描画の更新を一時的に止めることで、ループ中の再計算コストを最小化する
swModel.LockGraphics = True
Dim swView As SldWorks.View
Dim swSheet As SldWorks.Sheet
' 3. ビューの走査 (GetFirstViewはシート自体を指すため注意が必要)
Set swView = swDraw.GetFirstView ' これは「Sheet」ビュー
' シートビュー自体はスキップし、モデルビューから処理を開始する
Set swView = swView.GetNextView
Do While Not swView Is Nothing
' 4. ビジネスロジック: ビューのタイプに基づいた条件分岐
' ここでは例として「等角投影図(IsIsometric)」か否かで切り分ける
Dim viewType As String
viewType = swView.Type ' 必要に応じてビュー名を判定材料にする
' 表示モードの決定
' swDisplayMode_e の定数を利用
' 0: Wireframe, 1: Shaded, 2: Hidden Lines Removed, etc.
Dim targetMode As Long
If IsIsometricView(swView) Then
targetMode = swDisplayMode_e.swDisplayMode_Shaded
Else
targetMode = swDisplayMode_e.swDisplayMode_HiddenLinesRemoved
End If
' 5. API実行
swView.SetDisplayMode2 targetMode
' 次のビューへ
Set swView = swView.GetNextView
Loop
' 6. 後処理: 描画のロック解除と再描画
swModel.LockGraphics = False
swModel.GraphicsRedraw2
MsgBox "ビューの更新が完了しました。", vbInformation
CleanUp:
Exit Sub
ErrorHandler:
' エラー発生時も必ずロックを解除してプロセスを正常終了させる
swModel.LockGraphics = False
MsgBox "致命的なエラーが発生しました: " & Err.Description, vbCritical
Resume CleanUp
End Sub
''' <summary>
''' ビューが等角投影図であるかを判定するヘルパー関数
''' </summary>
Private Function IsIsometricView(view As SldWorks.View) As Boolean
' 実務ではビューの名前や、投影方向のベクトルから判定するロジックをここに実装する
' 今回は簡略化のため、ビュー名に "ISO" が含まれているかで判定する例とする
If InStr(1, view.Name, "ISO", vbTextCompare) > 0 Then
IsIsometricView = True
Else
IsIsometricView = False
End If
End Function
4. アーキテクトからのアドバイス
パフォーマンスの鍵:`LockGraphics`
コード内で使用した `swModel.LockGraphics = True`。これは、大規模なアセンブリ図面を扱う際に「命」となるプロパティだ。これを怠ると、ビューを1つ変えるたびにSolidWorksが全画面の再計算を行うため、100個のビューがある図面では、処理時間が数分から数秒へと劇的に変わる。
拡張性:ロジックの分離
`ApplySmartViewStyles` というメインルーチンの中に、判定ロジック(`IsIsometricView`)を直接書き込んではいけない。今回のように、判定ロジックを「ヘルパー関数」として切り出すことで、将来的に「ビューの名前ではなく、レイヤー名で判定したい」「特定の属性に基づいて判定したい」といった仕様変更が来た際、メインのフローを壊さずに修正が可能になる。これが「保守性の高いコード」の正体だ。
データベース連携への布石
もし、このツールを「Excelのリストに基づいた自動生成ツール」へと昇華させるなら、`targetMode` を決定する部分を、Excelから読み込んだパラメータ(`swDisplayMode_e` の値)に置き換えるだけでいい。設計が分離されていれば、この移行は容易だ。
結論
VBAは単なる「自動化の手段」ではない。それは、複雑なエンジニアリングプロセスを制御するための「ソフトウェア開発」そのものである。
型を意識し、エラーを予見し、計算資源を敬え。この規律を守る者だけが、現場で真に信頼されるツールを構築できる。
