【実務・中級編】【初心者向け】図面ビュー内の中心マーク(Center Mark)非表示設定を一括適用するVBAマクロ – SolidWorks VBA解析バイブル

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

【SolidWorks VBA】図面のノイズを制御せよ:中心マーク一括削除による「プロフェッショナルな図面」の自動生成術

設計現場において、モデル(3D)と図面(2D)の整合性を保つことは至上命題である。しかし、モデル側のフィーチャー(穴や円筒形状)に紐付いて、図面ビューへ「過剰に自動生成される中心マーク」に悩まされたことはないだろうか?

これらは、図面を不必要に煩雑にし、視認性を低下させる。さらには、図面ファイル自体のデータ容量を肥大化させ、表示パフォーマンスを阻害する「ノイズ」である。

本記事では、単に「中心マークを消す」という初歩的な作業を超え、実務に耐えうる堅牢な設計思想に基づいた、図面クレンジング・マクロの構築術を伝授する。

1. アーキテクトの視点:なぜ「単純なループ」では失敗するのか

初心者が陥る最大の罠は、コレクション(集合体)を走査しながら、その要素を削除しようとすることだ。

致命的な設計ミス:前方走査(Forward Loop)

例えば、図面内のアノテーション(注記)を `0` から `Count – 1` までループで回し、条件に合致したものを `Delete` していくコードを書いたとしよう。

' 【アンチパターン:絶対に真似してはいけない】
For i = 0 To annotationCount - 1
    Set swAnn = swView.GetAnnotation(i)
    If swAnn.GetType = swAnnotationType_e.swAnnotationType_CenterMark Then
        swAnn.Delete ' ここで要素が消えると、インデックスが詰まり、次の要素がスキップされる
    End If
Next i

要素を削除した瞬間、コレクションのインデックスは再構成される。つまり、削除した直後の要素は、次のループでスキップされてしまうのだ。これは、大規模な図面を処理する際、消し残しが発生する原因となる。

正解:後方走査(Backward Loop)

プロフェッショナルのコードは、常に「末尾から先頭へ」向かって走査する。これならば、要素を削除しても、未処理の要素のインデックスには影響を与えない。

2. 実装戦略:オブジェクト階層の完全掌握

図面操作のAPIリファレンスを読み解くと、以下の階層構造を辿ることがわかる。

1. `DrawingDoc`: 図面ドキュメント全体
2. `Sheet`: 各シート
3. `View`: 各ビュー(投影図、詳細図など)
4. `Annotation`: ビュー内に存在する注記(中心マーク、寸法、注記など)

我々の任務は、`View` の中にある `Annotation` を特定し、その `Type` が `swAnnotationType_CenterMark` であるものを見つけ出し、抹消することだ。

3. プロダクション・コード:堅牢な中心マーク・クリーナー

以下に、そのまま実務へ投入可能なレベルのコードを示す。エラーハンドリング、後方走査、そしてオブジェクトの解放を考慮した設計となっている。

Option Explicit

'' <summary>
''' 図面内の全てのシート、全てのビューを走査し、
''' 自動生成された中心マークを一括削除する。
''' </summary>
Public Sub CleanAllCenterMarks()
    Dim swApp As SldWorks.SldWorks
    Dim swModel As SldWorks.ModelDoc2
    Dim swDraw As SldWorks.DrawingDoc
    Dim swSheet As SldWorks.Sheet
    Dim vSheetNames As Variant
    Dim i As Integer, j As Integer, k As Integer
    Dim swView As SldWorks.View
    Dim swAnn As SldWorks.Annotation
    Dim annCount As Long
    
    ' エラーハンドリングの開始
    On Error GoTo ErrorHandler

    Set swApp = Application.SldWorks
    Set swModel = swApp.ActiveDoc

    ' 1. ドキュメントの型チェック(図面でない場合は終了)
    If swModel Is Nothing Then Exit Sub
    If swModel.GetType <> swDocDRAWING Then
        MsgBox "図面ファイルを開いた状態で実行してください。", vbCritical
        Exit Sub
    End If

    Set swDraw = swModel

    ' 画面更新を停止してパフォーマンスを向上させる(APIの制約により限定的だが習慣として)
    ' ※SolidWorks VBAでは完全に止めることは難しいが、処理の重い操作の前には意識すべき
    
    ' 2. 全てのシート名をループ
    vSheetNames = swDraw.GetSheetNames
    
    For i = 0 To UBound(vSheetNames)
        ' シートの切り替え
        swDraw.ActivateSheet vSheetNames(i)
        Set swSheet = swDraw.GetCurrentSheet
        
        ' 3. ビューの走査(シート内の全ビュー)
        ' GetFirstViewはシート自体を指すため、次のViewからが実際の投影図となる
        Set swView = swDraw.GetFirstView
        
        While Not swView Is Nothing
            ' ビュー内のアノテーション数を取得
            annCount = swView.GetAnnotationCount
            
            ' 4. 【重要】後方走査によるアノテーションの削除
            ' インデックスが詰まるのを防ぐため、末尾から 0 に向かってループする
            For k = annCount - 1 To 0 Step -1
                Set swAnn = swView.GetAnnotation(k)
                
                ' アノテーションの型を確認
                If Not swAnn Is Nothing Then
                    If swAnn.GetType = swAnnotationType_e.swAnnotationType_CenterMark Then
                        ' 中心マークを削除
                        swAnn.Delete
                    End If
                End If
            Next k
            
            ' 次のビューへ
            Set swView = swView.GetNextView
        Wend
    Next i

    ' 5. 変更を反映
    swModel.ForceRebuild3 True
    MsgBox "図面クリーニングが完了しました。", vbInformation

    Exit Sub

ErrorHandler:
    MsgBox "予期せぬエラーが発生しました。" & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Description: " & Err.Description, vbCritical
End Sub

4. 設計の深掘り:実務で差がつく3つのポイント

① `GetFirstView` の罠

`swDraw.GetFirstView` は、実は「シートそのもの」を指す特殊なビューを返す。実際の投影図(Front View等)は、その `GetNextView` から始まる。この階層構造を理解していないと、最初のビューをスキップしてしまうミスを犯す。

② パフォーマンスの最適化

大規模なアセンブリ図面では、ビューの数が数百に及ぶこともある。
このマクロでは `swModel.ForceRebuild3 True` を最後に一度だけ実行している。ループ内で毎回 `ForceRebuild` を呼び出すのは、エンジニアとして「敗北」を意味する。再構築は、全てのデータ操作が完了した後の「最後の一撃」であるべきだ。

③ 削除(Delete)か、非表示(Hide)か

本コードでは `Delete` を採用している。これは「図面をクリーンにする」という目的に対して最も効果的だ。しかし、もし「後で元に戻せる可能性を残したい」という要件があるならば、`swAnn.IsVisible = False` に書き換えるべきだ。
「破壊的変更を行うコードには、常にその意図を明確にする」。これが、保守性の高いツールを作る上での鉄則である。

まとめ

自動化エンジニアの仕事は、単に「動くもの」を作ることではない。
「例外に強く、データ構造を理解し、計算量を最小限に抑えた、信頼されるツール」を作ることだ。

今回学んだ「後方走査」と「オブジェクト階層の正しい走査」は、SolidWorks VBAに限らず、あらゆるコレクション操作の基本である。この知見を胸に、次の開発に挑んでほしい。

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