【実務・中級編】【上級プロフェッショナル向け】図面ファイル名の命名規則強制と自動リネーム機能 – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD VBAを掌握する極限の知見:図面命名規則の強制と自動リネーム制御

開発プロジェクトのリーダーである私たちが日々直面する最大のストレスの一つは、設計者たちが勝手気ままなファイル名でDWGを保存することだ。「`最終版.dwg`」「`RC造_配筋_修正_20231012_fix.dwg`」――このようなカオスが放置された瞬間から、PDM(製品データ管理)システム連携は破綻し、自動図面処理バッチは沈黙する。

今回は、AutoCAD VBAを用いて「図面保存時に命名規則を強制し、違反者を自動補正する(あるいは保存をブロックする)」ための、妥協なきプロダクションコードを伝授する。

単に「文字列を置換するだけのVBA」ではない。AutoCADのドキュメントライフサイクル、イベントハンドリングの罠、そしてOSのファイルI/Oの競合を防ぐための堅牢なアーキテクチャを解説しよう。

—

1. なぜ「通常のイベント処理」では破綻するのか?

多くの初学者は、`AcadDocument`の `AecbDocument` イベントや、`DocumentCollection` の `BeginSave` イベントを使ってファイル名チェックを実装しようとする。しかし、ここに大きな罠がある。

保存イベントの落とし穴

`BeginSave` イベント内でファイル名を書き換えようとしても、すでにAutoCADのセーブエンジンは対象ファイルへの排他ロックを獲得しており、イベントハンドラ内から安全に `SaveAs` を再再帰的に呼び出すことはデッドロックや予期せぬクラッシュを引き起こす。

したがって、「保存の完全な阻止、または別名保存(SaveAs)への安全なルーティング」を行うには、以下の設計アプローチが不可欠となる。

1. ActiveXの限界を見極める: AutoCAD VBAのイベントだけでは、ダイアログ経由の保存(`QSAVE` や `SAVEAS`)における「保存先の強制」を完全にインターセプトしきれない場合がある。
2. トランザクションとファイルI/Oの分離: 図面データベース内のカスタムプロパティに「正規化されたメタデータ」を保持させ、OS上のファイル名と同期させる。
3. 厳格な正規表現(RegEx)の適用: 企業標準の命名規則(例: `[プロジェクトコード]-[図面種別]-[図番]-[リビジョン].dwg`)を1ルールの妥協もなく検証する。

—

2. 命名規則の仕様定義

今回の実装では、以下の命名規則を強制するケースを想定する。

> フォーマット: `[A-Z0-9]{4}-[A-Z]{2}-[0-9]{3}-R[0-9]{2}.dwg`
> 例: `PRJ1-AR-101-R01.dwg`
>
> `PRJ1`: プロジェクトコード(4桁英数)
> `AR`: дисциплина/部門コード(2桁英字:AR=建築, ST=構造 など)
> `101`: 図面番号(3桁数字)
> `R01`: リビジョン(R+2桁数字)

この規則に合致しない場合、保存処理をキャッチし、自動リネーム(またはリネームを促すプロンプトと強制補正)を実行する。

—

3. プロダクションコード実装

以下のコードをAutoCADのVBAエディタ(`ThisDrawing` または標準モジュール)に実装する。実業務でそのまま耐えうるよう、エラーハンドリングとファイルシステム操作(`Scripting.FileSystemObject`)を組み込んでいる。

命名規則検証・自動リネームエンジン

Option Explicit

‘ ————————————————————————-
‘ 命名規則バリデーションおよび自動リネーム統括モジュール
‘ ————————————————————————-

‘ 組織標準の命名規則を表す正規表現パターン
‘ 例: PRJ1-AR-101-R01.dwg
Private Const STANDARD_PATTERN As String = “^[A-Z0-9]{4}-[A-Z]{2}-\d{3}-R\d{2}\.dwg$”

/

  • 図面保存前のフック関数(外部のイベントプロシージャから呼び出しを推奨)
  • @return Boolean 正常に保存処理を続行できる場合はTrue、中断・変更時はFalse

/
Public Function EnforceDrawingNamingRule() As Boolean
On Error GoTo ErrorHandler

Dim fso As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)

Dim currentFullPath As String
currentFullPath = ThisDrawing.FullName

‘ まだ一度も保存されていない(図面名が未定義・Drawing1.dwg等)の場合
If currentFullPath = “” Or InStr(ThisDrawing.Name, “Drawing”) = 1 Then
MsgBox “新規図面です。保存前に標準の命名規則に従ったファイル名義に変更してください。”, vbExclamation, “命名規則ガード”
EnforceDrawingNamingRule = False
Exit Function
End If

Dim currentFileName As String
currentFileName = fso.GetFileName(currentFullPath)
Dim parentFolder As String
parentFolder = fso.GetParentFolderName(currentFullPath)

‘ 正規表現によるパターンマッチング
If Not ValidateFileName(currentFileName) Then
MsgBox “【警告】ファイル名が企業の標準命名規則に違反しています。” & vbCrLf & _
“現在の名前: ” & currentFileName & vbCrLf & _
“パターン: 4桁英数-2桁部門-3桁図番-Rリビジョン (例: PRJ1-AR-101-R01.dwg)”, vbCritical, “命名規則違反”

‘ 自動リネーム試行、または対話型修正プロンプトへ誘導
Dim correctedName As String
correctedName = PromptAndGenerateCorrectName(currentFileName)

If correctedName <> “” Then
Dim newFullPath As String
newFullPath = fso.BuildPath(parentFolder, correctedName)

‘ すでに同名ファイルが存在しないかチェック
If fso.FileExists(newFullPath) Then
MsgBox “エラー: 修正後のファイル名は既に存在するためリネームできません: ” & correctedName, vbCritical
EnforceDrawingNamingRule = False
Exit Function
End If

‘ 図面を開いたまま別名保存して古いファイルを削除(またはリネーム保存)
ThisDrawing.SaveAs newFullPath

‘ 旧ファイルの削除(必要に応じて)
If fso.FileExists(currentFullPath) Then
fso.DeleteFile currentFullPath
End If

MsgBox “ファイル名を規則通りに自動リネームして保存しました。” & vbCrLf & correctedName, vbInformation
EnforceDrawingNamingRule = True
Exit Function
Else
‘ ユーザーが修正をキャンセルした場合、保存を中止
EnforceDrawingNamingRule = False
Exit Function
End If
End If

‘ 規則に適合している場合はそのまま保存を許可
EnforceDrawingNamingRule = True
Exit Function

ErrorHandler:
MsgBox “命名規則チェック中に致命的なエラーが発生しました: ” & Err.Description, vbCritical
EnforceDrawingNamingRule = False
End Function

Private Function ValidateFileName(ByVal fileName As String) As Boolean
Dim regEx As Object
Set regEx = CreateObject(“VBScript.RegExp”)

With regEx
.Pattern = STANDARD_PATTERN
.IgnoreCase = False ‘ 大文字小文字を厳格に区別
.Global = False
End With

ValidateFileName = regEx.Test(fileName)
End Function

Private Function PromptAndGenerateCorrectName(ByVal invalidName As String) As String
‘ 実務ではここでユーザーに入力を促すか、自動パースロジックを走らせる
‘ 今回は簡易的にインプットボックスによる対話的修正を実装
Dim inputVal As String
inputVal = InputBox(“正しい命名規則に基づき、新しいファイル名を入力してください。” & vbCrLf & _
“(例: PRJ1-AR-101-R01.dwg)”, “自動リネーム支援”, invalidName)

If inputVal = “” Then
PromptAndGenerateCorrectName = “”
Exit Function
End If

‘ 再度バリデーション
If ValidateFileName(inputVal) Then
PromptAndGenerateCorrectName = inputVal
Else
MsgBox “入力された名前も規則に違反しています。処理を中断します。”, vbExclamation
PromptAndGenerateCorrectName = “”
End If
End Function

—

4. 現場へ導入する際のアーキテクチャ上の注意点

この仕組みを全社展開するにあたり、チーフアーキテクトとして以下のガバナンスを強く推奨する。

1. アカデミックなモジュール配布の回避 (AcAdd.lsp / 部隊共通テンプレート)
VBAコード単体を各設計者のPCにばら撒いても、設定の改ざんやマクロ無効化によって簡単にバイパスされる。本気で標準化を徹底するのであれば、このロジックを組み込んだ社内標準図面テンプレート(`acad.dwt`)を強制配布し、さらにドキュメントオープン時のイベント(`AcadDocument_Activate` 等)で監視レイヤーを張るべきだ。
2. 排他制御とトランザクションの整合性
`.SaveAs` をコード内から実行する際、AutoCADのバックグラウンドプロセスがビジー状態であるときにコマンドを割り込ませると、致命的なメモリリークや図面破損(Fatal Error)を誘発するリスクがある。そのため、保存イベントのインターセプトには極力 `Document.SendCommand` ではなく、上記コードのように直接オブジェクトモデルのメソッド(`SaveAs`)を叩く設計が安全である。

総括

「ファイル名ぐらい自由にさせてくれ」という現場の声を跳ね返し、データの整合性を担保するのがプロフェッショナルなBIM/CAD管理者の仕事である。
今回提供したコードをベースに、自社のプロジェクトコード体系に合わせた正規表現チューニングを行い、今すぐ混沌としたファイルサーバーを浄化してほしい。

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