現場の混乱を鎮圧せよ:図面ビューの表示モードを「強制統一」する堅牢な設計思想
設計業務の自動化に取り組む際、初心者が最も陥りやすい罠がある。それは、「動けばいい」という思考停止のスクリプトを書いてしまうことだ。
特に図面(Drawing)の自動生成において、ビューの表示モード(隠線消去、隠線表示など)がバラバラな状態で納品されることは、設計品質における致命的な欠陥となる。ユーザーが誤って操作した、あるいはモデルの変更に伴って表示が変わってしまったビューを、いかに「エンジニアリングの力」で一括して、かつ安全に制御するか。
今回は、図面ビューの表示モードを「隠線消去(Hidden Lines Removed)」に強制適用するスクリプトを題材に、「単なるコードの書き写し」ではない、プロフェッショナルな自動化ツールの設計思想を伝授する。
1. なぜ、単純なループでは不十分なのか
多くの初心者は、以下のような思考でコードを書こうとする。
「図面を開く」→「ビューを全部取得する」→「表示モードを変える」
しかし、実務のSolidWorks APIは、そんなに甘くない。以下の3つのリスクを考慮しなければ、君のツールは現場で「使い物にならないバグの塊」として捨てられることになる。
1. ドキュメント型の不一致: 図面ファイルではない(部品やアセンブリ)状態で実行された場合、エラーで即死する。
2. シートとビューの階層構造: SolidWorksの図面構造は「Drawing > Sheet > View」という階層になっている。シートそのものをビューと誤認して処理しようとすると、予期せぬ挙動を招く。
3. パフォーマンスの欠如: ビューごとに画面更新(Redraw)を走らせていれば、ビュー数が多い図面では処理が極端に重くなる。
これらを回避するためには、「防御的プログラミング(Defensive Programming)」の概念が必要だ。
2. プロダクション品質の設計アーキテクチャ
堅牢なツールを作るための、私の設計指針は以下の通りだ。
- バリデーション(検証)の徹底: 処理を開始する前に、対象が本当に図面(swDocDRAWING)であるかを厳格にチェックする。
- 階層的トラバーサル(走査): シートを列挙し、各シート内のビューを走査するという、オブジェクトモデルに忠実なルートを辿る。
- 状態の一括管理: 処理中は画面更新を抑制し、最後に一括で再構築(Rebuild)を行う。これにより、ユーザーへの視覚的なノイズを減らし、実行速度を劇的に向上させる。
3. 【実践】隠線消去強制適用スクリプト
以下に、そのまま業務に投入できるレベルのコードを示す。これを単にコピペするのではなく、各行の「意図」を読み解いてほしい。
Option Explicit
''' <summary>
''' 図面内の全てのビューの表示モードを「隠線消去」に強制適用する。
''' </summary>
Public Sub ForceHiddenLinesRemoved()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim swSheet As SldWorks.Sheet
Dim swView As SldWorks.View
Dim vSheetNames As Variant
Dim i As Integer
Dim errorCount As Integer
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
' --- 1. バリデーション: ドキュメントが図面であるかを確認 ---
If swModel Is Nothing Then
MsgBox "ドキュメントが開かれていません。", vbCritical, "Error"
Exit Sub
End If
If swModel.GetType <> swDocDRAWING Then
MsgBox "このマクロは図面ファイル専用です。部品やアセンブリでは実行できません。", vbExclamation, "Type Mismatch"
Exit Sub
End If
Set swDraw = swModel
' 処理の高速化とチラつき防止のため、画面更新を抑制する思想を持つ
' (Note: SolidWorks APIには直接的なScreenUpdatingがないため、再描画のタイミングを制御する)
On Error GoTo ErrorHandler
errorCount = 0
' --- 2. 全シートの取得 ---
vSheetNames = swDraw.GetSheetNames
For i = 0 To UBound(vSheetNames)
' シートの切り替え
swDraw.ActivateSheet vSheetNames(i)
Set swSheet = swDraw.GetCurrentSheet
' --- 3. シート内のビューを走査 ---
' GetFirstViewは「シート自体」を指すビューを返すため、そのNextからが実際のモデルビューとなる
Set swView = swDraw.GetFirstView
Do While Not swView Is Nothing
' シート自体(最初のビュー)はスキップし、モデルビューのみを対象とする
' swView.Type が swDrawingViewType_e.swDrawingViewType_DrawingView であることを確認
If swView.Type <> swDrawingViewType_e.swDrawingViewType_Sheet Then
' 表示モードを「隠線消去 (swDrawingViewDisplayMode_e.swDrawingViewDisplayMode_HiddenLinesRemoved)」に設定
' 0 = Hidden Lines Removed
' 1 = Hidden Lines Visible
' 2 = Shaded with Edges
Dim status As Boolean
status = swView.SetDisplayMode2(swDrawingViewDisplayMode_e.swDrawingViewDisplayMode_HiddenLinesRemoved)
If Not status Then
errorCount = errorCount + 1
End If
End If
' 次のビューへ
Set swView = swView.GetNextView
Loop
Next i
' --- 4. 後処理: 再構築 ---
' 全ての変更を反映させるため、最後に一度だけリビルドを行う
swModel.ForceRebuild3 True
MsgBox "処理が完了しました。" & vbCrLf & _
"適用シート数: " & (UBound(vSheetNames) + 1) & vbCrLf & _
"エラー発生数: " & errorCount, vbInformation, "Success"
Exit Sub
ErrorHandler:
MsgBox "予期せぬエラーが発生しました。" & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Description: " & Err.Description, vbCritical, "Runtime Error"
End Sub
4. チーフアーキテクトの視点:コードの深層解説
このコードがなぜ「プロ仕様」なのか。その核心を解説する。
階層構造への理解:`GetFirstView` の罠
SolidWorksのAPIにおいて、`DrawingDoc.GetFirstView` は、モデルビューではなく「シートそのもの」を指す特殊なビューを返してくる。これを知らずに全てのビューに対して `SetDisplayMode2` を実行すると、シート全体のプロパティに干渉しようとして無意味な処理、あるいはエラーを招く。
私のコードでは、`swView.Type <> swDrawingViewType_e.swDrawingViewType_Sheet` という条件分岐を入れ、「真に操作すべきモデルビュー」のみを正確に射抜いている。
パフォーマンスの最適化:`ForceRebuild3` の位置
ループの中で `swModel.EditRebuild` を呼び出すのは、素人のやることだ。ビューが100個あれば、100回リビルドが走り、計算リソースを無駄に消費する。
プロは、「変更をメモリ上に溜め込み、最後に一撃で反映させる」。`swModel.ForceRebuild3 True` をループの外、全処理の最後に配置することで、計算負荷を最小限に抑えている。
エラーハンドリングの設計
`On Error GoTo ErrorHandler` は、単なるおまじないではない。自動化ツールが「なぜ止まったのか」をユーザーに明示的に伝えるための、責任ある設計である。実務では、エラーが発生した際にログを残す、あるいはエラー数をカウントして報告する仕組みが、ツールの信頼性を決定づける。
結論:自動化は「設計」である
「隠線消去にする」という一見単純なタスクであっても、その裏側にはオブジェクトのライフサイクル、階層構造、そしてパフォーマンスへの配慮が不可欠だ。
スクリプトを書くときは、常に自分に問いかけてほしい。
「このコードは、数千枚の図面があるプロジェクトでも、耐えうる設計か?」
もし答えが「NO」であれば、君はまだエンジニアリングの入り口に立っているに過ぎない。この知見を武器に、単なる作業の自動化を超えた、「堅牢なシステムの構築」へと踏み出してほしい。
