こんにちは!AutoCAD VBAの世界へようこそ。
図面を自動処理するマクロを組んでいて、誰もが一度はヒヤリとする瞬間……それは「既存の重要図面を誤って上書き保存してしまった」という事故ではないでしょうか?
「マクロの記録から脱却して、もっと実用的なプログラムを書きたい!」と考え始めたみなさんにとって、「ファイルの重複を自動で検知し、安全に枝番(_rev1, _rev2…)を振って保存するロジック」の習得は、まさに脱初心者への登竜門です。
ここをクリアすれば、AutoCAD VBAの基本はバッチリですよ!
今回は、現場でそのまま使える「安全なファイル命名・世代管理アルゴリズム」を、基礎から本質まで分かりやすく解説します。
—
1. なぜ「上書き防止ロジック」が必要なのか?
AutoCADの標準機能や単純なVBAコードで `ThisDrawing.SaveAs` を実行すると、同名ファイルが存在する場合に警告ダイアログが出たり、最悪の場合は静かに既存ファイルが上書きされてしまいます。
特に夜間バッチ処理などで大量の図面を自動処理する場合、途中でダイアログが出て止まってしまっては自動化の意味がありませんよね。
世代管理(リビジョン付与)の思考フロー
私たちが目指すロジックは、以下のような人間の判断をプログラムに肩代わりさせることです。
[保存処理のスタート]
│
▼
元のファイル名(例: FloorPlan.dwg)が存在するか?
├─ [NO] ─> 「FloorPlan.dwg」として保存!(終了)
│
└─ [YES]
│
▼
「_rev1」を付与して「FloorPlan_rev1.dwg」が存在するか?
├─ [NO] ─> 「FloorPlan_rev1.dwg」として保存!(終了)
│
└─ [YES]
│
▼
「_rev2」を付与して「FloorPlan_rev2.dwg」が存在するか?
├─ [NO] ─> 「FloorPlan_rev2.dwg」として保存!(終了)
│
└─ [YES] ─> (空いている数字が見つかるまでループ)
この「存在チェック ➔ なければ保存 ➔ あれば番号を増やして再チェック」というシンプルなループ(再帰的思考)をコードに落とし込みます。
—
2. 組み上げに必要な2つの重要パーツ
このアルゴリズムを構築するためには、AutoCAD VBAにおける2つの重要テクニックを使います。
1. `Scripting.FileSystemObject` (FSO):ファイルやフォルダの存在チェック、パスの分解を安全に行うWindowsの万能ツール。
2. `ThisDrawing.SaveAs`:AutoCADの図面を新しい名前で保存するAPIメソッド。
これらを組み合わせた、実用度100%の完成コードを見てみましょう。
—
3. 【コピペOK】完全自動・重複回避保存のVBAコード
以下のコードを、AutoCAD VBAエディタ(`VBAIDE`コマンドで起動)の標準モジュールに貼り付けて実行してみてください。
Option Explicit
‘===============================================================================
‘ メイン処理:現在開いている図面を安全にリビジョン付きで保存する
‘===============================================================================
Public Sub SaveDrawingWithRevision()
Dim currentPath As String
Dim folderPath As String
Dim fileName As String
Dim baseName As String
Dim ext As String
Dim newFilePath As String
‘ 1. 現在の図面が一度も保存されていない(新規図面)場合のガード
If ThisDrawing.Path = “” Then
MsgBox “この図面はまだ一度も保存されていません。” & vbCrLf & _
“一度手動で保存してから実行してください。”, vbExclamation, “処理中断”
Exit Sub
End If
‘ 2. パス情報の取得
currentPath = ThisDrawing.FullName
‘ 3. ファイルパスの分解(フォルダ、拡張子なしファイル名、拡張子)
Call SplitFilePath(currentPath, folderPath, baseName, ext)
‘ 4. 重複しない安全なファイルパスを算出(コアアルゴリズム)
newFilePath = GenerateUniqueFilePath(folderPath, baseName, ext, “_rev”)
‘ 5. 安全なファイル名でAutoCAD図面を保存
On Error GoTo ErrorHandler
‘ SaveAsを実行(※現在の作業図面も新しいファイル側に切り替わります)
ThisDrawing.SaveAs newFilePath
MsgBox “安全に保存が完了しました!” & vbCrLf & _
“保存先: ” & newFilePath, vbInformation, “保存完了”
Exit Sub
ErrorHandler:
MsgBox “保存処理中にエラーが発生しました。” & vbCrLf & _
Err.Description, vbCritical, “エラー”
End Sub
‘===============================================================================
‘ コア関数:ファイルが存在しなくなるまで連番(_rev1, _rev2…)をインクリメントする
‘===============================================================================
Private Function GenerateUniqueFilePath(ByVal folderPath As String, _
ByVal baseName As String, _
ByVal ext As String, _
Optional ByVal revPrefix As String = “_rev”) As String
Dim fso As Object
Dim candidatePath As String
Dim revIndex As Long
‘ Late Binding (参照設定不要) で FileSystemObject を生成
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ フォルダパスの末尾に「\」があることを保証
If Right(folderPath, 1) <> “\” Then
folderPath = folderPath & “\”
End If
‘ 1番目の候補:まずは元のファイル名そのまま
candidatePath = folderPath & baseName & ext
‘ ファイルが存在しない場合は、そのままのパスを返して終了
If Not fso.FileExists(candidatePath) Then
GenerateUniqueFilePath = candidatePath
Set fso = Nothing
Exit Function
End If
‘ 2番目以降の候補:同名ファイルが存在する限り _rev1, _rev2… と連番を増やす
revIndex = 1
Do
candidatePath = folderPath & baseName & revPrefix & revIndex & ext
revIndex = revIndex + 1
Loop While fso.FileExists(candidatePath)
‘ 空いているパスが見つかったらそれを返す
GenerateUniqueFilePath = candidatePath
Set fso = Nothing
End Function
‘===============================================================================
‘ 補助関数:フルパスを「フォルダ」「ファイル名」「拡張子」に分離する
‘===============================================================================
Private Sub SplitFilePath(ByVal fullPath As String, _
ByRef outFolder As String, _
ByRef outBaseName As String, _
ByRef outExt As String)
Dim fso As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)
outFolder = fso.GetParentFolderName(fullPath)
outBaseName = fso.GetBaseName(fullPath)
outExt = “.” & fso.GetExtensionName(fullPath)
Set fso = Nothing
End Sub
—
4. コードの解説と陥りやすいピットフォール
プログラミング初心者を脱出するために、このコードで使われている「本質的なプロの知恵」を解説します。
Point 1: 参照設定を不要にする「Late Binding(遅延結合)」
コード内で `CreateObject(“Scripting.FileSystemObject”)` と書いている部分があります。
これは「参照設定」をユーザーの手動操作に頼らず、VBAが実行された瞬間にWindowsの機能を呼び出す手法です。これにより、「他の人のPCで動かしたら参照設定エラーが出た!」というトラブルを完全に回避できます。
Point 2: 文字列の分解は `FileSystemObject` に任せる
ファイルパスから「拡張子」や「フォルダ名」を自力で文字列検索(`InStr`や`Right`など)して取り出すのは危険です。ファイル名に「.(ドット)」が複数含まれている場合(例:`Plan_v1.2.dwg`)にバグの原因になります。
`fso.GetBaseName` や `fso.GetExtensionName` を使うのが、最も安全で確実です。
Point 3: AutoCAD特有の `SaveAs` の挙動に注意!
AutoCAD VBAの `ThisDrawing.SaveAs` メソッドを実行すると、「現在AutoCADで開いている図面そのもの」が新しいファイル名に切り替わります。
【実行前】開いている図面:Sample.dwg
↓ (SaveAs “Sample_rev1.dwg” を実行)
【実行後】開いている図面:Sample_rev1.dwg (Sample.dwg は閉じられ、こちらに化ける)
もし「元の図面を開いたまま、裏でこっそり複製(バックアップ)だけを作りたい」という場合は、`SaveAs` ではなく `fso.CopyFile` などを使うか、AutoCAD APIの `ObjectDBX` という技術を使う必要があります。(※まずは基本の `SaveAs` からマスターすればOKです!)
—
5. 【一歩先へ】DWG互換バージョンの制御
現場では、「最新のAutoCADで保存すると、協力会社の古いAutoCADで開けなくなる」というバージョン問題がよく起こりますよね。
`SaveAs` メソッドの第2引数を指定すると、保存するDWGの形式(バージョン)を固定することができます。
‘ 2018形式のDWGとして保存する場合 (ac2018_dwg = 64)
ThisDrawing.SaveAs newFilePath, ac2018_dwg
‘ 2013形式のDWGとして保存する場合 (ac2013_dwg = 48)
ThisDrawing.SaveAs newFilePath, ac2013_dwg
このように保存形式を明示しておけば、チーム全体でのバージョン互換性の問題も同時に解決できる「超・実用的なマクロ」へと進化します!
—
まとめ:仕組みを理解すればVBAは怖くない!
今回ご紹介したアルゴリズムのポイントを復習しましょう。
1. `FileSystemObject` でファイルの有無をチェック
2. `Do While fso.FileExists(…)` で空いている連番を探す
3. `ThisDrawing.SaveAs` で安全に保存
「既存のファイルを消さない」という安全設計は、業務自動化ツールを作成する上で最も重要な信頼性に直結します。この連番ロジックは、DWGファイルだけでなく、Excelレポートの出力やPDFの自動保存など、あらゆるVBA開発に応用が可能です。
ぜひご自身の環境で試してみて、社内ツール作成に役立ててくださいね。
一歩ずつコードの意味を理解していけば、AutoCAD VBAの掌握はもうすぐそこです!応援しています!
