絶望を希望に変える:AutoCAD VBAにおける「読み取り専用」図面救済の極意
こんにちは。今日も図面作成、お疲れ様です。
AutoCADで作業をしていると、たまに「あ……」と声が出てしまう瞬間がありますよね。
「読み取り専用」として開いてしまった図面に対して、気づかないうちに30分、1時間と猛烈な勢いで修正を加えてしまった時。そして、いざ「保存」を押した瞬間に、無慈悲なエラーメッセージが画面を覆う……。
「今までの作業は全部消えてしまうのか?」
その恐怖、私も何度も味わってきました。マクロの記録(Record Macro)だけで戦っている段階では、こうした「想定外の事態」への対処法は教えてくれません。しかし、一歩先のエンジニアリングを目指すなら、「プログラムは失敗するものだ」という前提に立ち、失敗した時にどうユーザーを救うかを設計に組み込む必要があります。
今日は、そんな「作業の消失」という最悪のシナリオを防ぐための、エラーハンドリングによる自動退避機能をマスターしましょう。
1. なぜ「保存エラー」は起きるのか?(設計の視点)
まず、敵を知ることから始めましょう。AutoCAD VBAで保存に失敗する主な理由は以下の通りです。
- ファイル属性の問題: ファイル自体に「読み取り専用」属性がついている。
- 権限の問題: サーバー上のフォルダへの書き込み権限がない。
- 競合の問題: 他のユーザーが同じファイルを開いてロックしている。
通常のプログラムは、エラーが起きるとそこで「停止」します。しかし、業務自動化のプロが書くコードは違います。「保存できないなら、別の場所(デスクトップ等)に名前を変えて逃がしてあげよう」という、逃げ道(フォールバック)を用意しておくのです。
2. 救済ロジックの設計図
今回実装する機能のフローを、図解的に整理してみましょう。
[ 開始 ]
[ 通常の保存を試みる (ActiveDocument.Save) ]
|-- (成功) --> [ 終了 ]
|-- (失敗) --> [ エラーハンドリングへジャンプ ]
[ 救済モード発動! ]
1. デスクトップのパスを取得
2. ファイル名に「_RESCUED_時刻」を付与
3. 別の名前で SaveAs (別名保存) を実行
4. ユーザーに「救済完了」を通知
[ 終了 ]
この「失敗を検知して、別のルートへ誘導する」仕組みこそが、実務レベルのプログラミングの肝です。
3. 実装コード:図面救済マクロ
それでは、実際に使えるコードを見ていきましょう。初心者の方でも読みやすいよう、細かくコメントを入れています。
Option Explicit
''' <summary>
''' 図面を安全に保存する。失敗した場合はデスクトップに自動退避する。
''' </summary>
Sub SafeSaveRoutine()
Dim doc As AcadDocument
Set doc = ThisDrawing ' 現在アクティブな図面を対象にする
Dim originalPath As String
originalPath = doc.FullName ' 現在のファイルのフルパスを取得
' --- エラーハンドリングの開始 ---
' もしエラーが発生したら、"ErrorHandler:" というラベルまで飛んでね、という指示
On Error GoTo ErrorHandler
' 1. まずは通常の保存を試みる
Debug.Print "通常の保存を試行中..."
doc.Save
MsgBox "保存が正常に完了しました。", vbInformation, "Success"
Exit Sub ' 正常に終わったら、ここでマクロを終了する(重要!)
ErrorHandler:
' --- ここから救済プロセス ---
' エラーが発生した場合、ここから下の処理が実行される
Dim desktopPath As String
Dim newFileName As String
Dim timestamp As String
' エラー内容をデバッグ出力(開発者向け)
Debug.Print "Error Number: " & Err.Number
Debug.Print "Error Description: " & Err.Description
' 2. 救済用のファイル名を生成 (例: 図面名_RESCUED_20231027_1530.dwg)
timestamp = Format(Now, "yyyymmdd_hhnnss")
' 元のファイル名から拡張子を除いた部分を取得
newFileName = Left(doc.Name, InStrRev(doc.Name, ".") - 1) & "_RESCUED_" & timestamp & ".dwg"
' 3. デスクトップのパスを取得 (WScript.Shellを利用)
' これにより、ユーザー名が誰であっても自動でデスクトップを見つけられる
desktopPath = CreateObject("WScript.Shell").SpecialFolders("Desktop") & "\"
' 4. 救済保存の実行
On Error Resume Next ' SaveAs自体が失敗する場合に備えて、さらにエラーを無視する設定
doc.SaveAs desktopPath & newFileName
If Err.Number = 0 Then
' 保存に成功した場合
MsgBox "【警告】元のファイルは読み取り専用、または書き込み禁止です。" & vbCrLf & _
"作業内容は、以下の場所に安全に退避しました:" & vbCrLf & vbCrLf & _
desktopPath & newFileName, vbExclamation, "図面救済完了"
Else
' 救済保存すら失敗した場合(ディスクフルや極端な権限不足)
MsgBox "致命的なエラー: 保存も退避もできませんでした。" & vbCrLf & _
"作業内容が失われる可能性があるため、すぐに作業内容をコピーして別ソフトへ貼り付けてください!", vbCritical, "救済失敗"
End If
On Error GoTo 0 ' エラー設定をリセット
End Sub
4. ここが「プロ」のこだわり:技術解説
このコードには、単なる「動くコード」を超えた、いくつか重要なテクニックが含まれています。
① `On Error GoTo ErrorHandler` の魔法
マクロの記録で作ったコードには、この記述がありません。エラーが起きると、VBAは「実行時エラー」を表示して止まってしまいます。`On Error GoTo` を使うことで、「エラーが起きてもパニックにならず、あらかじめ用意した回避ルート(ErrorHandler)へ誘導する」という制御が可能になります。これが、プログラミングにおける「堅牢性(ロバストネス)」の第一歩です。
② `WScript.Shell` による環境への適応
`C:\Users\Tanaka\Desktop` のようにパスを直接書いてしまうのは、初学者が陥りやすい罠です。これでは他の人のPCでは動きません。`CreateObject(“WScript.Shell”).SpecialFolders(“Desktop”)` を使うことで、どんなユーザーの環境でも、魔法のように正しいデスクトップの場所を突き止めることができます。
③ タイムスタンプによる上書き防止
救済ファイル名に `Format(Now, “yyyymmdd_hhnnss”)` を加えている点に注目してください。もしユーザーが何度もエラーを繰り返した場合でも、ファイル名が毎回変わるため、「救済したファイルが、次の救済ファイルによって上書きされる」という悲劇を防ぐことができます。
5. まとめ:エラーは「設計」の一部である
「エラーが出るから、プログラムがダメなんだ」と考える必要はありません。
「エラーが出ることを前提に、どうやってユーザーを笑顔で帰すか」。それこそが、私たちが目指すべきエンジニアリングの姿です。
今回紹介した「自動退避ロジック」を、あなたの作成するツールに組み込んでみてください。それだけで、あなたのマクロは「便利な道具」から「信頼できるパートナー」へと進化します。
ここをクリアすれば、AutoCAD VBAの基本はバッチリですよ。
さあ、次の自動化へ進みましょう!
