AutoCAD自動化の壁を突破せよ:「ファイル使用中」を制するプロフェッショナルな待機戦略
AutoCAD VBAで大量の図面をバッチ処理する際、多くのエンジニアが最初に直面する「絶望的な壁」。それが「ファイルが他ユーザーによって使用されています(読み取り専用で開きますか?)」というダイアログです。
マクロが途中で停止し、無人のPCで作業が終わっていない。あるいは、無理やり開いてしまい図面を破壊するリスク。これを解決できないうちは、まだ「自動化の初心者」です。今日は、Windows APIの力を借りて、この「ロック状態」をエレガントに解決する、実戦的な手法を伝授しましょう。
—
なぜ「VBA標準機能」では不十分なのか?
AutoCADの`Documents.Open`メソッドをただ実行するだけでは、ファイルがロックされているかどうかを事前に知ることはできません。エラーハンドリングで拾うことも可能ですが、それだと「ファイルが開くまで待機する」という柔軟な制御ができません。
プロのエンジニアは、「ファイルに排他アクセス権を要求する」というOSレベルのAPIを叩くことで、ファイルの状態を「開く前」に判定します。
—
実装の肝:Windows API `CreateFile` による状態確認
Windowsでは、ファイルを開こうとする際に`CreateFile`というAPIを呼び出します。このとき、「共有モード」を適切に設定することで、ファイルが他者に握られているかを即座に判定できます。
以下のコードをVBAの標準モジュールに貼り付けてください。
Option Explicit
‘ Windows APIの宣言:ファイルへのアクセス権を試行する
Private Declare PtrSafe Function CreateFile Lib “kernel32” Alias “CreateFileA” ( _
ByVal lpFileName As String, ByVal dwDesiredAccess As Long, _
ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, _
ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, _
ByVal hTemplateFile As Long) As Long
Private Declare PtrSafe Function CloseHandle Lib “kernel32” (ByVal hObject As Long) As Long
‘ 定数定義
Private Const GENERIC_READ = &H80000000
Private Const FILE_SHARE_READ = &H1
Private Const OPEN_EXISTING = 3
Private Const INVALID_HANDLE_VALUE = -1
‘ 【核心関数】ファイルがロックされているか判定する
Public Function IsFileLocked(ByVal filePath As String) As Boolean
Dim hFile As Long
‘ 読み取り権限で開くことを試行(他者の書き込みを許可した状態で開けるか確認)
hFile = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0)
If hFile = INVALID_HANDLE_VALUE Then
IsFileLocked = True ‘ ロック中
Else
IsFileLocked = False ‘ オープン可能
CloseHandle hFile
End If
End Function
—
待機キューを実装する:堅牢なリトライ処理
単に判定するだけでは足りません。ファイルが空くまで「待つ」というロジックが必要です。ここで重要なのは、CPUをフル回転させないための「小休止(Sleep)」を入れることです。
‘ 待機用のAPI
Private Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
Public Sub OpenDrawingWithRetry(ByVal filePath As String)
Dim maxRetries As Integer: maxRetries = 10
Dim waitTime As Long: waitTime = 2000 ‘ 2秒待機
Dim i As Integer
For i = 1 To maxRetries
If Not IsFileLocked(filePath) Then
‘ ロック解除を確認!ここで安全に開く
ThisDrawing.Application.Documents.Open filePath
Exit Sub
End If
Debug.Print “ファイルが使用中です。再試行回数: ” & i
Sleep waitTime
Next i
MsgBox “最大リトライ回数を超えました。手動で確認してください。”, vbCritical
End Sub
—
プロフェッショナルへの道:陥りやすい罠
1. パスの形式: `CreateFile`に渡すパスはUNC形式(`\\Server\Folder\…`)にも対応していますが、文字コードや空白には細心の注意を払ってください。
2. AutoCAD特有のロックファイル: AutoCADはファイルを開くと`.dwl`や`.dwl2`という隠しファイルを生成します。しかし、ネットワーク環境ではこれらが残存することが多々あります。APIによる判定が「最終防衛線」である理由がここにあります。
3. イベントの連鎖: 大規模なバッチ処理を行う場合、`VBA`だけでなく`ObjectARX`や`.NET API`への移行も視野に入れましょう。VBAは強力ですが、メモリ管理の面で長時間稼働には不向きな側面があります。
まとめ:自動化の極意
コードをただ動かすだけでなく、「外部環境(OSやネットワーク)が意地悪をしてくること」を前提にプログラムを組むこと。これが、プロのエンジニアとアマチュアを分かつ最大の境界線です。
今回紹介したAPIを用いた待機戦略は、あなたのAutoCAD自動化業務を「時々止まる不安定なマクロ」から「深夜も黙々と働く堅牢なロボット」へと変貌させてくれるはずです。
「なぜ動かないのか」と悩む時間は今日で終わりにしましょう。次は、図面情報の抽出からPDFパブリッシュまで、さらに高度な自動化の世界でお会いしましょう!
