AutoCAD VBAの深淵:ファイル名からメタデータを抽出する「堅牢な設計」の極意
AutoCADの自動化において、最も頻繁に遭遇するミスは「パス文字列の単純な操作」に起因するものです。
「`Left`や`Instr`を駆使してファイル名を切り出せばいい」と考えているなら、それは現場で必ず手痛いバグを招きます。ファイル名にはスペースが含まれるかもしれないし、予期せぬハイフンが混じるかもしれない。文字列操作を甘く見ることは、自動化の設計を甘く見ることと同義です。
今回は、`AcadDocument.FullName`から「図面番号」と「リビジョン」を抽出し、図面枠へ反映させるための、プロフェッショナルな設計手法を伝授します。
—
1. なぜ「泥臭い文字列操作」は破綻するのか
初心者が書きがちな`Split`関数や`Mid`関数による切り出しは、命名規則が少し変わった瞬間にすべて崩壊します。
- 変更への脆弱性: 命名規則の変更=コードの全修正。
- 例外処理の欠如: フォルダ名に同じ文字が含まれていた場合の誤検知。
- 保守性の欠如: どこで何をしているか分からないスパゲッティコード。
我々エンジニアが目指すべきは、「ルールそのものを正規表現(RegExp)で抽象化し、データ抽出ロジックと属性反映ロジックを完全に分離すること」です。
—
2. プロダクションコード:堅牢な抽出エンジンの実装
以下のコードは、`VBScript.RegExp`オブジェクトを利用し、命名規則(例: `DRW-12345-A.dwg`)から図面番号とリビジョンを分離して抽出するテンプレートです。
Option Explicit
‘ 図面情報を格納するためのユーザー定義型
Public Type DrawingInfo
DrawingNumber As String
Revision As String
End Type
Public Sub UpdateTitleBlockFromFilename()
Dim doc As AcadDocument
Set doc = ThisDrawing
‘ 1. パスからファイル名のみを抽出
Dim fName As String
fName = Mid(doc.FullName, InStrRev(doc.FullName, “\”) + 1)
‘ 2. 正規表現による解析
Dim info As DrawingInfo
If ParseFilename(fName, info) Then
‘ ここで属性反映処理を呼び出す
Debug.Print “図面番号: ” & info.DrawingNumber
Debug.Print “リビジョン: ” & info.Revision
‘ UpdateAttributes(info) ‘ 実装例
Else
MsgBox “命名規則に従っていないファイルです: ” & fName, vbCritical
End If
End Sub
Private Function ParseFilename(ByVal fName As String, ByRef outInfo As DrawingInfo) As Boolean
Dim regEx As Object
Set regEx = CreateObject(“VBScript.RegExp”)
‘ 正規表現パターン: (図面番号)-(リビジョン).dwg
‘ 命名規則が変わっても、このパターンを修正するだけで対応可能
regEx.Pattern = “^(DRW-\d+)-([A-Z])\.dwg$”
regEx.IgnoreCase = True
If regEx.Test(fName) Then
Dim matches As Object
Set matches = regEx.Execute(fName)
outInfo.DrawingNumber = matches(0).SubMatches(0)
outInfo.Revision = matches(0).SubMatches(1)
ParseFilename = True
Else
ParseFilename = False
End If
End Function
—
3. 実務で「生き残る」ための3つの鉄則
① 処理を「抽出」と「反映」に分ける
上記のコードでは、解析ロジック(`ParseFilename`)と属性反映ロジックを分離しています。将来的に属性反映先がExcelになったり、データベース(SQL Server等)になったりしても、解析部分は一切変更する必要がありません。これが「保守性」の正体です。
② `AcadDocument.FullName`の罠を知る
`FullName`は、図面が一度も保存されていない場合、空文字列を返します。未保存の図面でこの処理を実行するとエラーになるため、必ず`doc.Saved`プロパティを確認するか、エラーハンドリング(`On Error Resume Next`)でガードを固めてください。
③ 属性ブロックとの付き合い方
図面枠の属性(`AcadAttributeReference`)は、ブロック参照(`AcadBlockReference`)の中に隠れています。`GetAttributes`メソッドで配列として取得し、タグ名でループを回して一致するものを更新する。この一連の動作を「関数化」して共通モジュールに格納しておくことが、チーム開発における正攻法です。
—
結論:自動化は「再利用性」がすべて
単にファイル名から文字列を抜き出すだけなら、誰でも書けます。しかし、「仕様変更を前提とした拡張性」と「エラー発生時の安全性」を組み込むことこそが、エンジニアの腕の見せ所です。
今日からあなたの書くコードは、単なるスクリプトではなく、組織の業務基盤の一部であるという意識を持ってください。正規表現という強力な武器を手に、複雑な命名規則の泥沼から脱出し、より高次元な自動化へとステップアップしましょう。
質問があればいつでも歓迎します。現場の泥臭い課題こそ、最高の技術的挑戦なのですから。
