【実務・中級編】【上級プロ】外部PDS/PLMシステムとのREST API連携による、アセンブリ構成部品の自動チェックイン・チェックアウト制御 – SolidWorks VBA解析バイブル

スポンサーリンク

【SolidWorks VBA × REST API】PLM連携によるアセンブリ構成部品の排他制御・自動チェックイン/アウト極限構築ガイド

開発現場のリーダーであるあなたなら、痛いほど理解しているはずだ。
「手動でのPDS/PLMへのチェックイン・チェックアウト忘れ」に起因する、上書き事故、参照切れ、そして夜間のバッチビルド崩壊。これらはエンジニアの意識改革などという精神論では絶対に防げない。システム的に強制する、すなわち「VBAによるアセンブリ自動生成の瞬間に、API経由でライフサイクルを完全に掌握する」以外に解決策はない。

今回は、単に「SolidWorksで部品を組み上げました」というレベルの低い話ではない。
外部のREST API(PLM/PDSサーバー)と同期し、「最新リビジョンの取得(チェックアウト)」から「アセンブリの動的構築」「合致(Mate)の定義」、そして「サーバーへの安全なアップロード(チェックイン)」までをトランザクションとして完結させる、極限まで堅牢なプロダクションコードを授けよう。

—

1. 現場を崩壊させる「素人コード」のアンチパターン

多くのプログラマ崩れが書くVBAコードは、実務の現場では使い物にならない。なぜか?

1. APIの同期・非同期エラーを考慮していない
HTTPリクエストがタイムアウトした際のエラーハンドリングがなく、SolidWorksのセッションが宙ぶらりんになる。
2. ローカルキャッシュとサーバーリビジョンの不整合
すでにローカルに存在する古いファイルをそのまま開き、参照エラーを引き起こす。
3. トランザクション概念の欠如
アセンブリの合致(Mate)定義中にエラーで落ちた場合、サーバー側でファイルが「チェックアウトしっぱなし(LOCKED)」のゴースト状態になり、他の設計者の作業を阻害する。

我々はプロの自動化エンジニアだ。「API通信の失敗」「ファイル競合」「セッションの例外」のすべてを想定した要塞のようなコードを書く。

—

2. 全体アーキテクチャ設計

今回の連携フローは以下の通りだ。

[SolidWorks VBA]
│
├─ 1. REST API呼び出し (GET /api/v1/parts/{id}/checkout)
│ └─ サーバー側で排他ロックを取得し、最新ファイルをローカル一時ディレクトリへダウンロード
│
├─ 2. SldWorks.AssemblyDoc.AddComponent4 によるアセンブリ動的構築
│
├─ 3. SldWorks.ModelDocExtension.AddMate5 による数学的・幾何学的な合致定義
│
└─ 4. REST API呼び出し (POST /api/v1/assemblies/checkin)
└─ アセンブリの保存 & サーバーへチェックイン & ロック解除

VBA標準の `MSXML2.ServerXMLHTTP.6.0` を用いてREST APIを叩き、JSONのパースにはVBA環境でも安定する簡易パーサー、またはAPI側でフラットなレスポンスを返す設計を前提とする。

—

3. プロダクションコード:PLM連携アセンブリ自動生成エンジン

以下のコードは、エラーハンドリング、API通信、SolidWorksのAPI呼び出しを統合した実践的なモジュールである。そのままコピペし、環境に合わせてエンドポイントを書き換えてほしい。

‘ =================================================================================
‘ 模块名: clsPlmAssemblyManager
‘ 概要: REST API連携による部品チェックアウト・アセンブリ自動生成・チェックイン制御クラス
‘ =================================================================================
Option Explicit

‘ 定数定義
Private Const PLM_BASE_URL As String = “https://plm.company-internal.local/api/v1”
Private Const LOCAL_WORK_DIR As String = “C:\SolidWorksWorkspace\Temp\”

‘ 外部API通信用オブジェクト(WinHttpRequestを使用)
Private http As Object

Private Sub Class_Initialize()
Set http = CreateObject(“WinHttp.WinHttpRequest.5.1”)
‘ タイムアウト設定 (接続:5秒, 送受信:30秒)
http.SetTimeouts 5000, 5000, 30000, 30000
End Sub

Private Sub Class_Terminate()
Set http = Nothing
End Sub

‘ ——————————————————————————–
‘ メイン処理:PLMから部品を取得し、アセンブリを新規作成して合致を定義、チェックインする
‘ ——————————————————————————–
Public Sub ExecutePlmAssemblyWorkflow()
Dim swApp As SldWorks.SldWorks
Dim swAssyDoc As SldWorks.AssemblyDoc
Dim swModel As SldWorks.ModelDoc2
Dim partNumber1 As String, partNumber2 As String
Dim file1 As String, file2 As String
Dim assyPath As String

Set swApp = Application.SldWorks

On Error GoTo ErrorHandler

‘ 0. ワークディレクトリの確保
Call EnsureDirectory(LOCAL_WORK_DIR)

‘ 1. 【PLM連携】部品Aのチェックアウト&ダウンロード
partNumber1 = “BRACKET-001”
file1 = CheckoutAndDownloadPart(partNumber1, “rev_A”)
If file1 = “” Then Err.Raise 1001, “PLM”, partNumber1 & ” のチェックアウトに失敗しました。”

‘ 2. 【PLM連携】部品Bのチェックアウト&ダウンロード
partNumber2 = “BOLT-M8”
file2 = CheckoutAndDownloadPart(partNumber2, “rev_B”)
If file2 = “” Then Err.Raise 1002, “PLM”, partNumber2 & ” のチェックアウトに失敗しました。”

‘ 3. 新規アセンブリドキュメントの作成 (テンプレート使用)
Set swModel = swApp.NewDocument(“C:\ProgramData\SolidWorks\SolidWorks 2023\templates\Assembly.asmdot”, 0, 0, 0)
If swModel Is Nothing Then Err.Raise 1003, “SolidWorks”, “アセンブリの新規作成に失敗しました。”
Set swAssyDoc = swModel

‘ 4. 構成部品の配置 (AddComponent4)
Dim comp1 As SldWorks.Component2
Dim comp2 As SldWorks.Component2
Dim transform As SldWorks.MathTransform

Set comp1 = swAssyDoc.AddComponent4(file1, “”, 0, 0, 0)
Set comp2 = swAssyDoc.AddComponent4(file2, “”, 0.1, 0, 0)

If comp1 Is Nothing Or comp2 Is Nothing Then
Err.Raise 1004, “SolidWorks”, “構成部品の配置に失敗しました。”
End If

‘ 5. 幾何拘束(合致: Mate)の定義
‘ ここでは面の一致(Coincident)をプログラム的に定義する例
Call DefineCoincidentMate(swModel, “Face<1>“, “Face<1>“)

‘ 6. アセンブリをローカルに保存
assyPath = LOCAL_WORK_DIR & “Assy_AutoGenerated.sldasm”
Dim saveError As Long, saveWarning As Long
swModel.SaveAs3 assyPath, 0, 2 ‘ swSaveAsOptions_Silent

‘ 7. 【PLM連携】アセンブリ自体のチェックイン
Call CheckinAssembly(assyPath, “Auto-generated by SolidWorks VBA Automation”)

MsgBox “PLM連携によるアセンブリの自動生成・チェックインが正常に完了しました。”, vbInformation
Exit Sub

ErrorHandler:
‘ 異常系:ロックの解放やロールバック処理をここに記述
MsgBox “致命的なエラーが発生しました [” & Err.Number & “]: ” & Err.Description, vbCritical
‘ 必要に応じてAPI経由でチェックアウト状態を強制解除するリクエストを送信するフェイルセーフを実装すること
End Sub

‘ ——————————————————————————–
‘ REST API: チェックアウトとファイルのローカルダウンロード
‘ ——————————————————————————–
Private Function CheckoutAndDownloadPart(ByVal partNumber As String, ByVal revision As String) As String
Dim url As String
url = PLM_BASE_URL & “/parts/” & partNumber & “/checkout?revision=” & revision

http.Open “POST”, url, False
http.setRequestHeader “Content-Type”, “application/json”
http.setRequestHeader “Authorization”, “Bearer YOUR_API_TOKEN_HERE”
http.Send
ステータス確認
If http.Status = 200 Then
‘ 200OKの場合、レスポンスヘッダーやJSONからダウンロードURLを取得、またはバイナリを直接保存
‘ ここでは簡易的にAPIがローカルパスを返す、あるいはバイナリをストリーム保存する処理を想定
Dim localFilePath As String
localFilePath = LOCAL_WORK_DIR & partNumber & “.sldprt”

‘ バイナリデータの保存処理 (ADODB.Streamを使用)
Dim stream As Object
Set stream = CreateObject(“ADODB.Stream”)
stream.Type = 1 ‘adTypeBinary
stream.Open
stream.Write http.ResponseBody
stream.SaveToFile localFilePath, 2 ‘adSaveCreateOverWrite
stream.Close
Set stream = Nothing

CheckoutAndDownloadPart = localFilePath
Else
CheckoutAndDownloadPart = “”
End If
End Function

‘ ——————————————————————————–
‘ REST API: アセンブリのチェックイン
‘ ——————————————————————————–
Private Sub CheckinAssembly(ByVal filePath As String, ByVal comment As String)
Dim url As String
url = PLM_BASE_URL & “/assemblies/checkin”

‘ 実務ではマルチパートフォームデータ(multipart/form-data)でファイルをアップロードする
‘ ここでは概念としてのPOSTリクエスト送信を定義
http.Open “POST”, url, False
http.setRequestHeader “Authorization”, “Bearer YOUR_API_TOKEN_HERE”
‘ ※バイナリ送信の実装は省略(標準的なWinHttpを用いたストリーム送信をここにバインドする)
http.Send

If http.Status <> 200 And http.Status <> 201 Then
Err.Raise 1005, “PLM”, “チェックインに失敗しました。HTTP Status: ” & http.Status
End If
End Sub

‘ ——————————————————————————–
‘ 補助関数: 面の選択と合致の付与 (SolidWorks API)
‘ ——————————————————————————–
Private Sub DefineCoincidentMate(ByVal swModel As SldWorks.ModelDoc2, ByVal entityName1 As String, ByVal entityName2 As String)
Dim swAssy As SldWorks.AssemblyDoc
Set swAssy = swModel

‘ 選択クリア
swModel.ClearSelection2 True

‘ 注: 実務の合致定義では、エンティティの正確な名前(Face<1>など)を動的特定するか、
‘ 座標ベース・サーフェスIDベースでSelectByID2を使用する。
‘ swModel.Extension.SelectByID2 …

‘ 例として、マクロ記録ベースの合致追加関数をラップ
Dim swMateRet As Long
swMateRet = swAssy.AddMate3(1, 0, False, 0, 0, 0, 0, 0, 0, 0, 0, False, 1) ‘ swMateCOIN

swModel.ClearSelection2 True
swModel.ForceRebuild3 True
End Sub

‘ ——————————————————————————–
‘ 補助関数: ディレクトリの存在確認と作成
‘ ——————————————————————————–
Private Sub EnsureDirectory(ByVal path As String)
If Dir(path, vbDirectory) = “” Then
MkDir path
End If
End Sub

—

4. チーフアーキテクトが教える「現場で絶対にハマる罠と対策」

このコードをそのまま導入するだけでは、プロの現場で生き残ることはできない。以下の3点に細心の注意を払え。

① APIトークンのハードコーディングは「悪」

コード内に `Bearer YOUR_API_TOKEN_HERE` などと直書きするな。セキュリティ監査で一発レッドカードだ。

  • 対策: トークンはWindowsの「環境変数」またはWindowsレジストリ、あるいは暗号化されたローカルiniファイルから動的に読み込む設計にせよ。

② ファイルロックの競合とタイムアウト

大規模アセンブリになると、APIからのファイルダウンロード(バイナリ書き込み)が完了する前に、SolidWorksがファイルを開こうとして「ファイルが使用中です」エラーを引き起こす。

  • 対策: `ADODB.Stream` での書き込み完了を確認したあと、`DoEvents` を挟むか、ファイルの存在とサイズが安定するまでループで待機する(ポーリング処理)ロジックを必ず入れること。

③ 例外発生時の「ゾンビチェックアウト」の防止

VBAが途中でクラッシュした場合、PLMサーバー側で部品が「ロック(チェックアウト中)」されたままになり、翌朝他の設計者が作業できなくなる。

  • 対策: クラスの `Class_Terminate` イベント、あるいはエラーハンドラ内に「異常終了シグナルをAPIに送信し、ロックを強制解除(ロールバック)するRESTリクエスト」を必ず組み込め。

—

5. さらなる高みへ:VBAから.NET (COM Add-in) への移行判断基準

もしあなたが今、「VBAでこのシステムを構築すべきか、VB.NETやC#でSolidWorksのCOMアドイン(Add-in)として作るべきか」迷っているなら、チーフとしてこうアドバイスしよう。

  • VBAを採用すべきケース:
  • 社内の開発リソースが限られており、マクロとしてサクッと配布・更新したい場合。
  • 外部ライブラリの依存関係が少なく、HTTP通信が `WinHttpRequest` 程度で完結する場合。
  • VB.NET / C# (COM Add-in) に移行すべきケース:
  • アセンブリの構成部品数が 1,000点を超える大規模モデル で、パフォーマンス(メモリ管理・非同期処理)がシビアな場合。
  • JSONの本格的なパース(Newtonsoft.Json等)や、より高度なスレッド制御が必要な場合。

まずは今回提供した堅牢なVBAクラス設計をベースにプロトタイプを組み、社内のPLMサーバーとの疎通を証明せよ。あなたのチームの設計プロセスは、この瞬間から劇的に進化するはずだ。

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