【入門編】【上級プロ】アセンブリファイルのバイナリ・メタデータ解析と、VBAから直接外部PDMシステムへのチェックイン・チェックアウト制御 – SolidWorks VBA解析バイブル

スポンサーリンク

【上級プロへの扉】SolidWorks VBAでアセンブリを制し、PDMを自在に操る!バイナリ・メタデータ解析とセキュアな同期の極意

こんにちは!SolidWorks VBAの世界へようこそ。伝説の業務自動化エンジニア、〇〇(あなたの名前)です。今日は、皆さんが「マクロの記録」から一歩踏み出し、SolidWorks VBAの真髄に触れる、そんなエキサイティングなテーマをお届けします。

「アセンブリの新規作成や合致(Mate)の自動定義って、APIでできるのは知ってるけど、もっと奥深いことがしたいんだよね…」
「PDMシステムとの連携?専用アドインなしで、VBAから直接制御できたら便利なのに…」

そんな熱い想いを抱えるあなたのために、今回は「アセンブリファイルのバイナリ・メタデータ解析と、VBAから直接外部PDMシステムへのチェックイン・チェックアウト制御」という、まさにプロフェッショナル向けのテーマに切り込みます!

「え、PDMシステムとの連携なんて、専門的な知識が必要なんじゃ…?」
「バイナリ・メタデータ解析って、難しそう…」

大丈夫です!この記事では、SolidWorks APIの基本的な使い方から、ファイルシステムを駆使したセキュアなセッション管理、そして排他制御の実装パターンまで、基礎から本質までを噛み砕いて、優しく知的な先輩エンジニアの口調で、丁寧に解説していきます。

この記事を読み終える頃には、あなたはSolidWorks VBAの新たな可能性に目覚め、「ここをクリアすれば、SolidWorks VBAの基本はバッチリ!」と自信を持って言えるようになっているはずです。さあ、一緒にSolidWorks VBAの深淵を覗いてみましょう!

1. なぜ「PDM連携」をVBAで?~アドインなしで実現する、そのメリットとは?

まず、なぜわざわざVBAからPDMシステムを直接制御するのか、その意義から確認しましょう。

  • 汎用性の向上: 特定のPDMシステムに依存しない、汎用的なVBAマクロを作成できます。これにより、異なるPDM環境でもコードの再利用性が高まります。
  • 開発コストの削減: 専用アドインの開発は、高度なプログラミングスキルと時間が必要です。VBAであれば、比較的容易に、かつ迅速にPDM連携を実現できます。
  • 柔軟なワークフロー構築: VBAの強力なロジックと組み合わせることで、PDMの標準機能だけでは実現できない、より柔軟で高度なワークフローを構築できます。

もちろん、専用アドインにはUIの統合や高度なセキュリティ機能などのメリットもあります。しかし、「手軽に、かつ強力に」PDM連携を実現したい場面では、VBAからの直接制御は非常に有効な選択肢となります。

2. SolidWorksアセンブリの「中身」を覗く~バイナリ・メタデータ解析の基礎

さて、ここからが本題です。PDMシステムと連携する上で、SolidWorksアセンブリファイル(`.sldasm`)の「中身」、つまりバイナリ・メタデータについて理解することが不可欠です。

2.1. SolidWorksファイルは「単なるテキスト」ではない!

多くの人が、CADファイルはテキストベースで編集できると思いがちですが、SolidWorksのような高度な3D CADファイルは、バイナリ形式で保存されています。これは、3Dモデルの複雑な形状情報、フィーチャー情報、ヒストリ、そして様々なメタデータ(部品表、プロパティなど)を効率的に格納するためです。

2.2. VBAで「ファイルを開く」だけではダメな理由

`FileSystemObject`などを使ってファイルを開き、テキストとして読み込もうとしても、バイナリデータは意味不明な文字列の羅列にしかなりません。

‘ これはあくまでイメージで、実際には意味のあるデータは得られません
Dim fso As Object
Dim ts As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set ts = fso.OpenTextFile(“C:\Path\To\Your\Assembly.sldasm”, 1) ‘ 1はForReading
Dim fileContent As String
fileContent = ts.ReadAll
Debug.Print fileContent ‘ 意味不明な文字が表示される
ts.Close

では、どうすればSolidWorksファイルの中身を理解できるのでしょうか?

2.3. SolidWorks APIによる「メタデータ」へのアクセス

SolidWorks APIは、このバイナリデータに直接アクセスするのではなく、ファイルが表現する「情報」にアクセスするためのインターフェースを提供してくれます。これが、APIの真骨頂です。

例えば、アセンブリに含まれる部品のリストや、各部品のカスタムプロパティなどを取得できます。

Sub GetAssemblyComponentsAndProperties()

Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssembly As SldWorks.AssemblyDoc
Dim vComponents As Variant
Dim vComp As Variant
Dim swCompModel As SldWorks.ModelDoc2
Dim componentName As String
Dim customPropValue As String

‘ SolidWorksアプリケーションへの接続
On Error Resume Next
Set swApp = GetObject(, “SldWorks.Application”)
If swApp Is Nothing Then
Set swApp = CreateObject(“SldWorks.Application”)
swApp.Visible = True
End If
On Error GoTo 0

‘ アセンブリファイルを開く(例)
Set swModel = swApp.OpenDoc6(“C:\Path\To\Your\Assembly.sldasm”, swDocASSEMBLY, swOpenDocOptions_Silent, “”, 0, 0)
If swModel Is Nothing Then
MsgBox “アセンブリファイルを開けませんでした。”, vbCritical
Exit Sub
End If

Set swAssembly = swModel

‘ アセンブリに含まれるコンポーネントを取得
vComponents = swAssembly.GetComponents(False) ‘ Falseでトップレベルのみ

If Not IsEmpty(vComponents) Then
For Each vComp In vComponents
componentName = vComp.Name2 ‘ コンポーネント名
Debug.Print “コンポーネント名: ” & componentName

‘ コンポーネントのモデルドキュメントを取得
Set swCompModel = swApp.OpenDoc6(vComp.GetPathName, swDocPART, swOpenDocOptions_Silent, “”, 0, 0)
If Not swCompModel Is Nothing Then
‘ カスタムプロパティを取得する例 (例: “Revision”)
customPropValue = swCompModel.Extension.CustomPropertyManager(“”).Get(“Revision”) ‘ プロパティマネージャー名(””でデフォルト)
If customPropValue <> “” Then
Debug.Print ” Revision: ” & customPropValue
Else
Debug.Print ” Revision プロパティが見つかりません。”
End If
swApp.CloseDoc swCompModel.GetTitle ‘ ドキュメントを閉じる
End If
Next vComp
Else
Debug.Print “このアセンブリにはコンポーネントがありません。”
End If

‘ メインのアセンブリドキュメントを閉じる
swApp.CloseDoc swModel.GetTitle

MsgBox “コンポーネント情報とカスタムプロパティをイミディエイトウィンドウに出力しました。”, vbInformation

End Sub

【コードのポイント】

  • `GetObject(, “SldWorks.Application”)` や `CreateObject(“SldWorks.Application”)` でSolidWorksアプリケーションに接続します。
  • `OpenDoc6` でアセンブリファイルを開きます。`swDocASSEMBLY` でアセンブリとして開くことを指定します。
  • `swAssembly.GetComponents(False)` で、アセンブリに含まれるコンポーネントの配列を取得します。`False` を指定すると、トップレベルのコンポーネントのみが取得されます。
  • 各コンポーネントの`Name2`で名前を取得し、`GetPathName`でファイルパスを取得します。
  • `swApp.OpenDoc6`で部品ファイルを開き、`Extension.CustomPropertyManager(“”).Get(“プロパティ名”)`でカスタムプロパティの値を取得します。
  • 処理が終わったら、`CloseDoc`で開いたドキュメントを閉じ、リソースを解放することが重要です。

このように、APIを使うことで、バイナリファイルの中身を直接解析することなく、必要な情報を構造化された形で取得できるのです。

3. PDMシステムとの「橋渡し」~チェックイン・チェックアウト制御の自動化

さて、アセンブリのメタデータを取得できるようになったら、いよいよPDMシステムとの連携です。ここでは、専用アドインなしで、VBAからPDMのチェックイン・チェックアウトを制御する、堅牢なセッション管理と排他制御の実装パターンを解説します。

3.1. PDMシステムへの「アクセス方法」を理解する

PDMシステムへのアクセス方法は、システムによって異なります。

  • ファイルサーバー上の共有フォルダ: Git LFSや一部のPDMシステムでは、ファイルが共有フォルダに保存されます。この場合、ファイルロックや属性(読み取り専用など)の操作で排他制御を行います。
  • PDMクライアントAPI: Vault、Teamcenterなどの主要なPDMシステムは、独自のAPIを提供しています。このAPIを利用することで、より高度で安全なチェックイン・チェックアウトが可能です。
  • Web API/RESTful API: 最近のPDMシステムでは、HTTPリクエストを介して操作できるWeb APIが提供されている場合もあります。

今回は、汎用性が高く、かつVBAから比較的容易に実装できる「ファイルシステム制御」をベースにしたアプローチを中心に解説します。これは、ファイルサーバー上にキャッシュされたデータに対して操作を行うようなシナリオで有効です。

3.2. 堅牢なセッション管理と排他制御の実装パターン

「セッション管理」と「排他制御」は、複数ユーザーが同時にファイルにアクセスする環境で、データの不整合や競合を防ぐための非常に重要な概念です。

【実装パターン】

1. 「作業中」フラグの利用:

  • 各ファイル/アセンブリに対して、作業中であることを示す「フラグファイル」(例: `.lock`、`.working`)を作成・削除します。
  • ファイルを開く前に、フラグファイルの存在を確認します。存在すれば、他のユーザーが作業中と判断し、アクセスをブロックします。
  • 作業完了後、フラグファイルを削除します。

2. 「チェックアウト」状態の管理:

  • PDMシステム側で「チェックアウト」状態を管理するのが理想ですが、VBAから直接行う場合は、ローカルな管理ファイル(例: INIファイル、CSVファイル、あるいは専用のデータベース)を作成し、どのユーザーがどのファイルをチェックアウトしているかを記録します。
  • この管理ファイルは、共有フォルダなどに配置し、アクセス権限を適切に設定します。

3. 「バージョン」管理の意識:

  • PDMシステムは、ファイルの変更履歴(バージョン)を管理します。VBAからチェックインする際には、新しいバージョンとして登録されることを意識した処理が必要です。

【VBAコード例:ファイルロックによる排他制御】

ここでは、シンプルな「`.lock`」ファイルを使った排他制御の例を示します。

‘=============================================================================
‘ ファイルロック管理モジュール
‘=============================================================================

Option Explicit

Const LOCK_FILE_EXTENSION As String = “.lock”

‘ ファイルをロックする
‘ 戻り値: True (ロック成功), False (ロック失敗 – 既にロックされている)
Function LockFile(filePath As String) As Boolean
Dim lockFilePath As String
lockFilePath = filePath & LOCK_FILE_EXTENSION

If FileExists(lockFilePath) Then
‘ 既にロックファイルが存在する場合
‘ より高度な実装では、ロックファイルのタイムスタンプを確認し、
‘ 長時間放置されているロックを解除する処理などを追加します。
LockFile = False
Exit Function
End If

On Error Resume Next
‘ ロックファイルを作成 (排他モードで開く)
Open lockFilePath For Output Lock Read Write As #1
If Err.Number <> 0 Then
‘ ロックファイルの作成に失敗した場合 (稀だが、権限などの問題)
Err.Clear
LockFile = False
Exit Function
End If
Print #1, “Locked by: ” & Environ(“USERNAME”) & ” on ” & Now() ‘ ロック情報を記録
Close #1
On Error GoTo 0

LockFile = True
End Function

‘ ファイルのロックを解除する
Sub UnlockFile(filePath As String)
Dim lockFilePath As String
lockFilePath = filePath & LOCK_FILE_EXTENSION

If FileExists(lockFilePath) Then
On Error Resume Next
Kill lockFilePath ‘ ロックファイルを削除
On Error GoTo 0
End If
End Sub

‘ ファイルが存在するかどうかをチェックするヘルパー関数
Function FileExists(filePath As String) As Boolean
FileExists = (Dir(filePath) <> “”)
End Function

‘=============================================================================
‘ SolidWorks アセンブリ処理モジュール (PDM連携を想定)
‘=============================================================================

Sub CheckOutAndEditAssembly()

Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim assemblyPath As String
Dim pdmUser As String ‘ PDMシステムで管理するユーザー名(例)

‘ — 設定 —
assemblyPath = “C:\Work\MyAssembly.sldasm” ‘ 対象アセンブリのフルパス
pdmUser = Environ(“USERNAME”) ‘ 現在のWindowsユーザー名を使用 (PDMシステムと連携させる場合は、PDMのユーザー名に置き換える)
‘ ———–

‘ SolidWorksアプリケーションへの接続
On Error Resume Next
Set swApp = GetObject(, “SldWorks.Application”)
If swApp Is Nothing Then
Set swApp = CreateObject(“SldWorks.Application”)
swApp.Visible = True
End If
On Error GoTo 0

‘ — PDMチェックアウト処理 (ファイルロックによる模倣) —
If Not LockFile(assemblyPath) Then
MsgBox “エラー: アセンブリファイル ‘” & assemblyPath & “‘ は現在他のユーザーによって使用されています。”, vbExclamation
Exit Sub
End If

‘ チェックアウト成功。セッション管理情報を記録する(例)
‘ 実際には、PDMシステムにチェックアウト情報を登録するAPIコールなどを行う
Debug.Print “アセンブリ ‘” & assemblyPath & “‘ をチェックアウトしました。(User: ” & pdmUser & “)”

‘ — SolidWorksでの編集処理 —
On Error GoTo ErrorHandler ‘ エラー発生時の処理を設定
Set swModel = swApp.OpenDoc6(assemblyPath, swDocASSEMBLY, swOpenDocOptions_ReadOnly, “”, 0, 0) ‘ まず読み取り専用で開く
If swModel Is Nothing Then
MsgBox “アセンブリファイルを開けませんでした。”, vbCritical
GoTo CleanUp ‘ クリーンアップ処理へ
End If

‘ ここで、必要に応じてモデルの変更やプロパティの更新などを行う
‘ 例: カスタムプロパティの更新
Dim swCustPropMgr As SldWorks.CustomPropertyManager
Set swCustPropMgr = swModel.Extension.CustomPropertyManager(“”) ‘ デフォルトのプロパティマネージャー
Dim stat As Long
stat = swCustPropMgr.Set(“LastEditedBy”, pdmUser) ‘ 編集者情報を記録
stat = swCustPropMgr.Set(“EditDate”, Format(Now, “yyyy-mm-dd hh:nn:ss”)) ‘ 編集日時を記録

‘ 変更を保存
swModel.SaveAs assemblyPath ‘ 上書き保存
swModel.ClearChanges ‘ 変更履歴をクリア(保存したので)

Debug.Print “アセンブリ ‘” & assemblyPath & “‘ を編集し、保存しました。”

‘ — PDMチェックイン処理 —
‘ ここで、PDMシステムへのチェックイン処理を実装します。
‘ 例:
‘ Call PDM_CheckIn(assemblyPath, “変更内容のコメント”)
‘ PDM_CheckIn は、実際のPDMシステムAPIを呼び出す関数を想定しています。

‘ チェックインが完了したら、ロックを解除
UnlockFile assemblyPath
Debug.Print “アセンブリ ‘” & assemblyPath & “‘ のロックを解除しました。”

MsgBox “アセンブリの編集と保存が完了しました。”, vbInformation
GoTo CleanUp ‘ クリーンアップ処理へ

ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description & ” (Err.Number: ” & Err.Number & “)”, vbCritical
‘ エラー発生時でもロックを解除する
UnlockFile assemblyPath
Debug.Print “エラー発生のため、アセンブリ ‘” & assemblyPath & “‘ のロックを解除しました。”

CleanUp:
‘ 開いているドキュメントがあれば閉じる
If Not swModel Is Nothing Then
swApp.CloseDoc swModel.GetTitle
End If
‘ SolidWorksアプリケーションを終了させる場合は、ここで処理を追加
‘ swApp.ExitApp

End Sub

‘=============================================================================
‘ 実際のPDMシステム連携を模倣するダミー関数
‘=============================================================================
‘ Sub PDM_CheckIn(filePath As String, comment As String)
‘ ‘ ここに、実際のPDMシステムにチェックインするためのAPIコールを記述します。
‘ ‘ 例: Vault API, Teamcenter API など
‘ Debug.Print “PDMシステムにチェックイン中: ” & filePath & ” (Comment: ” & comment & “)”
‘ ‘ 実際には、成功/失敗の判定やエラーハンドリングが必要です。
‘ End Sub

【コードのポイント】

  • `LockFile`関数:
  • 対象ファイルのパスに`.lock`拡張子を付けたロックファイルパスを作成します。
  • `FileExists`関数でロックファイルの存在を確認し、存在すればロック失敗として`False`を返します。
  • `Open lockFilePath For Output Lock Read Write As #1` で、ロックファイルを排他モードで開きます。これにより、他のプロセスからの同時書き込みを防ぎます。
  • ロックファイルにユーザー名やタイムスタンプを記録しておくと、デバッグや管理に役立ちます。
  • `Close #1` でファイルを閉じ、ロックを完了します。
  • `UnlockFile`関数:
  • `Kill lockFilePath` でロックファイルを削除します。
  • `CheckOutAndEditAssembly`サブ:
  • `LockFile`を呼び出して、アセンブリファイルのロックを試みます。ロックに失敗した場合は、エラーメッセージを表示して処理を中断します。
  • ロックに成功したら、PDMシステムにチェックアウト情報を登録する(この例では、`Debug.Print`で模倣)処理を行います。
  • SolidWorksでアセンブリファイルを開き、必要に応じて編集・保存します。
  • 編集・保存後、`UnlockFile`を呼び出してロックを解除します。
  • エラーハンドリング: `On Error GoTo ErrorHandler` を設定し、処理中にエラーが発生した場合でも、必ず`UnlockFile`が実行されるようにします。これにより、ロックされたままファイルが使用できなくなる「デッドロック」状態を防ぎます。
  • セッション管理情報: `pdmUser` 変数に、PDMシステムで管理するユーザー名を格納します。実際のPDM連携では、この情報をPDMシステムに渡す必要があります。
  • カスタムプロパティの更新: 編集者や編集日時をカスタムプロパティに保存することで、誰がいつファイルを変更したかの履歴を追跡しやすくなります。

【注意点】

  • このファイルロックは簡易的な排他制御です。ネットワークの遅延や、ユーザーによる強制終了などにより、ロックファイルが残ってしまう可能性はゼロではありません。
  • より高度な排他制御が必要な場合は、PDMシステムが提供するAPIを使用することを強く推奨します。VBAからPDM APIを呼び出すには、通常、COMコンポーネントの参照設定などが必要になります。
  • ネットワークドライブへのアクセス権限にも注意が必要です。ロックファイルの作成・削除、アセンブリファイルへのアクセスには、適切な権限がなければなりません。

4. よくあるエラーとその回避策

SolidWorks VBA開発でよく遭遇するエラーと、その回避策をいくつかご紹介します。

  • 「オブジェクト変数またはWithブロック変数が設定されていません。」
  • 原因: オブジェクトが初期化されていない(`Nothing`のまま)状態で、そのオブジェクトのプロパティやメソッドを呼び出そうとした場合に発生します。
  • 回避策:
  • オブジェクト変数を宣言したら、必ず`Set オブジェクト変数 = …`で初期化します。
  • `GetObject`などで既存のアプリケーションインスタンスを取得する際は、`On Error Resume Next` を使用し、インスタンスが存在しない場合の処理を記述します。
  • `swModel` や `swAssembly` など、`OpenDoc6` の戻り値が`Nothing`になる可能性のあるオブジェクトは、必ず`If Not swModel Is Nothing Then …` のようにチェックしてから使用します。
  • 「ファイルが見つかりません。」
  • 原因: 指定したファイルパスが存在しない、あるいはパスの指定が間違っている場合に発生します。
  • 回避策:
  • ファイルパスを正確に記述します。相対パスではなく、フルパスを使用することを推奨します。
  • `Dir()` 関数や `FileSystemObject` を使って、ファイルが存在するかどうかを事前にチェックします。
  • (アセンブリの場合)参照されている部品ファイルが見つからない場合も、同様のエラーが発生することがあります。
  • 「アクセスが拒否されました。」
  • 原因: ファイルやフォルダに対する書き込み権限がない場合に発生します。
  • 回避策:
  • 対象のファイルやフォルダのプロパティを確認し、書き込み権限が付与されているか確認します。
  • (ネットワークドライブの場合)ネットワーク上の共有フォルダへのアクセス権限を確認します。
  • (ロックファイルの場合)ロックファイルの作成・削除権限があるか確認します。
  • 「COM オブジェクトが、初期化されていません。」
  • 原因: SolidWorksアプリケーションが正常に起動していない、あるいはVBAからSolidWorksへの接続が確立できていない場合に発生することがあります。
  • 回避策:
  • SolidWorksが起動しているか確認します。
  • `GetObject`や`CreateObject`のコードが正しいか確認します。
  • VBAエディタで「ツール」→「参照設定」を開き、「SOLIDWORKS xxxx Type Library」がチェックされているか確認します。(通常は自動で設定されますが、念のため)

【エラーハンドリングの重要性】

これらのエラーに適切に対応するために、`On Error GoTo` ステートメント を活用したエラーハンドリングは必須です。エラー発生時に処理を中断するだけでなく、リソースの解放(ファイルのクローズ、ロックの解除など)を確実に行うことで、システム全体の安定性を高めることができます。

5. まとめ:SolidWorks VBAで、より高度な自動化の世界へ!

いかがでしたでしょうか?

今回は、SolidWorks VBAを使ってアセンブリファイルのメタデータを取得し、ファイルシステム制御をベースにしたPDMシステムへのチェックイン・チェックアウト制御という、一歩踏み込んだテーマに挑戦しました。

  • SolidWorksファイルはバイナリ形式だが、APIを使えば構造化された情報にアクセスできること。
  • PDM連携では、セッション管理と排他制御が重要であり、ファイルロックはその一例であること。
  • エラーハンドリングとリソース解放の重要性。

これらの知識とコード例は、皆さんがSolidWorks VBAのスキルを次のレベルへと引き上げるための強力な一歩となるはずです。

「マクロの記録」から脱却し、APIを理解し、ファイルシステムを自在に操ることで、皆さんの業務効率は飛躍的に向上することでしょう。そして、PDMシステムとの連携という、より高度な自動化の世界への扉が開かれます。

ここをクリアすれば、SolidWorks VBAの基本はバッチリですよ!

ぜひ、今回ご紹介したコードを参考に、ご自身の環境で試してみてください。そして、SolidWorks VBAの可能性を、さらに広げていきましょう!

もし、この内容についてご質問や、「こんなこともできるの?」といった疑問があれば、ぜひコメントで教えてくださいね。皆さんの熱意にお応えできるよう、私もさらに深掘りしていきたいと思います!

それでは、また次回の記事でお会いしましょう!

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