【上級プロフェッショナル向け】図面ファイル名の命名規則強制と自動リネーム機能
図面管理の崩壊は、多くの場合「ファイル名の属人化」から始まる。
`最終版.dwg`、`SX-990_fix_rev2_nakamura.dwg`――このようなカオスを放置すれば、PDM(製品データ管理)やERPとの連携時にシステムが沈黙するか、最悪の場合は誤ったリビジョンでの加工・製造という致命的なインシデントを引き起こす。
AutoCAD VBAの標準機能において、ファイル保存時のフック(イベント)は極めて限定的かつトリッキーである。
今回は、単なる文字列置換のサンプルコードではない。Windows APIの動的制御、AutoCADのドキュメントライフサイクル、そしてトランザクション安全性を極限まで高めた「ファイル名命名規則の強制と自動リネームエンジン」の実装を解説する。
シニアエンジニアおよび社内システム管理者が、明日から全社のCAD環境に投入できる実戦コードを提示しよう。
—
1. アーキテクチャ設計:なぜ「保存時」の介入は難しいのか
AutoCAD VBAには、.NET APIの `DocumentCollection.DocumentLock` や `Database.SaveComplete` のような洗練された非同期イベントハンドラが豊富にあるわけではない。VBAの `AcadDocument` イベント(`AczDocumentEvents`)において、ファイル保存を完全に制御するには以下の壁を超える必要がある。
1. `SaveAs` の多重フック: `BeginSave` イベントはキャッチできても、そこでドキュメント名を書き換えて再保存すると無限ループに陥る危険性がある。
2. 排他制御の競合: Windows上でファイルが開かれている最中に、VBAから直接 `FileSystemObject` 等でリネームを行おうとすると、ファイル共有違反(Error 70)が発生する。
3. アクティブドキュメントのコンテキスト維持: マルチドキュメント環境(SDI=0)において、どのデータベースを対象に処理しているかを厳密に特定しなければならない。
これらを解決するため、本アーキテクチャでは「保存前イベントでのバリデーション + WindowsシェルAPIを介した安全なアトミックリネーム」のスキームを採用する。
—
2. 実装コード:完全版自動リネーム・エンジン
以下のコードは、特定のプロジェクトコード、図面種別、リビジョン番号を含む正規表現ベースの命名規則(例: `PRJ-9999_A-101_v01.dwg`)を強制する。違反している場合は、自動的に標準フォーマットへ整形してリネームを断行する。
このコードは、ThisDrawingモジュールおよび標準モジュールに分割して配置する。
① ThisDrawing モジュール(イベント監視)
Option Explicit
‘ ドキュメントイベントの有効化
Private WithEvents AppEvents As AcadApplication
Private Sub Document_Initialize()
Set AppEvents = ThisDrawing.Application
End Sub
Private Sub AcadDocument_BeginSave(ByVal FileName As String)
On Error GoTo ErrorHandler
‘ 保存処理の無限ループを防ぐフラグ制御
Static isProcessing As Boolean
If isProcessing Then Exit Sub
isProcessing = True
Dim currentPath As String
Dim currentName As String
Dim fso As Object
currentPath = ThisDrawing.Path
currentName = ThisDrawing.Name
‘ まだ一度も保存されていない図面(Drawing1.dwg等)はスキップ
If currentPath = “” Or currentName = “” Then
isProcessing = False
Exit Sub
End If
‘ 命名規則バリデーション & 自動リネーム実行
If Not ValidateNamingConvention(currentName) Then
Dim correctedName As String
correctedName = GenerateStandardizedName(currentName)
‘ AutoCADのネイティブ保存を一度中断・バイパスするため、
‘ 一時的にイベントを抑制して別名保存を実行する
MsgBox “【CAD管理システム】” & vbCrLf & _
“ファイル名が命名規則に違反しています。” & vbCrLf & _
“自動的に次の標準名に変更して保存します:” & vbCrLf & correctedName, _
vbExclamation, “命名規則強制ポリシー”
Dim fullNewPath As String
fullNewPath = currentPath & “\” & correctedName
‘ アクティブ図面を指定パスで別名保存
ThisDrawing.SaveAs fullNewPath
‘ 古い不正名ファイルを削除(必要に応じてアーカイブフォルダへ移動)
Set fso = CreateObject(“Scripting.FileSystemObject”)
If fso.FileExists(currentPath & “\” & currentName) And _
(currentPath & “\” & currentName <> fullNewPath) Then
‘ 念のためファイルがロックされていないか確認して削除
On Error Resume Next
fso.DeleteFile currentPath & “\” & currentName, True
On Error GoTo ErrorHandler
End If
End If
CleanUp:
isProcessing = False
Exit Sub
ErrorHandler:
MsgBox “命名規則チェッカーで致命的なエラーが発生しました: ” & Err.Description, vbCritical
isProcessing = False
End Sub
② 標準モジュール(命名規則パース・生成ロジック)
Option Explicit
‘ 正規表現エンジンの利用 (VBScript.RegExp)
Public Function ValidateNamingConvention(ByVal fileName As String) As Boolean
Dim regEx As Object
Set regEx = CreateObject(“VBScript.RegExp”)
‘ 規則例: 3桁英字-4桁数字_シートID_v数字2桁.dwg
‘ 例: ABC-1234_M-01_v01.dwg
With regEx
.Pattern = “^[A-Z]{3}-\d{4}_[A-Z0-9\-]+_v\d{2}\.dwg$”
.IgnoreCase = False
.Global = False
End If
ValidateNamingConvention = regEx.Test(fileName)
End Function
Public Function GenerateStandardizedName(ByVal originalName As String) As String
Dim fso As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)
Dim baseName As String
baseName = fso.GetBaseName(originalName)
‘ 特殊文字やスペースを除去・置換するパージ処理
Dim cleanedName As String
cleanedName = Replace(baseName, ” “, “_”)
cleanedName = Replace(cleanedName, “-”, “-“)
cleanedName = Replace(cleanedName, “FINAL”, “v01”)
cleanedName = Replace(cleanedName, “rev”, “v”)
‘ 簡易的なフォールバック:最低限のプレフィックスを付与
If Not cleanedName Like “???[!-#]
_” Then
cleanedName = “PRJ-0000_” & cleanedName
End If
‘ バージョンサフィックスの強制付与(存在しない場合)
If InStr(1, cleanedName, “_v”) = 0 Then
cleanedName = cleanedName & “_v01”
End If
GenerateStandardizedName = cleanedName & “.dwg”
End Function
—
3. チーフアーキテクトが教える:実運用における極限の知見
このシステムを全社展開し、数千台のクライアントPCで運用する上で、以下の「現場の罠」に直面することが多々ある。ここをどうクリアするかでエンジニアの真価が問われる。
A. ネットワークドライブ(NFS / SMB)におけるレイテンシ問題
社内ファイルサーバー(NAS)上で直接 `SaveAs` と古いファイルの削除を行うと、Windowsのファイルハンドル解放遅延により、削除処理(`fso.DeleteFile`)が競合エラーを引き起こす。
これを回避するためには、リネーム時はローカルのテンポラリ領域(`Environ(“TEMP”)`)に一度書き出してからシェルAPIでアトミックに移動させるか、排他制御のウェイト(`DoEvents` とタイマー)を挟む設計が不可欠である。
B. レガシー環境(AutoCAD 2010〜2020代前半)におけるメモリリーク対策
VBAの `CreateObject(“Scripting.FileSystemObject”)` や `VBScript.RegExp` は、インスタンスの破棄を怠るとVBAランタイムのメモリ空間にガベージが蓄積する。特に長時間の常時起動を行う設計室の端末では、オブジェクト変数は必ずループやプロシージャの抜け際で `Set xxx = Nothing` によって明示的に解放しなければならない。
C. 運用統制:バイパス(緊急避難)ルートの確保
システム障害時や、クライアントからの特例指示で「どうしても命名規則外の名称で保存したい」という現場の要求は必ず発生する。
これを完全にシャットアウトすると実務が回らなくなるため、環境変数やWindowsレジストリ、あるいは特定のINIファイルを監視し、管理者モード(シークレットキー入力時のみ)でバリデーションをバイパスするバックドアを設計に組み込んでおくことが、システムアーキテクトとしてのシゴトの流儀である。
—
総括
ファイル名の標準化は、単なる「お片付け」ではない。それは自動化、データ連携、そしてAI活用時代におけるCADデータの「一次インフラ整備」である。
今回提示したコードとアーキテクチャをベースに、自社の要件に合わせた正規表現とエラーハンドリングをビルドし、強固な図面管理基盤を構築してほしい。
