序文:なぜ、あなたのツールは「共有サーバー」で牙を剥くのか
AutoCAD VBAを少し触れるようになり、意気揚々と業務自動化ツールを社内に配布した直後、決まって報告されるトラブルがある。
「図面が開けません」「読み取り専用で開かれて、保存ができません」という悲鳴だ。
開発環境(ローカルPC)では完璧に動いていたコードが、実務の共有サーバー上で無力化する最大の原因。それは、「他者が図面を編集している可能性」を完全に無視しているからだ。
初心者は `Documents.Open` を単に実行し、エラーが出たら `On Error Resume Next` で握りつぶす。これは最悪の悪手だ。プロフェッショナルは、APIを叩く前に「戦場の霧」を晴らす。つまり、ロックファイル(.dwl / .dwl2)の存在を確認し、排他制御を自前でハンドリングする。
今回は、AutoCAD VBAを「プロダクションレベル」に引き上げるための、堅牢なファイルオープン処理の極意を伝授する。
—
1. AutoCADの「排他制御」の裏側を知る
AutoCADで図面(example.dwg)を開くと、同じディレクトリに隠しファイルとして以下の2つが生成される。
1. example.dwl
2. example.dwl2
これらはAutoCADが「誰が、いつ、どのマシンからこの図面を開いているか」を記録するためのロックファイルだ。図面を正常に閉じれば消滅するが、誰かが開いている間は居座り続ける。
`AcadDocument.Open` メソッドは、これらのファイルの存在を無視して強引にファイルを開こうとする。その結果、図面は「読み取り専用」で開かれ、ツールが実行するはずだった「編集・保存」という目的は音を立てて崩壊する。
「開けるかどうかを試す」のではなく、「開ける状態にあるかを確認してから動く」。 これが、手戻りのない自動化設計の鉄則だ。
—
2. 堅牢な設計:ロックファイル確認の実装
ここでは、`Microsoft Scripting Runtime (FSO)` を利用した、実戦的なチェック関数を組み込む。
実装のポイント
- FSOの活用: ファイルシステムの操作はVBA標準の `Dir` 関数よりも、オブジェクト指向で例外に強い FileSystemObject を推奨する。
- DWLとDWL2の両面待ち: 念のため両方の拡張子をチェックする。
- ユーザーへのフィードバック: 単に「開けません」ではなく、他者が開いていることを明示する。
プロダクションコード例
‘ Microsoft Scripting Runtime (scrrun.dll) への参照設定を推奨
‘ [ツール] -> [参照設定] からチェックを入れてください
Option Explicit
”’
”’
Public Sub SafeOpenExecution()
Dim dwgPath As String
dwgPath = “Z:\Projects\Drawing_001.dwg” ‘ 共有サーバー上のパスを想定
‘ 1. 開く前にロック状態をセルフチェック
If IsDwgLocked(dwgPath) Then
MsgBox “対象の図面は他ユーザーが編集中のため、処理を中断します。” & vbCrLf & _
“ファイルパス: ” & dwgPath, vbCritical, “排他制御アラート”
Exit Sub
End If
‘ 2. ロックがなければAcadDocument.Openを試みる
Dim doc As AcadDocument
On Error Resume Next
Set doc = ThisDrawing.Application.Documents.Open(dwgPath)
If Err.Number <> 0 Then
MsgBox “図面を開く際に予期せぬエラーが発生しました。” & vbCrLf & _
“Error: ” & Err.Description, vbExclamation
On Error GoTo 0
Exit Sub
End If
On Error GoTo 0
‘ — ここに編集ロジックを記述 —
Debug.Print “図面を正常に排他確保しました: ” & doc.Name
‘ 最後に保存して閉じるのを忘れずに
‘ doc.Close True
End Sub
”’
”’
”’ チェック対象のDWGフルパス
”’
Private Function IsDwgLocked(ByVal dwgPath As String) As Boolean
Dim fso As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ DWGファイルの存在確認(そもそもファイルがない場合への対処)
If Not fso.FileExists(dwgPath) Then
‘ ファイルがない場合はロック以前の問題だが、
‘ 呼び出し側で処理させるためここではFalseを返すか、エラーを投げる
IsDwgLocked = False
Exit Function
End If
Dim dwlPath As String
Dim dwl2Path As String
‘ ロックファイルのパスを生成
‘ .dwg を .dwl / .dwl2 に置換
dwlPath = Left(dwgPath, InStrRev(dwgPath, “.”)) & “dwl”
dwl2Path = Left(dwgPath, InStrRev(dwgPath, “.”)) & “dwl2”
‘ いずれかのロックファイルが存在すれば、他者が開いていると判断
If fso.FileExists(dwlPath) Or fso.FileExists(dwl2Path) Then
IsDwgLocked = True
Else
IsDwgLocked = False
End If
Set fso = Nothing
End Function
—
3. チーフアーキテクトの視点:なぜこの設計なのか
① 読み取り専用で開くリスクの回避
AutoCAD VBAの `Documents.Open` は、ロックファイルがあってもエラーを吐かずに「読み取り専用」で開いてしまうケースがある。この場合、コードの最後で `doc.Save` を実行した瞬間に「読み取り専用ファイルは保存できません」という実行時エラーでツールがクラッシュする。
数千行のデータを処理した後にこのエラーが出るのは、ユーザーにとって悲劇でしかない。「保存できないなら、最初から開かせない」。これが業務自動化の優しさであり、堅牢性だ。
② なぜ `On Error Resume Next` だけでは不十分か
ネットワークの瞬断や、AutoCADの強制終了によって「実体はないのにロックファイルだけが残る(ゴーストロック)」という現象が稀に起きる。
私の設計では、まずロックファイルをチェックし、それでも万が一 `Open` で失敗した場合のために `On Error` を二段構えにしている。
「FSOによる事前チェック」は論理的なガードであり、「On Errorによるトラップ」は物理的なガードだ。この二重構造が、現場で「止まらないツール」を作る。
③ データベース連携への応用
もしあなたが図面管理台帳(ExcelやAccess, SQL Server)と連携しているなら、この `IsDwgLocked` 関数はさらに威力を発揮する。
バッチ処理で100枚の図面を更新する場合、ロックされている図面だけをスキップし、最後に「スキップしたリスト」を表示するような親切な設計が可能になる。
—
結言:細部にこそ「プロの魂」が宿る
`Documents.Open` という一行のコードの裏側には、共有サーバーというカオスな戦場が広がっている。
そこを想像し、先回りしてリスクを潰すコードを書けるかどうかが、単なる「スクリプト書き」と「自動化エンジニア」の境界線だ。
ロックファイルの確認は、地味で退屈な処理に見えるかもしれない。しかし、この一見無駄に見える「確認の儀式」こそが、あなたの作成したツールの信頼性を支え、ユーザーからの信頼を勝ち取るための最短ルートなのだ。
このコードをあなたのライブラリに加え、今日から「絶対に落ちない自動化」の第一歩を踏み出してほしい。
