「転記ミス」を設計思想で根絶せよ:SolidWorks 図面自動化における「プロパティ駆動型」設計の極意
現場のエンジニアが「図面番号の打ち間違い」や「材質の転記ミス」を報告してくる。その時、多くの「自動化担当者」が取る行動は、図面内のテキスト(Note)を力技で検索し、その値を書き換えるという、極めて脆いコードを書くことだ。
断言する。それは「自動化」ではない。単なる「不安定なスクリプト」だ。
もし、テンプレートのレイアウトが1ミリ変わった、あるいは注釈の名称が変更されただけで、そのスクリプトは即座に沈黙する。そんなものは、プロフェッショナルの業務フローに組み込む価値はない。
本記事では、外部データ(CSV/テキスト)から図面のメタデータを流し込む際、単に値を書き込むのではなく、「SolidWorksのデータ構造(Custom Property)をマスターとし、図面表示をそれに従わせる」という、堅牢な設計思想に基づいた実装方法を伝授する。
1. 致命的な誤解:Noteを直接操作してはいけない
初心者が陥る最大の罠は、「図面枠内のテキスト(Noteオブジェクト)を直接見つけ出し、そのTextプロパティを書き換える」という手法だ。
なぜこれが「悪」なのか? 理由は明白だ。
1. 依存性の高さ: 図面枠のレイアウト変更(Noteの名称変更や配置変更)に極めて弱い。
2. 整合性の欠如: Noteの値を書き換えても、モデル(部品・アセンブリ)が持つプロパティとは同期されない。
3. メンテナンスコスト: 項目が増えるたびに、コード内の「検索ロジック」を書き直す必要がある。
プロフェッショナルの解法:プロパティ駆動設計
我々が目指すべきは、「Custom Property(カスタムプロパティ)を書き換え、図面枠のNoteはプロパティを参照(リンク)させておく」という設計だ。
- データソース (CSV) $\rightarrow$ SolidWorks Custom Property $\rightarrow$ 図面枠のNote ($PRP)
このフローであれば、図面枠のデザインがどう変わろうとも、プロパティ名さえ一致していればマクロは一切の修正を必要とせず、正確に動作し続ける。
2. 実装の設計図:堅牢な自動化の3層構造
優れた自動化ツールは、以下の3つのレイヤーで構成されるべきだ。
1. Data I/O Layer: CSVファイルを読み込み、キー(項目名)と値(データ)のペアをメモリ上に展開する。
2. Logic Layer: 読み込んだデータに基づき、SolidWorksの `CustomPropertyManager` を介してプロパティを更新する。
3. Error Handling Layer: ファイル不在、フォーマット不正、SolidWorksの異常終了を検知し、ユーザーに適切なフィードバックを行う。
3. プロダクション・コード例
以下に、実務でそのまま運用可能なレベルまで作り込んだVBAコードを示す。単なるコピペで終わらせず、各行に込められた「意図」を読み取ってほしい。
'**
' Module: DrawingPropertyAutomator
' Description: CSVから図面プロパティを一括更新する堅牢な実装例
' Author: Chief Architect
'**
Option Explicit
' 定数定義:マジックナンバーを排除し、保守性を高める
Private Const DELIMITER As String = "," ' CSVの区切り文字
Sub Main()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim csvPath As String
On Error GoTo ErrorHandler
' 1. SolidWorksへの接続確認
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox "エラー: SolidWorksで図面ファイルを開いてから実行してください。", vbCritical
Exit Sub
End If
If swModel.GetType <> swDocDRAWING Then
MsgBox "エラー: アクティブなドキュメントが図面ではありません。", vbCritical
Exit Sub
End If
Set swDraw = swModel
' 2. CSVファイルの選択 (ユーザーにファイルを選ばせることでパスのハードコードを防ぐ)
csvPath = GetFilePath()
If csvPath = "" Then Exit Sub ' キャンセル時
' 3. データ読み込みとプロパティ更新の実行
Debug.Print "--- プロセス開始 ---"
UpdatePropertiesFromCSV swModel, csvPath
Debug.Print "--- プロセス完了 ---"
' 4. 再描画して変更を反映
swModel.ForceRebuild3 True
MsgBox "図面プロパティの更新が完了しました。", vbInformation
Exit Sub
ErrorHandler:
MsgBox "予期せぬエラーが発生しました。" & vbCrLf & _
"Error No: " & Err.Number & vbCrLf & _
"Description: " & Err.Description, vbCritical
End Sub
''' <summary>
''' CSVを読み込み、CustomPropertyManagerを使用してプロパティを書き換える
''' </summary>
Private Sub UpdatePropertiesFromCSV(swModel As SldWorks.ModelDoc2, filePath As String)
Dim fso As Object
Dim ts As Object
Dim line As String
Dim dataParts() As String
Dim propName As String
Dim propValue As String
Dim swCustPropMgr As SldWorks.CustomPropertyManager
' FileSystemObjectを使用してファイル操作の堅牢性を確保
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FileExists(filePath) Then
Err.Raise 53, , "指定されたCSVファイルが見つかりません。"
End If
' 図面のカスタムプロパティマネージャーを取得
' ※図面全体のプロパティ(General)を対象とする
Set swCustPropMgr = swModel.Extension.CustomPropertyManager("")
Set ts = fso.OpenTextFile(filePath, 1) ' 1 = ForReading
Do While Not ts.AtEndOfStream
line = ts.ReadLine
If Trim(line) <> "" Then
dataParts = Split(line, DELIMITER)
' 配列の要素数チェック(不正な行によるクラッシュを防止)
If UBound(dataParts) >= 1 Then
propName = Trim(dataParts(0))
propValue = Trim(dataParts(1))
' プロパティの書き込み(Add3は存在しない場合は追加、存在する場合は更新)
' 第3引数に swCustomPropertyReplace を指定することで上書きを実現
swCustPropMgr.Add3 propName, swCustomPropertyReplace, propValue, swCustomPropertyReplace
Debug.Print "Updated: [" & propName & "] -> [" & propValue & "]"
Else
Debug.Print "Warning: 不正なフォーマットの行をスキップしました: " & line
End If
End If
Loop
ts.Close
Set ts = Nothing
Set fso = Nothing
End Sub
''' <summary>
''' ファイル選択ダイアログを表示
''' </summary>
Private Function GetFilePath() As String
Dim fd As Object
Set fd = Application.FileDialog(3) ' msoFileDialogFilePicker
With fd
.Title = "メタデータCSVファイルを選択してください"
.Filters.Clear
.Filters.Add "CSV Files", "*.csv;*.txt"
.AllowMultiSelect = False
If .Show = -1 Then
GetFilePath = .SelectedItems(1)
Else
GetFilePath = ""
End If
End With
End Function
4. 実装の極意:なぜこのコードは「強い」のか
このコードを単なる「動くコード」としてではなく、「プロダクション品質」として昇華させているポイントを解説する。
① `Add3` メソッドの戦略的利用
`swCustPropMgr.Add3` を使用している点に注目してほしい。第3引数に `swCustomPropertyReplace` を指定することで、「プロパティがなければ作成し、あれば上書きする」という挙動を1行で実現している。これにより、`If Exists Then Update Else Add` といった冗長でバグの温床となるロジックを排除している。
② `FileSystemObject` (FSO) の採用
VBA標準の `Open` ステートメントではなく、`Scripting.FileSystemObject` を採用している。これは、ファイルが存在しない場合のハンドリングや、ファイルの読み取り権限、文字コードの扱いにおいて、標準機能よりも圧倒的に堅牢で予測可能な挙動を示すためだ。
③ エラーハンドリングの階層化
`On Error GoTo ErrorHandler` を使い、エラーが発生した際に「何が起きたか(エラー番号と内容)」をユーザーに明示的に伝える設計にしている。自動化ツールにおいて、「なぜか動かない(が、理由がわからない)」状態は、開発者にとって最大の損失である。
④ データバリデーション
`Split` した後の配列要素数チェック(`UBound(dataParts) >= 1`)を忘れてはならない。CSVの末尾に空行があったり、カンマが足りない行があったりした場合、このチェックがないと `Subscript out of range` で即座にクラッシュする。
5. 運用に向けたアドバイス
このマクロを導入する際、必ず以下の準備を徹底すること。
1. テンプレートの整備:
図面枠のNoteに対し、あらかじめ「プロパティのリンク」を設定しておくこと。
例:材質を表示するNoteのテキストを `$PRP:”Material”` と設定する。
2. CSVフォーマットの標準化:
`項目名,値` という形式を徹底させる。ヘッダー行が必要な場合は、コード内で `ts.SkipLine` を使ってスキップするロジックを追加すること。
3. バックアップの自動化:
大規模な更新を行うマクロの場合、実行前に `swModel.SaveAs2` でバックアップを作成する処理を検討すべきだ。
結論
自動化エンジニアの仕事は、コードを書くことではない。「変化に強く、ミスが物理的に起こり得ない仕組み」を設計することだ。
今回紹介した「プロパティ駆動型」のアプローチは、一見すると回り道に見えるかもしれない。しかし、長期的なメンテナンスコストと、現場での信頼性を考えれば、これこそが最短ルートである。
次に君がコードを書くとき、そのNoteを直接触ろうとしていないか? 自問自答してほしい。
