【入門編】【実務中級者向け】「名前を付けて保存」失敗時のリトライアル:ネットワーク遅延によるファイルロックを待機するループ処理 – AutoCAD VBA解析バイブル

スポンサーリンク
スポンサーリンク

AutoCAD VBAの極意:ネットワークの壁を越える「堅牢な保存」の実装術

「ローカル環境では完璧に動いたのに、共有サーバーに保存しようとした瞬間にマクロが止まってしまう……」

もしあなたが今、そんな壁にぶつかっているとしたら、おめでとうございます。あなたはプログラミングの「理想」から、実務という「現実」へと足を踏み入れた証拠です。

こんにちは。今日は、AutoCAD VBAの世界で中級者へとステップアップするために避けては通れない、「ファイルアクセスにおける不確実性」への対処法についてお話ししましょう。

マクロの記録から脱却し、現場で「本当に使える」ツールを作るための、魂のコードを伝授します。

1. なぜ「単純な保存」は失敗するのか?

AutoCADのVBAで、図面を保存するコードは非常にシンプルです。

ThisDrawing.SaveAs "Z:\Project\Drawing1.dwg"

しかし、実務環境(特にNASや共有サーバーを使用している現場)では、この一行が「エラー」を吐いて止まることが多々あります。なぜでしょうか?

犯人は「ファイルロック」と「ネットワークの揺らぎ」

原因はあなたのコードの書き間違いではありません。以下の外部要因による「一時的な拒絶」です。

1. ネットワークの遅延(Latency): サーバーへの書き込みリクエストが、一瞬だけネットワークの混雑でタイムアウトした。
2. アンチウイルスソフトの干渉: 保存された瞬間に、セキュリティソフトが「新しいファイルができたぞ!」と検知してスキャンを開始し、ファイルにロックをかけた。
3. 他のユーザーやプロセス: 誰かがそのファイルをプレビューしていたり、バックアップソフトが掴んでいたりした。

これらは「プログラムのバグ」ではなく、「OSやインフラの振る舞い」です。プロのエンジニアは、こうした「避けられないエラー」を前提に、「エラーが起きても、粘り強くやり直す仕組み」を組み込みます。

2. 戦略:リトライアル(再試行)ループの設計

エラーが起きたら即座に終了するのではなく、「数秒待ってから、もう一度試す」。これを数回繰り返すのが、堅牢なプログラムの鉄則です。

設計図はこうなります。

1. 保存を試みる
2. 成功したら、即座にループを抜ける
3. 失敗したら、エラー内容を確認する
4. 「一時的なエラー」なら、数秒待機(Sleep)してリトライ
5. 規定回数(例:5回)試してもダメなら、諦めてユーザーに通知する

ここで重要なのが、「待ち時間」です。一瞬でリトライしても、サーバーの状態が変わっていなければまた失敗します。2〜3秒の「間」を置くことが、成功への鍵となります。

3. 実装:プロフェッショナルな「堅牢保存」コード

それでは、実際に現場でそのまま使えるレベルのコードを見ていきましょう。
ここでは、Windowsの機能を呼び出す「API宣言」を使い、精密な待機処理を実現します。

Option Explicit

' Windowsの「Sleep」機能を使うための宣言(ミリ秒単位で待機させるため)
' 64bit版AutoCADを使用している場合は PtrSafe を追加します

If VBA7 Then

Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)

Else

Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

End If

''' <summary> ''' ネットワーク遅延を考慮した、堅牢な「名前を付けて保存」関数 ''' </summary> ''' <param name="fullPath">保存先のフルパス</param> ''' <returns>成功したらTrue、失敗したらFalse</returns> Function RobustSaveAs(fullPath As String) As Boolean Dim retryCount As Integer Dim maxRetries As Integer Dim waitTimeSeconds As Integer Dim isSuccess As Boolean ' --- 設定値 --- maxRetries = 5 ' 最大5回まで挑戦する waitTimeSeconds = 3 ' 失敗時に3秒待機する isSuccess = False ' -------------- For retryCount = 1 To maxRetries ' エラーハンドリングの開始 On Error Resume Next ' 保存実行 ThisDrawing.SaveAs fullPath ' エラーが発生したかチェック If Err.Number = 0 Then ' 成功! isSuccess = True On Error GoTo 0 ' エラーハンドリングを通常に戻す Exit For Else ' 失敗した場合の処理 Debug.Print "Attempt " & retryCount & " failed. Error: " & Err.Description ' エラー内容をクリアして、次の試行へ Err.Clear On Error GoTo 0 ' まだリトライ回数が残っているなら待機 If retryCount < maxRetries Then ' ここが重要!ユーザーに「今、頑張ってリトライ中だよ」と伝えるためのDoEvents DoEvents ' 指定した秒数だけ待機 (Sleepはミリ秒指定なので 1000倍する) Sleep (waitTimeSeconds * 1000) End If End If Next retryCount ' 結果を返す RobustSaveAs = isSuccess End Function ''' <summary> ''' メイン処理:この関数を呼び出して使用します ''' </summary> Sub MainSaveProcess() Dim targetPath As String targetPath = "Z:\Shared_Folder\Project_A\Design_v01.dwg" ' 保存したいパス MsgBox "保存を開始します。ネットワーク状況により数十秒かかる場合があります。", vbInformation If RobustSaveAs(targetPath) Then MsgBox "保存に成功しました!", vbInformation Else MsgBox "【警告】保存に失敗しました。" & vbCrLf & _ "ネットワークを確認するか、ローカルに保存してください。", vbCritical End If End Sub

4. 伝説のアーキテクトが教える「ここが落とし穴!」

このコードを理解する上で、絶対に外してはいけない「3つの極意」を伝授します。ここをクリアすれば、あなたはもう初級者ではありません。

① `DoEvents` の魔法

コードの中に `DoEvents` という記述を入れましたね。これは非常に重要です。
VBAがループ処理(待ち時間)をしている間、AutoCAD自体が「応答なし」の状態になり、Windowsから「このプログラムはフリーズしています」と判断されてしまうことがあります。`DoEvents` を挟むことで、「OSに制御を一時的に戻す」ことができ、AutoCADの画面が固まるのを防ぎます。

② `On Error Resume Next` の使い所

「エラーを無視する」というこの命令は、使い方を間違えると悪魔の道具になります。
今回のコードのように、「特定の処理(SaveAs)の直前で使い、直後にエラーチェックを行う」という限定的な使い方こそが、プロの作法です。エラーを無視し続けるのではなく、「エラーが起きたことを検知するために、一時的に無視する」という感覚を持ってください。

③ `Sleep` による「戦略的撤退」

エラーが起きた瞬間に、猛スピードで再試行しても意味がありません。ネットワークの瞬断や、セキュリティソフトのスキャンが終わるには「時間」が必要です。あえて「何もしない時間を作る」こと。これが、自動化エンジニアに求められる「余裕」です。

最後に

いかがでしたか?
「エラーが起きるのは当たり前。だから、エラーが起きても大丈夫なように準備しておく」
この考え方こそが、プロフェッショナルな業務自動化の第一歩です。

今回紹介した `RobustSaveAs` 関数は、一度作ってしまえば、あなたのあらゆるプロジェクトで使い回せる「最強の武器」になります。ぜひ、自分のコードに組み込んで、その堅牢さを体感してみてください。

一歩ずつ、確実に。
AutoCAD VBAの深淵へ、共に進んでいきましょう。

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