図面を「データ」として支配せよ:属性値を用いた自動リネーム保存の極意
こんにちは。今日もCADの海で、効率化という名の航路を探しているあなたへ。
「マクロの記録」で、なんとか簡単な操作を自動化できた。一歩前へ踏み出した自分を褒めてあげてください。でも、あなたは気づいているはずです。「記録しただけでは、現場の複雑なルールには太刀打ちできない」ということに。
今日、私たちが挑むのは、単なる「記録」ではありません。「図面の中身(データ)を読み取り、その情報に基づいて図面自身を再定義する」という、一歩進んだ自動化の領域です。
具体的には、「図面枠ブロック内の『図番』という属性値を読み取り、その値をファイル名にして自動でSaveAs(名前を付けて保存)する」というツールを構築します。
これをマスターすれば、あなたは「図面を引く人」から「図面管理の仕組みを作る人」へと進化します。さあ、一緒にコードの深淵を覗いてみましょう。
1. 設計思想:オブジェクトの階層構造を理解する
プログラミングを始める前に、AutoCADが「図面をどう見ているか」という地図(アーキテクチャ)を頭に叩き込んでください。ここを曖昧にすると、必ずエラーの迷宮に迷い込みます。
図面の中には、無数のオブジェクトが眠っています。今回のターゲットは「属性値を持つブロック」です。その階層構造は以下のようになっています。
1. ActiveDocument(開いている図面ファイルそのもの)
2. PaperSpace / ModelSpace(図面が描かれている空間)
3. BlockReference(配置されたブロックの「実体」)
4. AttributeReference(ブロックに紐付いた「属性情報」)
5. TextString(属性の中に書き込まれた「実際の文字」)
私たちがやりたいのは、「空間をスキャンし、特定の名前を持つブロックを見つけ、その中の特定のタグを探し出し、文字列を抜き出す」という一連の探索プロセスです。
2. 実装:属性値を抽出して保存するコード
それでは、魂を込めたコードを提示します。このコードは、単に動くだけでなく、実務で発生しうる「予期せぬ事態」を考慮した設計にしています。
Option Explicit
''' <summary>
''' 図面内の特定ブロックから属性値を抽出し、その値でファイル名を変更して保存する
''' </summary>
Sub AutoRenameAndSave()
On Error GoTo ErrorHandler
Dim acadDoc As AcadDocument
Set acadDoc = ThisDrawing
' --- 設定値 ---
Const TARGET_BLOCK_NAME As String = "TITLE_BLOCK" ' 探したいブロックの名前
Const TARGET_TAG_NAME As String = "DWG_NO" ' 抽出したい属性のタグ名
' --------------
Dim objEntity As AcadEntity
Dim objBlock As AcadBlockReference
Dim varAttributes As Variant
Dim i As Integer
Dim extractedValue As String
Dim newFilePath As String
Dim currentPath As String
extractedValue = ""
' 1. 図面内のオブジェクトを走査(ここではレイアウト空間を対象)
' ※ModelSpaceを対象にする場合は acadDoc.ModelSpace に変更してください
For Each objEntity In acadDoc.PaperSpace
' オブジェクトがブロック参照かどうかを判定
If TypeOf objEntity Is AcadBlockReference Then
Set objBlock = objEntity
' ブロックの名前が一致するか確認 (EffectiveNameは動的ブロックにも対応)
If UCase(objBlock.EffectiveName) = UCase(TARGET_BLOCK_NAME) Then
' 2. 属性値の取得
' GetAttributesは属性オブジェクトの配列を返します
varAttributes = objBlock.GetAttributes
For i = LBound(varAttributes) To UBound(varAttributes)
' タグ名が一致するかチェック
If UCase(varAttributes(i).TagString) = UCase(TARGET_TAG_NAME) Then
extractedValue = varAttributes(i).TextString
Exit For
End If
Next i
If extractedValue <> "" Then Exit For ' 見つかったらループを抜ける
End If
End If
Next objEntity
' 3. 抽出結果のチェック
If extractedValue = "" Then
MsgBox "指定された属性値が見つかりませんでした。", vbExclamation
Exit Sub
End If
' 4. ファイル名のクレンジング(重要!)
' Windowsのファイル名に使えない文字 (\ / : * ? " < > |) を除去する
extractedValue = CleanFileName(extractedValue)
' 5. 保存パスの生成
' 現在のフォルダパスを取得し、新しいファイル名を結合
currentPath = acadDoc.Path
If currentPath = "" Then
MsgBox "図面が一度も保存されていません。先に一度保存してください。", vbCritical
Exit Sub
End If
' フォルダパスの末尾に \ がない場合の処理
If Right(currentPath, 1) <> "\" Then currentPath = currentPath & "\"
newFilePath = currentPath & extractedValue & ".dwg"
' 6. SaveAsの実行
' 注意: SaveAsは現在のドキュメントのパス自体を書き換えます
acadDoc.SaveAs newFilePath
MsgBox "保存完了: " & vbCrLf & newFilePath, vbInformation
Exit Sub
ErrorHandler:
MsgBox "エラーが発生しました。" & vbCrLf & _
"番号: " & Err.Number & vbCrLf & _
"内容: " & Err.Description, vbCritical
End Sub
''' <summary>
''' ファイル名に使用できない禁止文字を置換する関数
''' </summary>
Private Function CleanFileName(ByVal fileName As String) As String
Dim invalidChars As Variant
Dim i As Integer
' 禁止文字のリスト
invalidChars = Array("\", "/", ":", "*", "?", """", "<", ">", "|")
For i = LBound(invalidChars) To UBound(invalidChars)
fileName = Replace(fileName, invalidChars(i), "_")
Next i
CleanFileName = fileName
End Function
3. ここがプロの視点:陥りやすい罠と回避術
コードをコピペして動いた、それで満足してはいけません。エンジニアとして、以下の「なぜ?」を理解してください。
① `Name` ではなく `EffectiveName` を使え
ブロックには「動的ブロック(Dynamic Block)」という存在があります。ユーザーが形状を変えた瞬間、そのブロックの `Name` プロパティは `*U…` といった匿名の名前に変わってしまいます。しかし、`EffectiveName` を使えば、元の定義名を正しく取得できます。これは実務における鉄則です。
② ファイル名の「クレンジング」を忘れるな
ここが初級者と中級者の最大の分かれ道です。
図面内の属性値に「図面/A-01」のようにスラッシュが入っていた場合、そのまま `SaveAs` しようとすると、Windowsは「/」をフォルダの区切りと誤認し、「そんなフォルダはありません」とエラーを吐きます。
`CleanFileName` 関数のように、禁止文字をアンダースコア `_` などに置換する処理を挟む。これこそが、「壊れないツール」を作るための作法です。
③ `SaveAs` のライフサイクル
`SaveAs` メソッドを実行すると、AutoCAD内で現在開いている図面の「身分(パス)」が、新しい名前へと切り替わります。もし、元のファイルも残しておきたい場合は、`SaveAs` ではなく、一度別の手段でコピーを作成するか、ロジックを慎重に設計する必要があります。
4. 次のステップへ
このツールはまだ、一つの機能に特化した「部品」に過ぎません。
しかし、この「属性を読み取る」「文字列を加工する」「ファイル操作を行う」という3つのステップを組み合わせることで、以下のような高度な自動化へと拡張できます。
- 一括リネーム: フォルダ内の全DWGを順次開き、属性値でリネームして保存する。
- 台帳自動作成: 属性値を読み取り、Excelに図番とファイル名を一覧出力する。
「マクロの記録」という魔法の杖を捨て、コードという名の設計図を手にしたあなた。
AutoCAD VBAの世界は、あなたが想像する以上に広大で、そして制御可能なものです。
ここをクリアすれば、AutoCAD VBAの基本はバッチリですよ。
さあ、次はどんな仕組みを作りますか?
Happy Coding!
