【極限の設計】AutoCAD大量バッチ処理の「即死」を防ぐ:堅牢なエラーハンドリングの実践
AutoCADのバッチ処理において、最も避けるべきは「マクロの停止」だ。1000枚の図面を処理する際、300枚目で破損ファイルに出会い、マクロがエラーで沈黙する。翌朝出社して画面を見た時の絶望感を知る者は、二度と同じ過ちを繰り返さない。
今日は、AutoCAD VBAにおける「生存率100%」を目指すための、プロフェッショナルなバッチ処理設計を伝授する。
—
なぜ「On Error Resume Next」を乱用してはいけないのか
多くの初学者が陥る罠が、単なる `On Error Resume Next` の放置だ。これでは、何が起きたか分からず、後続の処理でさらに致命的なエラーを誘発する。
真に堅牢なコードは、「エラーを制御可能な範囲に閉じ込め、ログとして吐き出し、即座に次のタスクへ移行する」というサイクルを回す。
プロダクションコード:例外を制するバッチ処理の雛形
以下のコードは、ファイルオープン時の「図面ファイルが有効ではありません(または破損)」という例外を美しく握りつぶし、ログに記録して次へ進むための設計だ。
Option Explicit
‘ ログ書き出し用のファイル番号定数
Private Const LOG_FILE_PATH As String = “C:\Temp\BatchProcess_Log.txt”
Public Sub ProcessDrawingsBatch(ByVal folderPath As String)
Dim fso As Object
Dim folder As Object
Dim file As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set folder = fso.GetFolder(folderPath)
For Each file In folder.Files
If LCase(fso.GetExtensionName(file.Path)) = “dwg” Then
‘ 個別のファイル処理を独立した関数に切り出すことが重要
If Not ProcessSingleDrawing(file.Path) Then
‘ ここで失敗したファイルをログに残す
LogFailure file.Path, “Failed to open or process.”
End If
End If
Next file
End Sub
Private Function ProcessSingleDrawing(ByVal filePath As String) As Boolean
Dim doc As AcadDocument
‘ エラーハンドリングの開始
On Error GoTo ErrorHandler
‘ 図面を開く(ReadOnlyモードで開くのがバッチ処理の鉄則)
Set doc = Application.Documents.Open(filePath, True)
‘ — ここに業務ロジックを記述 —
‘ doc.ActiveSpace = acModelSpace
‘ ——————————
doc.Close False ‘ 保存せずに閉じる
ProcessSingleDrawing = True
Exit Function
ErrorHandler:
‘ エラー発生時は即座にドキュメントを解放し、呼び出し元へ戻る
If Not doc Is Nothing Then doc.Close False
‘ エラー内容をログに出力し、Falseを返す
Debug.Print “Error in ” & filePath & “: ” & Err.Description
ProcessSingleDrawing = False
End Function
Private Sub LogFailure(ByVal path As String, ByVal msg As String)
Dim fso As Object: Set fso = CreateObject(“Scripting.FileSystemObject”)
Dim ts As Object
Set ts = fso.OpenTextFile(LOG_FILE_PATH, 8, True) ‘ 追記モード
ts.WriteLine Now & ” | [ERROR] | ” & path & ” | ” & msg
ts.Close
End Sub
—
プロが意識すべき3つの設計ポイント
1. ファイルハンドルの「早期解放」
`Set doc = Nothing` や `doc.Close` を怠ると、メモリリークだけでなく、ロックされたファイルが解放されず、次回のバッチ処理で「アクセス拒否」エラーを引き起こす。エラーハンドラ内での `doc.Close` は必須だ。
2. ReadOnlyフラグの徹底
バッチ処理でファイルを編集する必要がない場合、必ず `Application.Documents.Open(filePath, True)` の第二引数を `True` にせよ。これにより、ファイルロックによる競合や、誤保存のリスクを物理的に排除できる。
3. 「プロセス分離」の視点
AutoCAD VBAは非常に強力だが、長時間稼働させるとメモリ使用量が増大する。図面数が多い場合、VBA単体で完結させようとせず、VB.NET(ObjectARX)から外部プロセスとしてAutoCADを制御するか、あるいは処理ごとにAutoCADを再起動させるようなバッチ設計(タスクスケジューラ連携など)を検討すべきだ。
最後に:エンジニアとしての矜持
コードを書くことは、道具を作ることに似ている。あなたが作ったツールが深夜に止まってしまうことは、その開発者としての「信頼」を損なうことと同義だ。
エラーハンドリングを「面倒な作業」と捉えるか、「システムを完成させるための不可欠な設計の一部」と捉えるか。その差が、良いエンジニアと卓越したアーキテクトを分ける境界線となる。
さあ、このコードをベースに、君自身の「止められないバッチシステム」を構築してほしい。現場からは以上だ。
