SolidWorks VBAを掌握するエンジニアの皆さん、こんにちは。チーフアーキテクトの私だ。
図面のリビジョン管理、いまだに手作業でやっていないだろうか?
「設計変更のたびにExcelの変更管理表と見比べながら、図面側のリビジョンテーブルに新行を追加し、該当箇所にリビジョン記号(リビジョンシンボル)をドラッグ&ドロップで配置する……」
この作業、数枚ならまだしも、年間数千図面を扱うプラントや量産機器メーカーの現場において、ヒューマンエラーの温床であり、完全なる時間の無駄だ。
今回は、Excel等の外部管理台帳(あるいは直接構造化されたデータ)と連携し、図面内のリビジョンテーブルへの行追加と版管理を完全に自動化するプロダクションコードを授けよう。
—
1. なぜ素朴なVBAコードでは実務で破綻するのか?
ネットの海を漂うサンプルコードの多くは、単に「現在のアクティブなシートのテーブルにアクセスする」ことしか考えていない。しかし、実務の現場で戦う我々には、以下の壁が立ちはだかる。
1. シートとリビジョンテーブルの非同期:図面がマルチシートの場合、どのシートのどのリビジョンテーブルが「主」であるかを特定し制御しなければならない。
2. テーブル行のインデックス破壊:API経由で不適切に行を追加・削除すると、既存の改訂履歴が上書きされたり、不正なインデックスエラーを引き起こす。
3. リビジョンシンボルのアタッチメント喪失:ビューや図面エンティティに正しくアンカー(紐付け)されていないシンボルは、図面ビューの移動時に宙ぶらりんになる。
これらをクリアし、実務の耐えうる「堅牢なコード」をどう組むべきか。その答えを次項のアーキテクチャで示す。
—
2. 堅牢なリビジョン自動更新アーキテクチャ
今回のソリューションのコアロジックは以下のステップで流れる。
1. ドキュメントの安全な取得と型安全の確保 (`SldWorks.ModelDoc2`, `SldWorks.DrawingDoc`)
2. リビジョンテーブル(RevisionTableAnnotation)の存在確認と取得
3. 新規リビジョン行の追加(改訂番号、説明、承認者、日付の流し込み)
4. 外部データ(今回はハードコーディングだがExcel等に拡張可能)との同期
特にSolidWorksのAPIにおいて、リビジョンテーブルは通常の一般的な汎用テーブル(GeneralTableAnnotation)とは異なり、専用のオブジェクト階層を持っている点に注意せよ。
—
3. 【プロダクションコード】リビジョン自動更新マクロ
以下のコードは、アクティブな図面に対して、最新のリビジョン情報(例: 改訂「A」、説明「底面ブラケットの形状変更」、承認者「T.Suzuki」、日付「2023/10/25」)を強制的に追加・同期させる実用モジュールだ。
Option Explicit
‘ =================================================================================
‘ 処理名 : 業務自動化ソリューション – リビジョンテーブル自動更新エンジン
‘ 概要 : 外部管理データ(実務ではExcel等から取得)を基に、図面のリビジョンテーブルを更新する
‘ 前提 : ターゲットの図面ドキュメントがアクティブであること
‘ =================================================================================
Sub UpdateDrawingRevision_Enterprise()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim swRevTable As SldWorks.RevisionTableAnnotation
Dim swTableAnn As SldWorks.TableAnnotation
‘ アプリケーションインスタンスの取得
Set swApp = Application.SldWorks
If swApp Is Nothing Then Exit Sub
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。”, vbCritical, “エラー”
Exit Sub
End If
‘ 図面ドキュメントかどうかの型チェック
If swModel.GetType <> swDocDRAWING Then
MsgBox “このマクロは図面ドキュメント(.slddrw)でのみ実行可能です。”, vbExclamation, “型不一致”
Exit Sub
End If
Set swDraw = swModel
‘ 1. リビジョンテーブルの取得
‘ ※SolidWorksの図面には通常、シートごとにリビジョンテーブルが存在し得る
Set swRevTable = swDraw.GetCurrentRevisionTable()
If swRevTable Is Nothing Then
‘ テーブルが存在しない場合は新規作成を試みる(テンプレートに依存)
MsgBox “アクティブなシートにリビジョンテーブルが見つかりません。” & vbCrLf & _
“あらかじめ標準フォーマットのリビジョンテーブルを配置してください。”, vbCritical, “テーブル不在”
Exit Sub
End If
Set swTableAnn = swRevTable.GetAnnotation
If swTableAnn Is Nothing Then Exit Sub
‘ — 外部データソースから取得したと仮定する新しいリビジョン情報 —
Dim newRevSymbol As String
Dim newDescription As String
Dim newApprovedBy As String
Dim newDate As String
newRevSymbol = “A”
newDescription = “取付穴のP.C.D変更およびバリ対策追加”
newApprovedBy = “T.SUZUKI”
newDate = Format(Date, “YYYY/MM/DD”)
‘ —————————————————————-
‘ 2. トランザクション処理の開始(SolidWorksのパフォーマンスとUndoスタック保護)
swModel.Extension.SetCommandOpen
On Error GoTo ErrorHandler
‘ 3. 新規行の追加
‘ RevisionTableAnnotation特有の行追加メソッドを使用
Dim insertedRowIndex As Long
‘ 引数: 位置指定(通常は末尾追加)
Dim swRowAnn As SldWorks.TableAnnotation
‘ 既存のテーブルに行を追加
Dim totalRows As Long
totalRows = swTableAnn.RowCount
‘ 新しい行を最下部に挿入 (-1 は末尾を意味する)
Dim newRowIndex As Long
newRowIndex = swTableAnn.InsertRow(swTableInsertionPosition_Bottom, -1)
If newRowIndex < 0 Then
Err.Raise 1001, "RevisionUpdate", "リビジョンテーブルへの行追加に失敗しました。"
End If
' 4. 各セルの値の設定
' 注意: 列インデックスはテンプレートに依存する (通常 0:Rev, 1:Description, 2:Date, 3:Approved 等)
' 堅牢性を高めるためには、列タイトル文字列を走査してインデックスを動的に解決すべきである。
Dim colRev As Long, colDesc As Long, colDate As Long, colApp As Long
colRev = FindColumnIndex(swTableAnn, "REV")
colDesc = FindColumnIndex(swTableAnn, "DESCRIPTION")
colDate = FindColumnIndex(swTableAnn, "DATE")
colApp = FindColumnIndex(swTableAnn, "APPROVED")
If colRev >= 0 Then swTableAnn.Text(newRowIndex, colRev) = newRevSymbol
If colDesc >= 0 Then swTableAnn.Text(newRowIndex, colDesc) = newDescription
If colDate >= 0 Then swTableAnn.Text(newRowIndex, colDate) = newDate
If colApp >= 0 Then swTableAnn.Text(newRowIndex, colApp) = newApprovedBy
‘ 変更をモデルに反映し再描画
swModel.WindowRedraw
swModel.Extension.CommandClose
MsgBox “リビジョンテーブルの更新が正常に完了しました。”, vbInformation, “完了”
Exit Sub
ErrorHandler:
swModel.Extension.CommandClose
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “致命的エラー”
End Sub
‘ =================================================================================
‘ ヘルパー関数 : カラム名から対応する列インデックスを動的に解決する
‘ 理由 : 企業や図面テンプレートによって列の並び順が異なるため、ハードコーディングを避ける
‘ =================================================================================
Private Function FindColumnIndex(ByVal swTable As SldWorks.TableAnnotation, ByVal headerName As String) As Long
Dim colCount As Long
Dim i As Long
colCount = swTable.ColumnCount
For i = 0 To colCount – 1
If UCase(Trim(swTable.GetColumnTitle(i))) = UCase(Trim(headerName)) Then
FindColumnIndex = i
Exit Function
End If
Next i
‘ 見つからない場合は -1 を返す
FindColumnIndex = -1
End Function
—
4. プロとして知っておくべき「落とし穴」と実務的アドバイス
上記のコードを見れば、単なるコピペプログラマーとは一線を画す堅牢性が理解できるはずだ。最後に、現場でこのシステムを運用する上での重要な知見を授ける。
① 列タイトルの動的解決の重要性
コード内で `FindColumnIndex` というヘルパー関数を用意した。なぜなら、部署や顧客、プロジェクトの規格(JIS, ASME, 社内規格など)によって、リビジョンテーブルの「DESCRIPTION」が「変更内容」であったり「REVISION DESCRIPTION」であったりと表記揺れを起こすからだ。インデックスを固定値(`0, 1, 2…`)で決め打つコードは、テンプレート変更一発で沈没する。動的解決ロジックはマストである。
② Excel / PDMシステム連携への拡張
今回のコードは変数をハードコーディングしているが、実務ではここを `ADODB` や `Scripting.FileSystemObject` を経由して、Excelの進捗管理シートやTeamcenterなどのPDMからJSON/CSVでデータを引っぱる構造に拡張してほしい。設計変更通知書(ECO)の番号と連動させれば、エンジニアが図面に向き合う時間を劇的にゼロに近づけられる。
最後に
SolidWorks APIは、正しく扱い、適切にエラーハンドリングとトランザクション(`SetCommandOpen / CommandClose`)を組めば、あなたの右腕となる最強の自動化エンジンに変貌する。
手作業での図面管理という泥臭いルーチンワークはVBAにすべて押し付け、君たちは「真に価値のある設計創造」に集中したまえ。
