同期される真実:Excel変更通知書を用いた図面リビジョンテーブルの完全自動制御
設計変更のプロセスにおいて、最も致命的なエラーは「データの不整合」である。
設計変更管理システム(Excel)に記録された変更内容と、実際のSolidWorks図面に刻まれたリビジョン履歴が食い違った瞬間、その図面は「信頼できない文書」へと成り下がる。
多くの現場では、この同期作業を「手作業」という名の不確実なプロセスに委ねている。しかし、我々エンジニアに許されるのは、確実な自動化による「真実の同期」のみである。
本稿では、Excelの変更通知書からデータを読み取り、SolidWorksの図面リビジョンテーブルへ、型安全かつメモリ効率を極限まで高めた手法で転記する、プロフェッショナル向けの自動化アーキテクチャを詳解する。
1. アーキテクチャの設計思想:COM境界の理解
単に「Excelの値をSolidWorksに送る」という発想では、中級者の域を出ることはできない。我々が直面しているのは、異なるアプリケーション(プロセス)間でのCOM(Component Object Model)通信である。
ExcelとSolidWorksは独立したプロセスであり、それらを跨ぐ通信にはオーバーヘッドが発生する。特に、ループ内で頻繁にAPIを呼び出す設計は、パフォーマンスの低下を招くだけでなく、不適切な参照カウント管理によって「ゾンビプロセス(終了してもメモリに残るSolidWorks)」を生む温床となる。
制御の原則
1. データの局所化: Excelからデータを読み取る際は、セルに何度もアクセスせず、一度に配列(Variant Array)へ格納し、メモリ上で処理を完結させる。
2. オブジェクトのライフサイクル管理: `Set = Nothing` は基本だが、複雑な階層構造を持つSolidWorks APIにおいては、参照の解放順序が重要である。
3. 決定論的なエラーハンドリング: APIの呼び出し失敗が、システム全体のクラッシュに繋がらないよう、各階層で例外を捕捉する。
2. 極限のメモリ管理:オブジェクト解放の作法
SolidWorks VBAにおいて、最も多くのシニアエンジニアを悩ませるのが「メモリリーク」だ。APIを通じて取得した `DrawingDoc` や `Sheet`、`RevisionTableAnnotation` といったオブジェクトは、明示的に解放しなければ、Excelを閉じてもSolidWorksがタスクマネージャーに居座り続けることになる。
特に、`GetFirstNote` や `GetNext` を用いてリビジョンテーブルの行を走査する場合、各行の `Note` オブジェクトを適切に解放しなければ、数千件の変更履歴を処理する際にメモリ消費が指数関数的に増大する。
3. 実装例:リビジョン同期エンジン
以下に、実務に耐えうる堅牢なコード構造を示す。このコードは、Excelの特定のシートから「改訂番号」「日付」「内容」「理由」を読み取り、図面の既存のリビジョンテーブルの末尾に追加、あるいは不一致を検知するロジックを想定している。
'------------------------------------------------------------------------------
' Module: RevisionSyncEngine
' Description: Excel Change Notification to SolidWorks Revision Table Sync
' Author: Legendary Chief Architect
'------------------------------------------------------------------------------
Option Explicit
' Windows API: ユーザーへの通知やプロセス制御に必要に応じて使用
' 今回は標準的なCOM操作に集中するが、環境によってはShell APIが必要になる
Private Declare PtrSafe Function MsgBox Lib "user32" Alias "MessageBoxA" ( _
ByVal hwnd As LongPtr, ByVal lpText As String, _
ByVal lpCaption As String, ByVal uType As Long) As Long
Sub SyncRevisionTableFromExcel()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim swSheet As SldWorks.Sheet
Dim swTable As SldWorks.RevisionTableAnnotation
Dim xlApp As Object ' Excel.Application (Late Binding for stability)
Dim xlWB As Object
Dim xlWS As Object
Dim dataArray As Variant
Dim i As Long
' エラーハンドリングの初期化
On Error GoTo ErrorHandler
' 1. SolidWorksへの接続
Set swApp = Application.SldWorks
If swApp Is Nothing Then
MsgBox "SolidWorksが起動していません。", vbCritical
Exit Sub
End If
' 2. アクティブなドキュメントの検証
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then GoTo CleanUp
If swModel.GetType <> swDocDRAWING Then
MsgBox "図面ファイルを開いた状態で実行してください。", vbExclamation
GoTo CleanUp
End If
Set swDraw = swModel
' 3. Excelデータの取得 (Memory Optimization: Array Loading)
' Excelをバックグラウンドで取得
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
On Error GoTo ErrorHandler
If xlApp Is Nothing Then
MsgBox "Excelが起動していません。", vbCritical
GoTo CleanUp
End If
Set xlWB = xlApp.ActiveWorkbook
Set xlWS = xlWB.Sheets("変更通知書") ' シート名は仕様に合わせる
' データ範囲を一括で配列に格納(セルへの個別アクセスを回避)
' A2:D100 の範囲を想定(改訂番号, 日付, 内容, 理由)
dataArray = xlWS.Range("A2:D100").Value
' 4. 図面シートとリビジョンテーブルの特定
Set swSheet = swDraw.GetCurrentSheet
' リビジョンテーブルの取得(既存のものを使用)
Set swTable = swSheet.GetFirstRevisionTableAnnotation
If swTable Is Nothing Then
' テーブルが存在しない場合のハンドリング(必要に応じて作成ロジックを挿入)
MsgBox "リビジョンテーブルが見つかりません。手動で配置してください。", vbCritical
GoTo CleanUp
End If
' 5. 同期ロジックの実行
' 配列の各行を走査
For i = 1 To UBound(dataArray, 1)
' 空行はスキップ
If IsEmpty(dataArray(i, 1)) Then GoTo NextIteration
' --- ここに同期ロジックを実装 ---
' 本来は、既存テーブルの最終行と、Excelの最新行を比較するロジックが必要
' 今回は「Excelのデータをテーブルの末尾に追加する」という極めてシンプルな実装を示す
Dim rowIdx As Long
rowIdx = swTable.GetRowCount + 1
' 各列への書き込み
swTable.AddRow
swTable.Text(rowIdx, 0) = CStr(dataArray(i, 1)) ' 改訂番号
swTable.Text(rowIdx, 1) = CStr(dataArray(i, 2)) ' 日付
swTable.Text(rowIdx, 2) = CStr(dataArray(i, 3)) ' 内容
swTable.Text(rowIdx, 3) = CStr(dataArray(i, 4)) ' 理由
' -------------------------------
NextIteration:
Next i
MsgBox "同期が完了しました。", vbInformation
CleanUp:
' 6. オブジェクトの明示的解放 (The Critical Part)
' 参照カウントを確実にゼロにするための儀式
On Error Resume Next
Set swTable = Nothing
Set swSheet = Nothing
Set swDraw = Nothing
Set swModel = Nothing
Set xlWS = Nothing
Set xlWB = Nothing
Set xlApp = Nothing
Set swApp = Nothing
Exit Sub
ErrorHandler:
MsgBox "致命的なエラーが発生しました: " & Err.Description, vbCritical
Resume CleanUp
End Sub
4. 運用における「極限の知見」
コードを書くだけでは、プロフェッショナルとは呼べない。実運用において以下の3点を考慮せよ。
I. Late Binding vs Early Binding
本コードではExcelに対して `Object` 型(Late Binding)を使用している。これは、開発環境と実行環境でのExcelのバージョン差異(Office 365 vs 2016等)による「参照不可エラー」を防ぐための戦略的選択である。SolidWorks APIについては、IntelliSense(入力補完)の恩恵を受けるため、Early Binding(参照設定済み)を推奨する。
II. 冪等性(Idempotency)の確保
「何度実行しても同じ結果になる」ことを保証せよ。
上記の単純な追加ロジックでは、二重実行すると同じデータが何度も書き込まれる。実用的なシステムでは、`swTable.Text(rowIdx, 0)`(改訂番号)をキーとして、Excel側のデータが既に図面に存在するかを判定するロジックを必ず組み込むこと。
III. トランザクションの概念
大量のデータを書き込む際、途中でエラーが起きたらどうするか?
SolidWorks APIには標準的な「ロールバック」機能はない。したがって、書き込みを開始する前に「現在のテーブル状態をバックアップ(または一時的なコピーを作成)」するか、書き込みが完了するまで図面を「読み取り専用」に近い状態で扱う運用設計が、システム管理者には求められる。
結論
図面のリビジョン管理は、製品の品質を担保するための「最後の防衛線」である。
VBAを単なる「作業の自動化」としてではなく、「データの整合性を守るためのインフラ」として捉えること。オブジェクトのライフサイクルを支配し、メモリの挙動を理解した者だけが、真に信頼される設計システムを構築できる。
