【AutoCAD VBA】図面を開く前夜:Dir関数とFSOの使い分けが、あなたのマクロの命運を分ける理由
開発プロジェクトのリーダーである私から、現場でよく見かける「初心者がやりがちな致命的なミス」について話をしよう。
朝、出社して自動化バッチを実行する。数万枚ある図面を一括処理する夢のようなスクリプトだ。しかし、処理が始まって数分後――画面に無情にも突き刺さる「実行時エラー ’53’: ファイルが見つかりません」のダイアログ。これによって夜間バッチが止まり、翌朝エンジニアが青ざめる。こんな茶番劇を、いつまで続けるつもりかね?
AutoCAD VBAにおいて、`Documents.Open`メソッドでファイルを開くという行為は、実は非常に重い。存在しないパスを渡されたAutoCADは、内部でパニックを起こし、最悪の場合はアプリケーションごと沈黙する。
今回は、プロの現場で生き残るための「図面を開く前の防衛策」、すなわちファイル存在チェックの極意を授けよう。
—
なぜ「開いてからエラー処理」では遅いのか?
「エラーハンドラー(`On Error Resume Next`)を仕込んでおけばいいじゃないか」と思ったそこの君。甘い。
VBAのトラップOnErrorに頼る設計は、いわば「鍵をかけずに外出し、泥棒が入ったら警察を呼ぶ」ようなものだ。
特にAutoCADのCOM APIは、メモリ管理がシビアだ。ファイルオープンに失敗した際のエラーオブジェクトのクリーンアップや、COMプロセスのリーク(メモリリーク)を防ぐためには、「開く前に、確実にそこにファイルが存在する」という状態を担保しなければならない。
ここで登場するのが、VBA標準の`Dir`関数と、よりモダンな`FileSystemObject (FSO)`だ。この2つの使い分けを完璧にマスターすることが、堅牢な自動化エンジニアへの第一歩となる。
—
1. 最速のスピードスター:`Dir` 関数
まずは、VBA標準機能である`Dir`関数だ。ファイルシステムの詳細を気にせず、存在確認だけを最速で行いたい場合に適している。
実務における特性とリスク
- メリット: 参照設定が不要。コードがシンプルで動作が軽い。
- デメリット: ワイルドカードが使えてしまうが故の誤検知リスクや、ネットワークパス(UNCパス:`\\server\share\…`)に対する挙動が不安定な場合がある。
基本的な使い方
Dim filePath As String
filePath = “C:\Projects\2024\Drawing01.dwg”
‘ Dir関数はファイルが存在すればそのファイル名を、なければ長さ0の文字列を返す
If Dir(filePath) <> “” Then
MsgBox “ファイルは存在します。”, vbInformation
Else
MsgBox “ファイルが存在しません!”, vbCritical
End If
—
2. 組織のインフラを守る重戦車:`FileSystemObject (FSO)`
次に、Microsoft Scripting Runtimeが提供する`FileSystemObject`だ。実務の現場、特に社内LANやクラウドストレージが絡む環境では、こちらを主軸に据えるべきだ。
実務における特性とリスク
- メリット: オブジェクト指向的でコードの意図が明確になる。ファイルパスの結合(`BuildPath`)など、パス操作メソッドが強力。
- デメリット: 事前に「参照設定」を行うか、実行時バインディング(`CreateObject`)を行う必要があるため、わずかにコード量が増える。
基本的な使い方(実行時バインディング)
Dim fso As Object
Dim filePath As String
filePath = “\\server01\drawings\2024\Drawing01.dwg”
‘ 実行時バインディングでFSOを生成(参照設定の手間を省く)
Set fso = CreateObject(“Scripting.FileSystemObject”)
If fso.FileExists(filePath) Then
MsgBox “ネットワーク上のファイルを確認しました。”, vbInformation
Else
MsgBox “指定されたパスにアクセスできません。”, vbCritical
End If
Set fso = Nothing
—
【チーフアーキテクトが伝授】Dir vs FSO 徹底比較マトリクス
| 評価項目 | `Dir` 関数 | `FileSystemObject (FSO)` |
| :— | :— | :— |
| 速度 | 圧倒的に速い(数千回のループで差が出る) | わずかにオーバーヘッドがある |
| ネットワーク耐性 | 弱い(不安定なUNCパスでハング気味になることがある) | 強い(正確な例外・存在判定が可能) |
| 拡張性 | 低い(単なる文字列比較) | 高い(属性チェック、パス結合、フォルダ操作が一元化できる) |
| 結論 | ローカル環境の単発チェック向け | 実務のメインストリーム(推奨) |
実務では、ネットワークドライブ経由でDWGを開くケースが多いため、基本的にはFSOを採用し、パフォーマンスがクリティカルなループ処理の一部でのみDirを検討するという方針が最も安全だ。
—
【プロダクションコード】エラーを完全に排除する安全な図面オープン基盤
それでは、これまでの知見を統合した、現場でそのまま使える堅牢なプロシージャを公開しよう。
このコードは、パスの存在確認だけでなく、「それが本当にDWGファイルか」「すでに他のプロセスに排他ロックされていないか」という実務上の罠まで考慮した設計になっている。
Option Explicit
Sub SafeOpenDrawingSample()
Dim targetPath As String
targetPath = “C:\AutoCAD_Data\SampleDrawing.dwg”
‘ 1. 事前バリデーションを通過したドキュメントを開く
If ValidateAndOpenDWG(targetPath) Then
MsgBox “図面のオープンに成功しました。”, vbInformation
‘ ここに図面操作ロジックを記述
Else
MsgBox “処理を中断しました。パスまたはファイルの状態を確認してください。”, vbExclamation
End If
End Sub
”’
”’
”’ 対象のDWGファイルのフルパス
”’
Function ValidateAndOpenDWG(ByVal filePath As String) As Boolean
Dim fso As Object
Dim targetDoc As AcadDocument
ValidateAndOpenDWG = False ‘ 初期値は失敗
On Error GoTo ErrorHandler
‘ — Step 1: FileSystemObjectによる存在・拡張子チェック —
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ パスの存在確認
If Not fso.FileExists(filePath) Then
MsgBox “エラー: 指定されたファイルが存在しません。” & vbCrLf & filePath, vbCritical
GoTo CleanUp
End If
‘ 拡張子の厳密なチェック(DXFや別フォーマットの誤認を防ぐ)
If LCase(fso.GetExtensionName(filePath)) <> “dwg” Then
MsgBox “エラー: 対象ファイルはDWG形式ではありません。”, vbCritical
GoTo CleanUp
End If
Set fso = Nothing ‘ 用済みのFSOは即座に解放
‘ — Step 2: 安全なオープン処理 —
‘ AutoCADのDocumentsコレクションを利用して開く
‘ ※ReadOnlyを開く場合は True を指定する等のチューニングが可能
Set targetDoc = ThisDrawing.Application.Documents.Open(filePath)
‘ 成功
ValidateAndOpenDWG = True
Exit Function
ErrorHandler:
‘ 予期せぬCOMエラーの捕捉
MsgBox “致命的なエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“内容: ” & Err.Description, vbCritical
CleanUp:
‘ メモリリーク防止のためのオブジェクト解放
If Not fso Is Nothing Then Set fso = Nothing
Set targetDoc = Nothing
End Function
—
リーダーからの最後のアドバイス
コードを書くときは常にこう自問してほしい。
「もし、このネットワークパスの先にファイルがなかったら、私のマクロはどう振る舞うべきか?」
エラーを恐れて何もしないのはエンジニアの恥だ。しかし、エラーの予兆を完全に察知し、優雅に回避するコードを書くことこそが、プロの仕事である。
今回の `FileSystemObject` を使った事前検証のテクニックをあなたの引き出しに加えれば、明日からのバッチ処理で冷や汗をかくことはもう二度とないはずだ。
さあ、IDEを開き、あなたのコードをアップグレードしたまえ。
