【上級】AcadDocument.Auditメソッドの実行結果をテキストログへ自動出力するデバッグ支援ツール
図面データの破損、未定義のオブジェクト参照、不正なシンボルテーブル。CADオペレーターの悪夢であるこれらを未然に防ぎ、数百枚単位の図面アーカイブの健全性を担保するために、プロは何を使うべきか?
答えは、`AcadDocument.Audit` メソッドの完全制御だ。
一般的に、UI上から「AUDIT」コマンドを実行し、「修正しますか? [はい(Y)/いいえ(N)]」のプロンプトに手動で答えているうちは、アマチュアの域を出ない。本物のエンジニアは、VBAを用いてこれを完全自動化し、検出されたエラーの全容を外部テキストログへ吐き出し、バッチ処理の基盤へと昇華させる。
今回は、AutoCAD VBAのオブジェクトモデルの深淵を知る者だけが書ける、実務で即座に使える堅牢なデバッグ支援ツールの全貌を伝授しよう。
—
1. なぜ「標準のAUDIT手動実行」では業務が破綻するのか
数百枚、数千枚のレガシー図面を抱えるプロジェクトにおいて、手動での図面監査は以下の致命的なボトルネックを生む。
1. 対話型プロンプトの罠:`Audit`メソッドは、引数に `FixErrors`(エラーを修正するかどうか)を指定しないと、バックグラウンド実行時に予期せぬストップを引き起こす。
2. エラー情報の消失:画面上のコマンドラインに流れる「検出されたエラー数」「修正された数」は、CADを閉じれば消える。どの図面が腐敗しているのかをトレーサビリティ(追跡可能性)として残せない。
3. メモリリークとCOMの呪縛:AutoCAD VBAにおけるドキュメントの開閉(`Open` と `Close`)は、不適切に行うと致命的なメモリリークやゾンビプロセスの温床となる。
これらを完全に克服する設計思想を、コードを通じて解説する。
—
2. 堅牢な設計:プロダクションコードの全体像
以下のコードは、指定したフォルダ内の全図面(DWG)をサイレント(非表示またはバックグラウンドに近い状態)で開き、`Audit`を実行し、その詳細な実行結果をタイムスタンプ付きのテキストログへ書き出すプロフェッショナル向けモジュールだ。
Option Explicit
‘ Windows Script Host Object Model を使用したファイルシステム操作
‘ ※ 事前バインディングする場合は参照設定に追加してください (Microsoft Scripting Runtime)
Private fso As Object
Private tsLog As Object
”
‘ @Title 図面一括監査&テキストログ出力ツール
‘ @Description 指定フォルダ内の全DWGに対してAuditを実行し、結果をログに集約する
Public Sub ExecuteBatchAudit()
Dim targetFolder As String
Dim logFilePath As String
Dim dwgPath As String
Dim doc As AcadDocument
Dim fileCount As Long
Dim errorCount As Long
‘ — 1. 初期設定とパスの解決 —
targetFolder = “C:\AutoCAD_Archives\” ‘ 監査対象フォルダ
logFilePath = targetFolder & “Audit_Report_” & Format(Now, “yyyymmdd_HHMMSS”) & “.log”
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ ログファイルの作成 (Unicode:False, 上書き:True)
Set tsLog = fso.CreateTextFile(logFilePath, True, False)
Call WriteLog(“=== AutoCAD Audit Batch Execution Started ===”)
Call WriteLog(“Target Directory: ” & targetFolder)
Call WriteLog(“Timestamp: ” & Now)
Call WriteLog(“————————————————–“)
‘ フォルダの存在確認
If Not fso.FolderExists(targetFolder) Then
MsgBox “指定されたフォルダが存在しません: ” & targetFolder, vbCritical, “致命的エラー”
Exit Sub
End If
‘ — 2. 実行環境の最適化 (パフォーマンス向上) —
With ThisDrawing.Application
.ScreenUpdating = False
.Visible = True ‘ 完全非表示にすると一部のAuditダイアログでフリーズするため表示状態を維持
End With
fileCount = 0
errorCount = 0
On Error GoTo ErrorHandler
‘ — 3. ループ処理:対象フォルダ内のDWGを走査 —
Dim targetFile As Object
For Each targetFile In fso.GetFolder(targetFolder).Files
If LCase(fso.GetExtensionName(targetFile.Name)) = “dwg” Then
dwgPath = targetFile.Path
fileCount = fileCount + 1
Call WriteLog(vbCrLf & “[” & fileCount & “] Processing: ” & targetFile.Name)
‘ ドキュメントを開く (Read-Onlyではなく、修復を保存するため通常オープン)
‘ ※ロックされているファイルやパスワード付きはエラー捕捉が必要
Set doc = Documents.Open(dwgPath, False)
If Not doc Is Nothing Then
‘ Auditメソッドの実行
‘ 第1引数: True = エラーを自動修正する, False = 検出のみ
On Error Resume Next
doc.AuditInfo True
If Err.Number <> 0 Then
Call WriteLog(” [ERROR] Audit execution failed: ” & Err.Description)
errorCount = errorCount + 1
Err.Clear
Else
Call WriteLog(” [SUCCESS] Audit completed and fixed.”)
‘ 変更を保存して閉じる
doc.Save
End If
On Error GoTo ErrorHandler
doc.Close False
Set doc = Nothing
End If
End If
Next targetFile
‘ — 4. 終了処理 —
Call WriteLog(vbCrLf & “————————————————–“)
Call WriteLog(“Batch Completed. Total Processed Files: ” & fileCount)
Call WriteLog(“Files with critical errors: ” & errorCount)
Call WriteLog(“Log saved to: ” & logFilePath)
tsLog.Close
Set tsLog = Nothing
Set fso = Nothing
ThisDrawing.Application.ScreenUpdating = True
MsgBox “図面監査バッチが正常終了しました。” & vbCrLf & “ログファイルを確認してください。”, vbInformation, “完了”
Exit Sub
ErrorHandler:
‘ 予期せぬ例外の捕捉
Dim errDesc As String
errDesc = Err.Description
If Not tsLog Is Nothing Then
Call WriteLog(” [FATAL ERROR] ” & errDesc)
End If
If Not doc Is Nothing Then
doc.Close False
Set doc = Nothing
End If
ThisDrawing.Application.ScreenUpdating = True
If Not tsLog Is Nothing Then tsLog.Close
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & errDesc, vbCritical, “実行時エラー”
End Sub
”
‘ ログファイルへタイムスタンプ付きで文字列を書き出すプライベートヘルパー
Private Sub WriteLog(ByVal message As String)
tsLog.WriteLine “[” & Format(Now, “hh:nn:ss”) & “] ” & message
‘ デバッグウィンドウへも同時出力
Debug.Print message
End Sub
—
3. コードの急所:プロフェッショナルが仕込んだ技術的ポイント
このコードが「単なるサンプル」と一線を画す理由は、以下の設計思想に基づいているためだ。
① `AuditInfo` メソッドの正しい引数制御
AutoCADのAPIでは、`Document.Audit` ではなく、オブジェクトモデル上では `AuditInfo(FixErrors As Boolean)` を使用する(※AutoCADのバージョンやVBAリファレンスによる差異に注意)。引数に `True` を渡すことで、「検出されたエラーを自動的に修正せよ」という命令になり、ダイアログボックスによる処理の停止(ハングアップ)を完全に回避している。
② COMオブジェクトのライフサイクル管理とメモリ解放
ループ内で `Documents.Open` を使用する場合、最も恐ろしいのはメモリリークだ。
処理の成否に関わらず、ループの各イテレーションの最後、および例外発生時(`ErrorHandler`)に必ず `doc.Close False` を叩き、変数に `Nothing` を代入してCOM参照を即座に解放している。これを怠ると、数図面処理しただけでAutoCADが Out of Memory(メモリ不足)でクラッシュする。
③ `ScreenUpdating` による描画負荷の軽減
大量の図面を次々に開閉する際、AutoCADが毎度グラフィック画面を再描画していると、処理速度が何倍も遅くなる。`ScreenUpdating = False` によって描画コストを極限まで削り、バックグラウンドに近い速度でバッチを完遂させる。
—
4. 運用上の注意点とさらなる高みへ
このツールを実際の業務(特に社内サーバーやPdm環境)に導入する際は、以下の点に留意してほしい。
- 排他制御(ファイルのロック):他のユーザーがネットワーク上で開いている図面をVBAで開こうとすると、通常は読み取り専用で開くか、エラーになる。本番運用では `Fso.FileExists` と合わせてファイル属性や占有状態をチェックするロジックを加えるとさらに堅牢になる。
- トランザクションとエラーログの詳細化:標準の `AuditInfo` は詳細なエラーオブジェクトのリストを返さないため、より深く「どの画層が消されたか」「どのブロックが修復されたか」をログに収めたい場合は、CADのシステム変数(`AUDITCTL`)を `1` に設定し、AutoCADが自動生成する `.adt` ログファイルをFileSystemObjectで読み取って統合するアプローチが最強のソリューションとなる。
総括
AutoCAD VBAは、単に「マクロで線を引くためのおもちゃ」ではない。
APIの仕様を正しく理解し、OSのリソース管理とライフサイクルを掌握したコードを書けば、巨大な設計資産の品質を守る強力な「自動化インフラ」へと変貌する。
今回の `Audit` 自動化ツールをベースに、あなたの現場のワークフローを極限まで最適化してほしい。
