【入門編】【中級者向け】部品表(BOM)の特定カラム(重量や備考欄)の値を自動計算して上書きするVBA – SolidWorks VBA解析バイブル

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

マクロ記録の限界を超えろ:BOMテーブルを自在に操る「セル走査」の極意

こんにちは。設計自動化の世界へようこそ。

SolidWorksで図面を作成していると、必ずと言っていいほど直面する壁があります。それが「部品表(BOM)のカスタマイズ」です。

「標準のBOMでは、重量の単位を社内規定の数値に変換して表示できない…」
「特定の材質の時だけ、備考欄に『要熱処理』と自動入力したい…」

マクロの記録機能を使って「セルを書き換える」操作を記録しようとしても、うまくいかない。あるいは、記録されたコードが「特定のセル番地(A5など)」を直接指定していて、行が増減すると全く使い物にならない。

もしあなたが今、そんな壁にぶつかっているなら、おめでとうございます。あなたは「単なる操作の記録」から「プログラムによるロジックの実装」へとステップアップする境界線に立っています。

今日は、BOMテーブルを「セル番地」ではなく「構造(オブジェクト)」として捉え、中身を自動計算・更新する、実務直結のテクニックを伝授しましょう。ここをクリアすれば、SolidWorks VBAの基本はバッチリですよ。

1. 思考の転換:セル番地ではなく「走査(スキャン)」せよ

マクロ記録から脱却できない人が陥る最大の罠は、「A列の5行目」という固定的な考え方です。図面の設計変更で部品が増えた瞬間、そのコードはゴミになります。

プロのエンジニアはこう考えます。
「BOMテーブルという箱を見つけ、その中の『重量』という見出しがある列を探し、そこから下の行を一行ずつ順番に見ていく」

これをプログラミング用語で「走査(スキャン)」と呼びます。
「何行目か」を知らなくても、「データの終わりまでループする」という書き方をすれば、部品数が10個でも1000個でも、コードは完璧に動作します。

2. 実践コード:BOMの特定カラムを自動更新する

では、具体的なコードを見ていきましょう。
今回のシナリオは、「BOM内の『重量』カラムを探し、その値を1.1倍(安全率を考慮した値など)して書き換える」というものです。

Option Explicit

''' <summary>
''' 図面内のBOMテーブルを走査し、特定の列の値を計算して更新する
''' </summary>
Sub UpdateBOMWeightColumn()
    Dim swApp As SldWorks.SldWorks
    Dim swModel As SldWorks.ModelDoc2
    Dim swDraw As SldWorks.DrawingDoc
    Dim swSheet As SldWorks.Sheet
    Dim swTableAnn As SldWorks.TableAnnotation
    Dim swBomTable As SldWorks.BomTableAnnotation
    Dim vTables As Variant
    Dim i As Integer, j As Integer
    Dim rowCount As Long
    Dim colCount As Long
    Dim targetCol As Integer
    Dim currentValue As Double
    Dim newValue As Double
    Dim colHeader As String
    
    ' --- 1. 初期設定 ---
    Set swApp = Application.SldWorks
    Set swModel = swApp.ActiveDoc
    
    ' 図面ドキュメントが開かれているかチェック
    If swModel Is Nothing Or swModel.GetType <> swDocDRAWING Then
        MsgBox "図面ファイルを開いてから実行してください。", vbCritical
        Exit Sub
    End If
    
    Set swDraw = swModel
    
    ' --- 2. テーブルの取得 ---
    ' 図面上のすべての注釈(Annotation)からテーブルを探す
    ' ※ここでは簡略化のため、図面上の最初のテーブルを取得するロジックにします
    ' 本来はスキャンして「BOM」かどうかを判定するのがベストです
    
    ' 図面内の全てのテーブル注釈を取得
    vTables = swDraw.GetFirstTableAnnotation
    
    If IsEmpty(vTables) Then
        MsgBox "図面内にテーブルが見つかりません。", vbExclamation
        Exit Sub
    End If

    ' 最初のテーブルを対象とする(実務ではループでBOMを特定する)
    Set swTableAnn = vTables
    
    ' テーブルがBOM(部品表)であることを確認
    If swTableAnn.Type = swTableAnnotation_Bom Then
        Set swBomTable = swTableAnn
    Else
        MsgBox "選択されたテーブルはBOMではありません。", vbExclamation
        Exit Sub
    End If

    ' --- 3. ターゲット列の特定 ---
    ' 「重量」という名前のヘッダーを探す
    targetCol = -1
    colCount = swTableAnn.ColumnCount
    rowCount = swTableAnn.RowCount
    
    For j = 0 To colCount - 1
        colHeader = swTableAnn.Text(0, j) ' 0行目はヘッダー
        If colHeader = "重量" Or colHeader = "Weight" Then
            targetCol = j
            Exit For
        End If
    Next j

    If targetCol = -1 Then
        MsgBox "「重量」カラムが見つかりませんでした。", vbExclamation
        Exit Sub
    End If

    ' --- 4. データの走査と計算 ---
    ' 1行目(ヘッダー)は飛ばして、2行目から最終行までループ
    For i = 1 To rowCount - 1
        ' セルのテキストを取得
        Dim cellText As String
        cellText = swTableAnn.Text(i, targetCol)
        
        ' 数値に変換可能かチェック(空文字や文字列エラー対策)
        If IsNumeric(cellText) Then
            currentValue = CDbl(cellText)
            
            ' --- ここに独自の計算ロジックを記述 ---
            ' 例:重量に1.1倍の係数をかける
            newValue = currentValue * 1.1
            
            ' 書き戻し(小数点第3位まで表示するように整形)
            swTableAnn.Text(i, targetCol) = Format(newValue, "0.000")
        End If
    Next i

    ' 画面を更新して結果を表示
    swModel.GraphicsRedraw
    MsgBox "BOMの更新が完了しました!", vbInformation

End Sub

3. コードの「魂」を解剖する:エンジニアの視点

このコードには、単なる記録にはない「堅牢さ」を持たせるための工夫が詰まっています。

① オブジェクトの階層を辿る

`swDraw.GetFirstTableAnnotation` を使って、図面の中に存在する「テーブル」というオブジェクトにアクセスしています。SolidWorks APIにおいて、テーブルは `TableAnnotation` というクラスで制御されます。これが全ての操作の入り口です。

② ヘッダー検索による「動的な列特定」

ここが最も重要なポイントです。
`For j = 0 To colCount – 1` のループを使って、1行目の各セルをチェックしています。これにより、「重量」列がA列にあろうがC列にあろうが、プログラムが自動で見つけ出します。 これが「マクロの記録」との決定的な違いです。

③ エラー回避の「防波堤」

実務のデータは常に綺麗とは限りません。

  • `If swModel.GetType <> swDocDRAWING`: 図面じゃない時に実行してエラーで落ちるのを防ぐ。
  • `If IsNumeric(cellText)`: セルに「欠品」などの文字が入っていた場合に、計算エラーでプログラムが停止するのを防ぐ。

これらを書くか書かないかで、あなたの作ったツールの「信頼性」が劇的に変わります。

4. 陥りやすいエラーと、プロの回避策

エラー1:インデックスの「0」と「1」の混同

SolidWorks APIの多く(テーブルの行・列など)は 0から数え始めます。

  • 1行目 $\rightarrow$ `index 0`
  • 1列目 $\rightarrow$ `index 0`

一方、VBAの一般的な配列や、人間が考える数え方と混同すると、「1行ずれて計算される」という恐ろしいバグを生みます。常に「APIリファレンスが0始まりか1始まりか」を確認する癖をつけましょう。

エラー2:計算後の「表示形式」問題

`swTableAnn.Text(i, targetCol) = newValue` とだけ書くと、数値が `1.23456789` のように長くなり、図面が見づらくなります。
必ず `Format(newValue, “0.00”)` のように、「人間が見て心地よい形式」に整えてからセルに戻すのが、プロの仕事です。

最後に:一歩先へ進むあなたへ

今回のコードは、あくまで「BOMの値を書き換える」というシンプルなものでした。
しかし、ここから先は無限の可能性があります。

  • 「備考欄に、材質が『アルミ』なら『防錆処理』と追記する」
  • 「部品の構成に基づき、特定のサブアセンブリの重量だけを倍増させる」

これらはすべて、今回学んだ「走査(ループ)」と「条件分岐(If)」の組み合わせで実現できます。

「マクロの記録」は、いわば「辞書を写す」作業です。
しかし、今回学んだ「オブジェクト操作」は、「自分の言葉で文章を書く」作業です。

言葉(ロジック)を身につければ、SolidWorksはあなたの強力な武器になります。一歩ずつ、楽しみながらコードを書いていきましょう。応援していますよ!

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