【テクニカル・上級編】【初心者向け】図面ビューの「非表示エッジ(Hidden Lines Removed)」表示モード強制適用VBA – SolidWorks VBA解析バイブル

スポンサーリンク
スポンサーリンク

幾何学的整合性の強制:図面ビューの表示モード統一におけるアーキテクチャ設計

設計業務の自動化において、我々エンジニアが直面するのは「コードが動くか」という初歩的な問題ではない。「そのコードが、大規模なレガシー環境や、予測不能なユーザー操作が入り混じる実務の荒波の中で、どれほど堅牢(Robust)であり続けられるか」という問題だ。

図面(Drawing)の自動生成において、最も頻繁に、かつ致命的に発生する不整合の一つが、ビューの表示モードの乱れである。あるビューは「隠線消去(Hidden Lines Removed)」、別のビューは「隠線表示(Hidden Lines Visible)」。この些末な差異が、図面規約(Standard)への違反となり、検図工程での手戻りを生む。

本稿では、単なる「ループを回してプロパティを変える」というレベルのスクリプトではない。オブジェクトのライフサイクル、メモリ管理、そして実行パフォーマンスを極限まで考慮した、実戦的な「表示モード強制適用」の設計思想を詳解する。

1. オブジェクト・ツリーの構造的理解

SolidWorks APIを操作する際、多くの初学者が陥る罠は、オブジェクトの階層構造(Hierarchy)に対する認識の甘さである。図面ファイルにおけるビューの走査は、以下の階層を辿るプロセスとなる。

`SldWorks (Application)` $\rightarrow$ `ModelDoc2 (DrawingDoc)` $\rightarrow$ `Sheet` $\rightarrow$ `View`

ここで重要な知見がある。`DrawingDoc::GetFirstView` メソッドが返す最初のオブジェクトは、「モデルビュー」ではなく「シート自体」を指す特殊なビューオブジェクトであるという点だ。これを見落とすと、シート自体のプロパティを書き換えようとしてエラーを吐くか、あるいは最初のモデルビューをスキップするというバグを誘発する。

2. パフォーマンスとメモリの最適化:アーキテクトの作法

大規模なアセンブリ図面では、ビューの数が数十、数百に及ぶことがある。各ビューに対して表示モードを変更するたびに、SolidWorksのグラフィックス再描画(Redraw)が走れば、実行時間は指数関数的に増大し、最悪の場合、アプリケーションは応答なしの状態に陥る。

我々が取るべき戦略は以下の3点だ。

1. 描画更新の抑制: 処理中、画面更新を停止し、計算コストを最小化する。
2. 明示的なオブジェクト解放: VBAのガベージコレクションに頼らず、`Set obj = Nothing` を用いてメモリ空間を即座に解放する。これは、長時間稼働するバッチ処理や、サーバーサイドでの自動生成において、メモリリークを防ぐための鉄則である。
3. 例外処理(Error Handling)の構築: 特定のビューが破損している、あるいは特殊なプロパティを持っている場合でも、プロセス全体を停止させないための「耐性」を持たせる。

3. 実装:堅牢な表示モード強制適用スクリプト

以下に、シニアエンジニアが実戦で用いるレベルのコードを示す。これは単なる「書き換え」ではなく、「整合性の確保」を目的とした設計である。

' **
' Module: DrawingStandardization
' Description: 強制的に全てのビューの表示モードを「隠線消去」に統一する
' Author: Chief Architect
' **

Option Explicit

' SolidWorks Constants (定義されていない環境のためのバックアップ)
Private Const swViewHiddenLinesRemoved As Long = 3
Private Const swViewHiddenLinesVisible As Long = 2

Sub ForceAllViewsToHiddenLinesRemoved()
    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 sheetNames As Variant
    Dim i As Long
    Dim viewCount As Long
    
    ' エラーハンドリングの開始
    On Error GoTo ErrorHandler

    ' 1. アプリケーションおよびドキュメントの取得
    Set swApp = Application.SldWorks
    Set swModel = swApp.ActiveDoc

    ' ドキュメントが図面でない場合は即時終了
    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.GraphicsRedraw = False

    ' 3. 全シートの走査
    ' 全てのシートを確実に処理するため、シート名のリストを取得
    sheetNames = swDraw.GetSheetNames

    For i = 0 To UBound(sheetNames)
        ' シートの切り替え
        swDraw.ActivateSheet sheetNames(i)
        Set swSheet = swDraw.GetCurrentSheet
        
        ' 4. ビューの走査
        ' GetFirstViewは「シートビュー」を返す。その次のViewからが実際のモデルビューである。
        Set swView = swDraw.GetFirstView
        
        If Not swView Is Nothing Then
            ' シートビューをスキップし、最初のモデルビューへ移動
            Set swView = swView.GetNextView
            
            Do While Not swView Is Nothing
                ' 表示モードの取得と判定(無駄なAPIコールを避ける)
                ' swViewDisplayMode プロパティの現在の状態を確認
                If swView.DisplayMode <> swViewHiddenLinesRemoved Then
                    ' 表示モードの強制適用
                    swView.DisplayMode = swViewHiddenLinesRemoved
                    viewCount = viewCount + 1
                End If
                
                ' 次のビューへ
                Set swView = swView.GetNextView
            Loop
        End If
        
        ' ライフサイクル管理: シートオブジェクトの解放
        Set swSheet = Nothing
    Next i

    ' 5. 後処理
    ' 描画更新を再開
    swModel.GraphicsRedraw = True
    swModel.ForceRebuild3 True
    
    MsgBox "処理完了。" & vbCrLf & _
           "変更されたビュー数: " & viewCount, vbInformation, "System Integrity Check"

CleanUp:
    ' メモリ解放の徹底
    Set swView = Nothing
    Set swSheet = Nothing
    Set swDraw = Nothing
    Set swModel = Nothing
    Set swApp = Nothing
    Exit Sub

ErrorHandler:
    swModel.GraphicsRedraw = True
    MsgBox "致命的なエラーが発生しました。" & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Description: " & Err.Description, vbCritical, "Architecture Error"
    Resume CleanUp
End Sub

4. 結論:エンジニアリングの本質

このスクリプトにおいて、我々が意図的に行っているのは「単なる自動化」ではない。

  • `swModel.GraphicsRedraw = False`: ユーザーの視覚的なフィードバックよりも、プロセスの完遂と計算リソースの節約を優先する判断。
  • `If swView.DisplayMode <> swViewHiddenLinesRemoved`: 状態の変化がない場合にAPIを叩かないという、無駄なI/Oを削ぎ落とす最適化。
  • `CleanUp` セクション: どのようなエラー経路を辿ったとしても、必ずメモリを解放し、SolidWorksのグラフィックス状態を正常に戻すという、システムの整合性に対する責任。

シニアエンジニアとして、あるいはシステム管理者として、コードを書く際には常に自問してほしい。「このコードは、1000個の図面を、サーバー上で一晩中回し続けても、メモリを食いつぶさずに、かつ正確に完遂できるか?」と。

技術の真髄は、華やかな機能の実装にあるのではない。「例外的な状況下でも、設計者の意図した通りの秩序(Order)を維持し続ける能力」にあるのだ。

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