【実務・中級編】【中級者向け】アセンブリ図面における「部品番号の連番(バブル)」の自動付与と並び順制御 – SolidWorks VBA解析バイブル

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

秩序なき図面を制する:BOM同期型バルーン自動配置アルゴリズムの設計思想

設計現場において、アセンブリ図面の「バルーン(部品番号)」の配置は、エンジニアの精神を最も削る作業の一つだ。

「BOMの順番とバラバラだ」「引き出し線が重なってスパゲッティ状態だ」「部品を追加したら番号がズレた」――。これらはすべて、「図面を単なる『絵』として扱い、データ構造(BOM)との同期を軽視している」ことに起因する。

多くのプログラマが陥る罠は、`DrawingDoc.GetFirstBalloon` のように、図面に既に存在するオブジェクトをループで回して位置を調整しようとすることだ。そんなものは「修正ツール」であって「自動生成エンジン」ではない。

真に堅牢な自動化ツールを構築するには、「BOMを正(Single Source of Truth)とし、図面ビュー上の幾何学的座標を決定論的に計算する」というアーキテクチャが必要だ。

本稿では、中級者以上のエンジニアに向けて、BOMの並び順に基づいたバルーンの自動配置と、保守性の高いコード設計について、その極限の知見を伝授する。

1. アーキテクチャ設計:なぜ「既存のバルーン操作」では失敗するのか

一般的な「バルーン整理マクロ」は、既存のバルーンを一つずつ取得し、そのテキストを読み取り、位置を動かすというアプローチをとる。しかし、これには致命的な欠陥がある。

1. データの不整合: BOMの行が入れ替わった際、既存のバルーンの「テキスト」と「BOMのインデックス」の紐付けが崩壊する。
2. 計算コストの増大: 既存オブジェクトの検索とプロパティ書き換えは、オブジェクトモデルの再構築を頻繁に引き起こし、大規模アセンブリでは極めて低速になる。
3. 幾何学的制御の欠如: 既存の配置に依存するため、新しい部品が増えた際に「どこに置くべきか」という空間的な判断ができない。

推奨される設計フロー

我々が実装すべきは、以下の「Destroy & Rebuild(破壊と再構築)」戦略だ。

1. Extract: BOMから「部品名」「部品番号」「数量」のリストをメモリ上に抽出する。
2. Locate: 図面ビュー内の各コンポーネントの「重心座標(Center of Gravity)」または「境界ボックスの中心」を特定する。
3. Calculate: 重心座標に基づき、衝突を回避する「配置予定座標」を計算する。
4. Execute: 既存のバルーンを一旦クリアし、計算結果に基づいて新しいバルーンを「一括生成」する。

2. 実装の核心:BOM同期型バルーン配置アルゴリズム

以下に、プロダクション環境で耐えうる堅牢な設計思想に基づいたVBAコードの骨子を示す。ここでは、単なるコピペ用コードではなく、「エラーハンドリング」と「オブジェクトのライフサイクル管理」を組み込んだ、設計図としてのコードを提示する。

Option Explicit

' ==============================================================================
' Module: BalloonAutomationEngine
' Description: BOMの並び順に基づき、図面ビューへバルーンを最適配置する
' Author: Chief Architect
' ==============================================================================

Sub Main()
    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 Exit Sub
    If swModel.GetType <> swDocDRAWING Then
        MsgBox "図面ファイルを開いた状態で実行してください。", vbCritical
        Exit Sub
    End If
    
    Set swDraw = swModel
    
    ' 2. 処理の開始(パフォーマンス向上のため再描画を抑制)
    swModel.LockVisualUpdates = True
    
    ' 3. メインプロセスの実行
    ' ここでは、アクティブなシートの最初のビューを対象とする
    Dim swSheet As SldWorks.Sheet
    Set swSheet = swDraw.GetCurrentSheet
    
    Dim swView As SldWorks.View
    Set swView = swDraw.GetFirstView ' Sheet自体が最初のViewとして取得される
    Set swView = swView.GetNextView  ' 次のView(実際の投影図)へ移動
    
    If Not swView Is Nothing Then
        Debug.Print "Processing View: " & swView.Name
        ProcessViewBOMAlignment swView
    Else
        MsgBox "有効なビューが見つかりません。", vbExclamation
    End If

CleanUp:
    ' 4. 後処理(必ず実行されるべきリソース解放)
    swModel.LockVisualUpdates = False
    swModel.ForceRebuild3 True
    Set swDraw = Nothing
    Set swModel = Nothing
    Set swApp = Nothing
    Exit Sub

ErrorHandler:
    MsgBox "致命的なエラーが発生しました: " & Err.Description, vbCritical
    Resume CleanUp
End Sub

''' <summary>
''' 指定されたビュー内のコンポーネントをBOM順に走査し、バルーンを配置する
''' </summary>
Private Sub ProcessViewBOMAlignment(ByRef swView As SldWorks.View)
    Dim swModel As SldWorks.ModelDoc2
    Set swModel = swView.ReferencedDocument
    
    ' --- [重要] ここでBOMデータを取得するロジックを分離して実装すべき ---
    ' 今回は概念を示すため、ビュー内のコンポーネントを直接走査する
    ' 実際の実務では、BOMテーブルからItemNumberを取得する関数を介すこと
    
    Dim swComp As SldWorks.Component2
    Dim swAnnotation As SldWorks.Annotation
    Dim swBalloon As SldWorks.Note ' バルーンはNoteオブジェクトとして扱われる
    
    Dim vComps As Variant
    vComps = swView.GetVisibleEntities2(swView.GetFirstEntity, swEntityQuery_Components)
    ' ※実際には GetVisibleEntities2 の使い方は複雑なため、
    ' 投影図内のコンポーネントリストを適切に取得するロジックが必要
    
    ' 仮のループ処理(設計思想の提示)
    ' 1. 既存のバルーンを削除
    DeleteExistingBalloons swView
    
    ' 2. コンポーネントをBOM順にループ
    ' ※ 本来は BOM Table から ItemNumber を引き、その番号に対応するComponentを探す
    ' 以下のコードは、その「配置ロジック」の核心部である
    
    Dim i As Integer
    For i = 0 To 10 ' 仮のループ
        ' [Step A] コンポーネントの幾何学的中心を取得
        ' [Step B] 配置座標の計算 (Collision Avoidance Algorithm)
        ' [Step C] Balloonの生成
        ' CreateSmartBalloon swView, compCenterPos, itemNumber
    Next i
    
    Debug.Print "Alignment Complete."
End Sub

''' <summary>
''' ビュー内の既存バルーンを安全に削除する
''' </summary>
Private Sub DeleteExistingBalloons(ByRef swView As SldWorks.View)
    Dim swAnn As SldWorks.Annotation
    Set swAnn = swView.GetFirstAnnotation
    
    Do While Not swAnn Is Nothing
        ' バルーンタイプ(AnnotationType)を確認して削除
        If swAnn.GetAnnotationType = swAnnotationType_e.swAnnotationType_Balloon Then
            swAnn.GetAnnotation.Remove
        End If
        Set swAnn = swAnn.GetNext
    Loop
End Sub

''' <summary>
''' 幾何学的計算に基づきバルーンを生成する(設計の肝)
''' </summary>
Private Sub CreateSmartBalloon(ByRef swView As SldWorks.View, ByVal centerPos As Variant, ByVal itemNum As String)
    ' ここに「中心から半径Rの円周上に配置する」
    ' あるいは「グリッド状に配置する」といった幾何学アルゴリズムを実装する
    ' 単に centerPos + Offset とするだけでは、部品が密集した際に破綻する
End Sub

3. プロフェッショナルのための技術的アドバイス

幾何学的配置アルゴリズムの選択

バルーンの配置において、最も困難なのは「重なり(Collision)」の回避だ。実務的な解法として、以下の2段階アプローチを推奨する。

1. Radial Placement(放射状配置):
コンポーネントの重心を中心とし、一定の距離($R$)を保った円周上の座標 $(x, y) = (x_c + R\cos\theta, y_c + R\sin\theta)$ を計算する。$\theta$ は、部品の「詰まり具合」に応じて、既存のバルーンとの角度差を計算して決定する。
2. Grid-based Offset(グリッド・オフセット):
部品が極端に密集している場合、放射状では円周が重なりすぎる。その場合は、コンポーネントのBounding Box(境界ボックス)の外側に、仮想的なグリッドを生成し、空いているセルに配置する。

パフォーマンスを支配する「Update抑制」

SolidWorks APIを叩く際、最もコストが高いのは「モデルの再構築(Rebuild)」だ。
バルーンを1つ作るたびに図面全体が再計算されるような実装は、エンジニアを待たせる「質の低いツール」の証だ。
必ず `swModel.LockVisualUpdates = True` を使用し、全てのオブジェクト生成が終わった後に、一度だけ `ForceRebuild3` を実行せよ。

データベース(BOM)との連携における注意点

BOMは「アセンブリファイル」に内包されている場合と、「Excel」などの外部ファイルである場合がある。
ツールを設計する際は、「データ取得層(Data Layer)」を分離せよ。

  • `GetBOMData()` という関数をインターフェースとして定義し、中身がExcelからなのか、SolidWorksのBOMテーブルからなのかを、メインロジック(配置エンジン)に意識させない設計にすること。これが、保守性の高いコードを作るための鉄則だ。

結論:自動化とは「秩序の構築」である

バルーンの自動配置は、単なる座標計算ではない。それは、「設計意図(BOM)」を「視覚的情報(図面)」へと、数学的根拠を持って変換する作業である。

「なんとなく動く」コードを書くのは今日で終わりにしよう。
「なぜその位置に配置されるのか」を論理的に説明でき、BOMの変更に対して強靭な、プロフェッショナルなアーキテクチャを構築してほしい。

それが、世界最高峰のエンジニアリングを支える自動化への第一歩だ。

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