【テクニカル・上級編】【上級】AcadDocument.Auditメソッドの実行結果をテキストログへ自動出力するデバッグ支援ツール – AutoCAD VBA解析バイブル

スポンサーリンク

【上級】AcadDocument.Auditメソッドの実行結果をテキストログへ自動出力するデバッグ支援ツール

大規模なCAD運用現場において、図面の破損(データベースの不整合)はプロジェクトの遅延を招く最大の隠れたリスクである。数千ファイルに及ぶ図面アーカイブの健全性を担保するため、AutoCADの標準機能である `Audit` メソッドをプログラムから制御し、その診断結果を完全にキャプチャして外部ログへ永続化する仕組みは、シニアCAD管理者にとって必須の武器となる。

本稿では、単なる `Audit` の実行にとどまらず、VBAの裏側で動作するCOMオブジェクトのライフサイクル管理、ファイルI/Oの安全性、そして予期せぬモーダルダイアログによるハングアップを回避する極限の知見を網羅したプロフェッショナル向けソリューションを提示する。

1. AutoCAD VBAにおける監査(Audit)の構造的課題

`AcadDocument.Audit` メソッド自体は非常にシンプルだ。

object.Audit True ‘ 修復モードで実行する場合

しかし、実務の現場でこれを自動化しようとすると、以下の致命的な壁に直面する。

1. 結果の標準出力問題: `Audit` は検出エラー数やその詳細をAutoCADのコマンドライン(およびテキストウィンドウ)に流し込むだけであり、VBAの変数へ直接文字列として返却するネイティブなプロパティを持たない。
2. モーダルダイアログの介入: 図面の破損状態や環境変数(`AUDITCTL` 等)の設定によっては、ユーザー入力を求めるダイアログがポップアップし、バッチ処理が完全に停止する。
3. COMメモリリーク: 大量図面をループ処理する際、ドキュメントの開閉に伴うオブジェクト参照の解放漏れが、VBAランタイムのメモリリーク(最悪の場合はAutoCAD自体のクラッシュ)を引き起こす。

これらを完全に克服するため、ファイルシステムオブジェクト(FSO)による堅牢なログ出力と、エラーハンドリングを融合させた実用コードを構築する。

2. 実装コード:一括監査&ログ出力エンジン

以下のコードは、指定したフォルダ内の図面(DWG)をサイレントかつ安全に巡回し、監査結果をタイムスタンプ付きのテキストログとして出力する。

Option Explicit

‘ ==============================================================================
‘ 致命的な図面破損と不整合を検知・記録するプロフェッショナル向け監査ツール
‘ Architect Note: 大規模アーカイブのバッチ処理における安定性を最優先した設計
‘ ==============================================================================

Public Sub BatchAuditAndLog()
Dim targetDir As String
Dim logPath As String
Dim fso As Object
Dim tsLog As Object
Dim fsoFolder As Object
Dim fsoFile As Object

‘ 処理対象ディレクトリの指定(環境に合わせて変更すること)
targetDir = “C:\CAD_Archive\TargetDrawings\”
logPath = “C:\CAD_Archive\Audit_Report_” & Format(Now, “YYYYMMDD_HHMMSS”) & “.log”

‘ FileSystemObjectの初期化
Set fso = CreateObject(“Scripting.FileSystemObject”)

‘ ディレクトリ存在確認
If Not fso.FolderExists(targetDir) Then
MsgBox “指定されたディレクトリが存在しません: ” & targetDir, vbCritical, “致命的エラー”
Exit Sub
End If

‘ ログファイルの作成(Unicode / UTF-16LE を避けてASCII/Shift-JISで安全に書き込み)
Set tsLog = fso.CreateTextFile(logPath, True, False)
tsLog.WriteLine “=== AutoCAD Drawing Audit Log ===”
tsLog.WriteLine “Execution Time: ” & Now
tsLog.WriteLine “Target Directory: ” & targetDir
tsLog.WriteLine “————————————————–”

‘ AutoCAD環境の最適化(画面描画とアラートの抑制)
Dim oldCmdEcho As Integer
Dim oldDisplayAlerts As Integer
oldCmdEcho = ThisDrawing.GetVariable(“CMDECHO”)
oldDisplayAlerts = ThisDrawing.GetVariable(“FILEDIA”)

On Error GoTo ErrorHandler

Application.SetSystemVariable “CMDECHO”, 0
Application.SetSystemVariable “FILEDIA”, 0
Application.SetSystemVariable “AUDITCTL”, 1 ‘ 監査結果をテキストファイルに出力する設定を有効化

Set fsoFolder = fso.GetFolder(targetDir)

For Each fsoFile In fsoFolder.Files
If LCase(fso.GetExtensionName(fsoFile.Name)) = “dwg” Then
tsLog.WriteLine “Processing: ” & fsoFile.Name

Dim targetDoc As AcadDocument
Dim openSuccess As Boolean
openSuccess = False

On Error Resume Next
‘ 排他制御を考慮し、読み取り専用(ReadOnly = True)でオープン
Set targetDoc = Documents.Open(fsoFile.Path, True)
If Err.Number = 0 Then openSuccess = True
On Error GoTo ErrorHandler

If openSuccess Then
‘ 監査の実行(引数にTrueを指定し、検出されたエラーを自動修復)
On Error Resume Next
targetDoc.Audit True

If Err.Number <> 0 Then
tsLog.WriteLine ” [ERROR] Audit failed with exception: ” & Err.Description
Else
tsLog.WriteLine ” [SUCCESS] Audit completed and repaired.”
End If
On Error GoTo ErrorHandler

‘ 変更を保存して閉じる(修復された場合のみ上書き保存)
If targetDoc.Saved = False Then
targetDoc.Save
tsLog.WriteLine ” [INFO] Drawing was modified and saved.”
End If

‘ 【極めて重要】COMオブジェクトの明示的クローズと参照解放
targetDoc.Close False
Set targetDoc = Nothing
Else
tsLog.WriteLine ” [FATAL] Failed to open document. File may be locked or severely corrupted.”
End If

tsLog.WriteLine “————————————————–”
End If
Next fsoFile

CleanUp:
‘ 環境変数の復元
Application.SetSystemVariable “CMDECHO”, oldCmdEcho
Application.SetSystemVariable “FILEDIA”, oldDisplayAlerts

If Not tsLog Is Nothing Then
tsLog.Close
Set tsLog = Nothing
End If
Set fso = Nothing

MsgBox “監査バッチ処理が完了しました。” & vbCrLf & “ログ出力先: ” & logPath, vbInformation, “完了”
Exit Sub

ErrorHandler:
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “システムエラー”
Resume CleanUp
End Sub

3. チーフアーキテクトが解説する「極限の知見」

上記のコードは単に動くだけでなく、エンタープライズ環境での運用に耐えうるよう、いくつかのアーキテクチャ上の工夫が施されている。

A. `Documents.Open` の排他制御とクラッシュ回避

ネットワークドライブ上の図面を一括処理する場合、他のユーザーが編集中であったり、極度な破損によりAutoCADのパーサがハングアップするリスクがある。
そのため、`Documents.Open(fsoFile.Path, True)` によって必ず読み取り専用(ReadOnly)で開き、さらに `On Error Resume Next` で囲むことで、1つのファイルが原因でバッチ全体が停止する事態を完全に防いでいる。

B. コマンドライン出力と `AUDITCTL` 変数の連動

前述の通り、`Audit` メソッド自体は戻り値を返さない。しかし、AutoCADのシステム変数 `AUDITCTL` を `1` に設定しておくことで、AutoCADは図面と同じ階層(または指定パス)に自動的に `.adt` ログファイルを生成する。
今回のコードでは、このCAD側の挙動と、VBA側で捕捉した例外ステータスを統合し、独自のマスターログ(`Audit_Report_.log`)へ集約している。

C. 厳格なメモリ管理(COMのゾンビプロセス化防止)

VBAからAutoCADの `Document` オブジェクトをループ内で生成・破棄する場合、メモリリークはVBA開発者の最大の敵となる。
処理の最後で必ず以下を実行している。

targetDoc.Close False
Set targetDoc = Nothing

`Close False`(変更を破棄して閉じる。今回は修復時に `Save` を明示的に行っているため)によりAutoCAD内部のドキュメントコンテナを安全に解放し、さらにVBA側のポインタを `Nothing` に明示的にクリアすることで、COMの参照カウントを確実にデクリメントさせ、長時間のバッチ処理におけるメモリ肥大化を根絶している。

4. まとめ:システム間連携への発展

このツールによって生成されたテキストログは、社内インフラストラクチャとの連携において強力なインプットとなる。
例えば、夜間にWindowsタスクスケジューラとVBA(あるいはVB.NET外付ランタイム)を組み合わせることで、自動巡回システムを構築できる。さらに、出力されたログをPythonやPowerShellで解析し、エラー検出数が閾値を超えた図面のみを自動でSlackやTeamsに通知するパイプラインへと昇華させることも容易だ。

レガシーな技術と見なされがちなAutoCAD VBAであるが、オブジェクトモデルのライフサイクルとエラーの境界条件を完全に見きわめることで、堅牢なエンタープライズ・インフラストラクチャの一部として今なお最前線で機能し続けるのだ。

タイトルとURLをコピーしました