【実務・中級編】【上級プロフェッショナル向け】バイナリレベルでの「DWG/DXF破損」判定:AutoCAD APIがフリーズする前に不正ファイルを検知する – AutoCAD VBA解析バイブル

スポンサーリンク
スポンサーリンク

AutoCAD VBAを掌握する極限の知見:バイナリレベルでの「DWG/DXF破損」判定によるハングアップ回避術

業務自動化エンジニアとして、大規模な図面処理プロセスを構築している際、最も恐ろしい事態は何だろうか?

それは、コードのバグではない。「不正なファイル(破損ファイル)を読み込もうとした瞬間に、AutoCAD本体がフリーズ(ハングアップ)し、制御不能になること」だ。

多くの開発者は、`Documents.Open` メソッドを `On Error Resume Next` で囲めば、エラーを回避できると誤解している。だが、それは致命的な間違いだ。ファイルヘッダーが壊れている、あるいはDWG形式を装った不正なバイナリである場合、AutoCADの内部エンジンはファイル構造を解析しようとループに陥り、あるいはメモリセグメンテーション違反を起こして、VBAの制御権を返さなくなる。

本記事では、AutoCAD APIを呼び出す「前」に、バイナリレベルでファイルの正当性を検知し、システムを死守する防御的プログラミング(Defensive Programming)の極意を伝授する。

1. なぜ「APIによるエラーハンドリング」では不十分なのか

設計思想の根本的な欠陥を理解せよ。

AutoCAD VBAにおける `Documents.Open` は、AutoCADという巨大なブラックボックスに対して「このファイルを解析して開け」という命令を下す行為だ。ファイルが「論理的に壊れている(例:図形データが欠落している)」場合はエラーを返してくれる。

しかし、ファイルが「構造的に壊れている(例:ヘッダーのシグネチャが不正、ファイル形式が全く別物)」場合、AutoCADは「これはDWGファイルである」と信じ込んで解析を強行しようとする。この解析フェーズこそが、ハングアップの温床だ。

「APIがエラーを吐くのを待つ」のではなく、「APIに渡す前に、そのファイルが『DWGのふりをした何か』でないことを証明する」。これがプロフェッショナルな設計の境界線である。

2. 守護神としての「バイナリ・シグネチャ・チェック」

DWGファイルは、その先頭数バイトに特定の「マジックナンバー(シグネチャ)」を持っている。これをバイナリモードで直接読み取ることで、AutoCADのエンジンに触れる前に、ファイルが「本物のDWGか」を判定できる。

DWG形式の識別ポイント

AutoCADのバージョンによって細かな違いはあるが、DWGファイルは常に特定のヘッダーパターンから始まる。例えば、`AC10` で始まる識別コード(AC1015, AC1024など)が、ファイル構造の根幹を担っている。

DXF形式の識別ポイント

DXFはテキストベースの形式であるため、先頭に `SECTION` や特定のヘッダー文字列が存在する。

これらをVBAの `Open # [file number] For Binary` を用いて、メモリ負荷を最小限に抑えつつスキャンする手法を以下に示す。

3. プロダクション・コード:堅牢なファイルバリデーター

以下に、実務レベルでそのまま組み込める、高信頼性のバリデーション・モジュールを提示する。単なる `True/False` を返す関数ではなく、詳細な状態を返す設計にしている。

Option Explicit

' ファイルの健全性を表す列挙型
Public Enum FileValidationStatus
    svValidDWG = 0
    svValidDXF = 1
    svInvalidFormat = 2     ' DWG/DXFではない
    svFileCorruptHeader = 3 ' ヘッダーが異常(破損の疑い)
    svAccessDenied = 4      ' アクセス権限なし
    svFileNotFound = 5      ' ファイルが存在しない
End Enum

''' <summary>
''' AutoCADエンジンに渡す前に、ファイルのバイナリ構造を検証する。
''' </summary>
''' <param name="filePath">対象ファイルのフルパス</param>
''' <returns>検証結果 (FileValidationStatus)</returns>
Public Function ValidateFileIntegrity(ByVal filePath As String) As FileValidationStatus
    Dim fileNum As Integer
    Dim headerBuffer As String
    Dim bytesRead As Long
    Dim firstBytes As Byte()
    
    ' 1. 存在確認
    If Dir(filePath) = "" Then
        ValidateFileIntegrity = svFileNotFound
        Exit Function
    End If

    On Error GoTo ErrHandler
    fileNum = FreeFile
    
    ' 2. バイナリモードでオープン(極めて高速)
    Open filePath For Binary Access Read As #fileNum
    
    ' DWG/DXF判定に必要な最小限のバイト数(例として16バイト)を読み込む
    ' これにより、巨大なファイルでも一瞬で判定が終わる
    ReDim firstBytes(0 To 15)
    Get #fileNum, , firstBytes
    Close #fileNum
    
    ' 3. バイナリ解析ロジック
    ' --- DWG判定 ---
    ' DWGのシグネチャを確認(例:AC10...)
    ' ※実際のバイナリ値はバージョンにより異なるが、一般的に先頭に"AC"が含まれる
    If firstBytes(0) = &H41 And firstBytes(1) = &H43 Then ' 'A' and 'C'
        ' ここでさらに詳細なバージョンチェックを行うことも可能
        ValidateFileIntegrity = svValidDWG
        Exit Function
    End If
    
    ' --- DXF判定 ---
    ' DXFはテキスト形式なので、最初の数文字を文字列として評価
    headerBuffer = StrConv(firstBytes, vbUnicode)
    If InStr(1, headerBuffer, "SECTION", vbTextCompare) > 0 Or _
       InStr(1, headerBuffer, "!", vbTextCompare) > 0 Then
        ValidateFileIntegrity = svValidDXF
        Exit Function
    End If

    ' 判定不能
    ValidateFileIntegrity = svInvalidFormat
    Exit Function

ErrHandler:
    If fileNum > 0 Then Close #fileNum
    ' 読み取りエラーが発生した場合は、ヘッダーが物理的に壊れている可能性が高い
    ValidateFileIntegrity = svFileCorruptHeader
End Function

実装のポイント(アーキテクトの視点)

1. `Open For Binary Access Read`: ファイル全体をメモリに載せるのではなく、先頭の数バイトだけを「覗き見」する。これにより、数GBある巨大なDWGファイルでも、処理時間はマイクロ秒単位になる。
2. `StrConv` の活用: バイナリデータを文字列として解釈し、DXFのキーワードを検索する手法は、テキストベースのフォーマット判定において極めて効率的だ。
3. `Enum` による詳細な戻り値: 「ダメだった」だけでは、自動化プロセスは止まる。それが「ファイルがない」のか「壊れている」のかを区別させることで、エラーログに「破損ファイルを隔離(Quarantine)しました」といった高度なメッセージを残せるようになる。

4. データベース連携と実務への統合設計

このバリデーターを単体で使うのは素人だ。プロはこれを「パイプライン」の一部として組み込む。

推奨される処理フロー

1. Scan Phase: フォルダ内のファイルをリストアップ。
2. Pre-flight Phase (本手法): `ValidateFileIntegrity` を実行。

  • `svValidDWG/DXF` $\rightarrow$ 処理キューへ。
  • `svFileCorruptHeader/svInvalidFormat` $\rightarrow$ 「破損ファイル管理テーブル」へレコードを書き込み、隔離フォルダへ移動。

3. Execution Phase: 信頼できるファイルのみ `Documents.Open` を実行。

データベース(SQL Server / Access)との連携注意点

自動化ツールを運用する場合、どのファイルがいつ、なぜ失敗したのかをDBに記録すべきだ。

  • 注意点: ファイルの破損判定結果をDBに保存する際、ファイルパスだけでなく、「ファイルサイズ」と「最終更新日時」も併せて保存せよ。破損ファイルは、OSレベルの書き込みエラーやネットワーク切断によって「サイズが0」または「不自然に小さい」状態になっていることが多いため、これらは強力な二次証拠となる。

5. 結論:堅牢なコードは「疑うこと」から始まる

「AutoCADが読み込んでくれるだろう」という甘い期待は、プロフェッショナルな自動化の現場では通用しない。

APIは、あくまで「正常なデータ」を扱うための道具だ。その道具に渡す前に、データの「門番(Gatekeeper)」としてバイナリレベルのチェックを実装すること。これが、大規模なバッチ処理を、夜通し一度も止めることなく完遂させるための、唯一にして最強の戦略である。

設計に妥協するな。エラーを待つな。検知せよ。

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