こんにちは。AutoCADの自動化という深淵な世界へようこそ。
VBAで図面を自動保存するプログラムを書いたとき、こんなエラーに遭遇したことはありませんか?
「ファイルに書き込めません」「他のプロセスで使用中です」
特にネットワークドライブ上の図面や、数ギガバイトに及ぶ巨大な図面を扱っているときに発生しがちなこのエラー。実はこれ、AutoCADが「保存コマンド」を投げた直後に、あなたのプログラムが次の処理(ファイルを閉じる、フォルダを移動させる等)に走ってしまうことで発生する「タイミングの齟齬」が原因です。
今日は、AutoCADの気まぐれな「保存時間」を完璧に制御し、あなたのマクロを一段上の堅牢さへ引き上げる技術を伝授します。
—
なぜ「保存待ち」が必要なのか?
AutoCADの `Save` や `SaveAs` メソッドは、実は「保存を開始せよ」という命令を送るだけの非同期に近い動きをすることがあります。
PCやネットワークが高速であれば一瞬で終わりますが、図面が重かったりサーバーのレスポンスが悪かったりすると、AutoCADが裏でせっせと書き込みを行っている最中に、あなたのマクロが「保存終わったよね?じゃあファイルを閉じるよ!」と割り込んでしまう。これがエラーの正体です。
これを解決するには、「保存が完了するまで、マクロの時間を止めて見守る」という賢い待機ロジックが必要です。
—
実践:保存完了を検知する「待機ループ」
単純な `Sleep` 関数で時間を止めるのはNGです。図面の大きさに応じて必要な待機時間は変わるからです。そこで、「ファイルの更新時刻(タイムスタンプ)が更新されたか」を監視する、堅牢な手法を紹介します。
実装コード
Option Explicit
‘ Windows APIを使用してファイルシステムの情報にアクセスします
Private Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
Public Sub SafeSaveAs(targetPath As String)
Dim doc As AcadDocument
Set doc = ThisDrawing
‘ 1. 保存前のタイムスタンプを取得
Dim fso As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ 保存処理を実行
doc.SaveAs targetPath
‘ 2. 保存完了を待機するループ
Dim startTime As Double
startTime = Timer
‘ 最大10秒待機する設定
Do While Timer – startTime < 10
' ファイルが書き込みロックから解放され、タイムスタンプが更新されるのを待つ
' ※ファイルが存在し、かつアクセス可能になるまでループ
If fso.FileExists(targetPath) Then
' 保存直後のファイルを掴めるかテスト(簡易ロックチェック)
On Error Resume Next
Dim f As Object
Set f = fso.GetFile(targetPath)
' エラーが発生しなければ保存完了とみなす
If Err.Number = 0 Then
Debug.Print "保存完了を確認しました。"
Exit Sub
End If
On Error GoTo 0
End If
' CPU負荷を抑えるために少し待機
DoEvents
Sleep 200
Loop
MsgBox "保存処理がタイムアウトしました。ネットワーク環境を確認してください。", vbCritical
End Sub
---
コードのポイント:ここが「プロ」の流儀
1. `On Error Resume Next` の活用
ファイルが書き込み中の場合、`fso.GetFile` を実行すると「アクセス拒否」エラーが発生します。このエラーを逆手に取り、「エラーが出なくなるまで待つ」というロジックにしています。これが最も確実な「使用中」判定です。
2. `DoEvents` を忘れない
`Do While` ループの中で必ず `DoEvents` を呼んでください。これがないと、待機中にAutoCADの画面がフリーズしてしまい、最悪の場合「応答なし」状態に陥ります。`DoEvents` は、Windowsに「今のうちに描画や入力を処理していいよ」と許可を与える魔法の命令です。
3. タイムアウトの実装
無限ループは絶対に禁物です。`Timer` を使って「何秒経っても終わらなければ諦める」という安全装置を必ず組み込みましょう。
—
まとめ:マクロを「止まらない道具」にするために
今回紹介した「タイムスタンプ監視+エラーハンドリング」の考え方は、保存だけでなく、外部参照の読み込みや、PDF出力の完了待ちなど、あらゆる「非同期処理」に応用が可能です。
- 初級者: `SaveAs` を書くだけで満足する。
- 中級者: エラーが出てから `Sleep` で適当に時間を止める。
- 上級者: プロセスの状態を監視し、最短時間で次の処理へ移行させる。
あなたが目指すべきは、もちろん上級者です。この待機ループをあなたのツールボックスに入れておけば、ネットワーク環境の変化や図面の巨大化にも動じない、プロフェッショナルな自動化エンジニアとしての第一歩になりますよ。
それでは、また次の深淵でお会いしましょう。あなたのコードが、今日もスムーズに駆け抜けることを願っています。
