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

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

図面情報の「浄化」:中心マークの自動制御によるアノテーション・ポリューションの排除

設計業務の自動化において、多くのエンジニアが「フィーチャーの生成」や「寸法値の取得」といった、目に見える成果に目を奪われがちだ。しかし、真に堅牢なシステムを構築するアーキテクトが注視するのは、図面データが孕む「ノイズ(汚染)」である。

SolidWorksの仕様上、3Dモデル側の円筒面や球面に設定された中心線情報は、図面ビューへ投影される際、意図しない「中心マーク(Center Mark)」として大量に自動生成される。これが、大規模アセンブリの図面において、視認性の低下、ファイルサイズの肥大化、そして何より、後続の図面検図プロセスにおける「認知負荷」という致命的なコストを引き起こす。

本稿では、図面ビュー内に散らばる不要な中心マークを一括で制御(非表示化)するための、極めて実戦的なVBA実装手法を解説する。単なる「動くコード」ではない。メモリ管理、オブジェクトのライフサイクル、そして大規模環境でのパフォーマンスを考慮した、プロフェッショナルな実装を提示する。

1. アーキテクチャの設計思想:オブジェクト・トラバーサル

図面内のアノテーション(注釈)を操作するには、SolidWorksのオブジェクト階層を正確に辿る必要がある。

1. DrawingDoc: 図面ドキュメントのルート。
2. Sheet: 図面内の各シート。
3. View: 各シートに配置された各ビュー。
4. Annotation: ビュー内に存在する個々の注釈オブジェクト。

ここで重要なのは、`View`オブジェクトから直接`CenterMark`を叩くのではなく、`Annotation`オブジェクトの型(`AnnotationType`)を判定し、それが`swAnnotationType_e.swAnnotationType_CenterMark`であるかを識別するプロセスを挟むことだ。これにより、寸法や引き出し線といった他の重要なアノテーションを破壊することなく、ターゲットのみをピンポイントで制御できる。

2. 極限の実装:最適化された一括制御マクロ

以下のコードは、単にループを回すだけでなく、メモリリークを防ぐための明示的なオブジェクト解放と、実行速度を最大化するための処理を組み込んだものである。

Option Explicit

''' <summary>
''' 図面内の全ビューを走査し、中心マークを非表示にする。
''' プロフェッショナル向け実装:メモリ管理とオブジェクトライフサイクルを考慮。
''' </summary>
Public Sub PurgeCenterMarks()
    ' --- 1. オブジェクト宣言 ---
    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 swAnn As SldWorks.Annotation
    Dim vSheetNames As Variant
    Dim i As Long
    Dim count As Long
    
    ' 実行速度向上のためのエラーハンドリング
    On Error GoTo ErrorHandler

    ' --- 2. 初期化 ---
    Set swApp = Application.SldWorks
    Set swModel = swApp.ActiveDoc

    ' 図面ドキュメントであることを確認
    If swModel Is Nothing Then Exit Sub
    If swModel.GetType <> swDocDRAWING Then
        MsgBox "図面ファイルを開いた状態で実行してください。", vbCritical
        Exit Sub
    End If

    Set swDraw = swModel
    vSheetNames = swDraw.GetSheetNames
    count = 0

    ' UIの更新を抑制(描画負荷の低減)
    ' ※SolidWorks APIには直接的な"ScreenUpdating = False"はないが、
    ' 画面更新を伴う操作を最小限にすることで同等の効果を得る。
    
    ' --- 3. メイン・ループ:シート単位の走査 ---
    For i = 0 To UBound(vSheetNames)
        swDraw.ActivateSheet vSheetNames(i)
        Set swSheet = swDraw.GetCurrentSheet
        
        ' ビューの走査(最初のビューはシート自体を示すため、GetFirstViewから開始)
        Set swView = swDraw.GetFirstView
        
        Do While Not swView Is Nothing
            ' --- 4. アノテーションの走査 ---
            Set swAnn = swView.GetFirstAnnotation
            
            Do While Not swAnn Is Nothing
                ' 中心マーク(Center Mark)であるか判定
                If swAnn.GetType = swAnnotationType_e.swAnnotationType_CenterMark Then
                    ' 非表示に設定(削除ではなく非表示にすることで、データの完全性を保つ)
                    swAnn.IsVisible = False
                    count = count + 1
                End If
                
                ' 次のアノテーションへ(ここでの参照渡しに注意)
                Set swAnn = swAnn.GetNext
            Loop
            
            ' 次のビューへ
            Set swView = swView.GetNext
        Loop
        
        ' シートオブジェクトの解放
        Set swSheet = Nothing
    Next i

    ' --- 5. 終了処理とクリーンアップ ---
    swModel.ForceRebuild3 True
    MsgBox count & " 個の中心マークを非表示にしました。", vbInformation

CleanUp:
    ' メモリの明示的解放(COMオブジェクトのライフサイクル管理)
    ' これを怠ると、長時間稼働するサーバーサイドでの自動化においてメモリリークを引き起こす。
    Set swAnn = Nothing
    Set swView = Nothing
    Set swSheet = Nothing
    Set swDraw = Nothing
    Set swModel = Nothing
    Set swApp = Nothing
    Exit Sub

ErrorHandler:
    MsgBox "予期せぬエラーが発生しました: " & Err.Description, vbCritical
    Resume CleanUp
End Sub

3. アーキテクトの視点:なぜ「削除」ではなく「非表示」なのか

シニアエンジニアがこのコードをレビューする際、必ず「`swAnn.Delete` ではなく、なぜ `swAnn.IsVisible = False` を選択したのか?」という問いを投げかけるだろう。これに対する答えは、「データの完全性とトレーサビリティ」にある。

1. 非可逆性の回避: `Delete` メソッドはオブジェクトをメモリから完全に抹消する。もし、特定の条件下でのみ中心マークが必要になった場合、マクロを再度走らせることはできず、手動での再生成を強いることになる。
2. システム間連携(PDM/PLM)への影響: PDM(Product Data Management)環境下では、図面データの変更履歴が厳格に管理される。オブジェクトの「削除」は大きな変更履歴として記録されるが、「属性(可視性)の変更」は、設計意図に基づく制御として管理しやすい。
3. ロールバックの容易性: `IsVisible = True` に戻すロジックを別途用意しておけば、簡単に「浄化」前の状態へ復元できる。これは、自動化システムにおける「安全装置」として機能する。

4. パフォーマンス最適化の極意

大規模な図面(シート数が数十枚、ビューが数百ある場合)において、上記のコードをそのまま走らせると、描画の更新プロセスがボトルネックとなり、実行時間が指数関数的に増大する。

更なる高みを目指すならば、以下の技術的アプローチを検討せよ。

  • `swModel.ForceRebuild3` の実行タイミング: ループ内で毎回リビルドをかけるのは愚策だ。すべての処理が完了した後に一度だけ呼び出すのが鉄則である。
  • Windows APIによる描画制御: VBAの限界を超える場合、`SendMessage` を用いて、SolidWorksのウィンドウに対して `WM_SETREDRAW` メッセージを送り、描画を完全にロックする手法がある。これにより、処理中の「画面のチラつき」を抑え、CPUリソースをロジック計算に集中させることができる。
  • オブジェクトの明示的解放 (`Set = Nothing`): VBAは参照カウント方式を採用しているが、複雑な階層構造を持つCOMオブジェクトを扱う場合、参照の循環(Circular Reference)が発生し、メモリが解放されないケースがある。ループの各段階で、使用済みのオブジェクトを明示的に `Nothing` にすることは、レガシー環境でも最新の64bit環境でも、システムの安定性を担保する唯一の手段である。

結論

図面自動化の真髄は、単に作業を速めることではない。「ノイズのない、高品質なデータを、いかに低コストで生成し続けるか」という設計思想にある。中心マークの制御という一見些細なタスクに、こうしたアーキテクチャの視点を持ち込むことこそが、シニアエンジニアと初級者の分水嶺となる。

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