【テクニカル・上級編】【上級プロフェッショナル向け】図面を開かずにプロパティ情報を取得:DWG/DXFヘッダー情報の解析 – AutoCAD VBA解析バイブル

スポンサーリンク

【AutoCADアーキテクトの極意】図面を「開かずに」DWGの魂を読み解く:ヘッダー解析の深淵

AutoCADのオートメーションにおいて、最も無駄で、かつ最も頻発する罪。それは「情報の取得のために図面を一度開くこと」だ。

数千、数万の図面ファイルをバッチ処理する際、`Documents.Open`を呼び出す設計は、設計者として失格と言わざるを得ない。AutoCADのアプリケーションインスタンスを立ち上げ、Drawingオブジェクトをメモリにロードし、イベントを初期化する。そのオーバーヘッドは、巨大な図面であればあるほどシステムを麻痺させる。

今回は、真のエンジニアが辿り着くべき、「図面をロードせずにファイルバイナリからヘッダー情報を抽出する」という禁断のテクニックを伝授する。

—

1. なぜ「開いてはいけない」のか?

AutoCADのCOM API経由で図面を開くと、以下のリソースを強制的に消費する。

  • Documentのメモリ確保: オブジェクトモデル全体をメモリ上に構築するコスト。
  • イベントループのオーバーヘッド: `BeginOpen`や`EndOpen`などのイベントフック。
  • ファイルロック: 他のプロセスやユーザーとの競合。

これらは、単に「DWGバージョン」や「作成者」を知りたいだけの処理には過剰すぎる。私たちは、OSレベルのファイルI/Oを用いて、DWGファイルの先頭128バイト(ヘッダー部)を直接読み取るべきなのだ。

—

2. DWGファイル形式の構造的真実

DWGファイルは、歴史的に「マジックナンバー」と呼ばれるシグネチャを先頭に持っている。

| バージョン文字列 | 内部コード (例) |
| :— | :— |
| AC1027 | AutoCAD 2013 |
| AC1032 | AutoCAD 2018 |
| AC1035 | AutoCAD 2021 |

この文字列は、ファイルの先頭数バイトに必ず存在する。これさえ特定できれば、巨大なCADエンジンを回す必要はない。

—

3. 実装:Windows APIを用いた高速ヘッダー抽出

以下のコードは、VBAから`Scripting.FileSystemObject`を使用してファイルをバイナリで開き、先頭のシグネチャのみを抽出する最小構成だ。

‘ DWGヘッダー情報を低負荷で取得するためのプロシージャ
Public Function GetDwgVersion(ByVal filePath As String) As String
Dim fileNum As Integer
Dim headerStr As String 6 ‘ 先頭6バイト(AC10xx)を読み込むための固定長文字列

If Dir(filePath) = “” Then
GetDwgVersion = “Error: File not found”
Exit Function
End If

‘ バイナリモードでアクセス。共有ロックをかけて読み込む
fileNum = FreeFile
Open filePath For Binary Access Read Shared As #fileNum

‘ 先頭から6バイトを取得
Get headerStr

Close #fileNum

‘ 抽出したシグネチャを返す
GetDwgVersion = headerStr
End Function

【プロの知見】メモリ最適化と安定性へのこだわり

  • Access Read Shared: これが重要だ。CADで図面が開かれている最中でも、このコードはファイルを読み取れる。排他制御でシステムを止めることは許されない。
  • 固定長文字列の活用: `String 6` を用いることで、動的なメモリ確保の頻度を抑え、ガベージコレクションの負荷を最小化している。

—

4. さらなる高みへ:DXFの解析

DXF形式はテキストファイルであるため、さらに容易だ。`$ACADVER` グループコードを探せばよい。ただし、全行読み込むのは愚策だ。

Public Function GetDxfVersion(ByVal filePath As String) As String
Dim fso As Object
Dim ts As Object
Dim line As String

Set fso = CreateObject(“Scripting.FileSystemObject”)
Set ts = fso.OpenTextFile(filePath, 1) ‘ ForReading

Do While Not ts.AtEndOfStream
line = Trim(ts.ReadLine)
If line = “$ACADVER” Then
‘ 次の行にバージョン情報が格納されている
GetDxfVersion = ts.ReadLine
Exit Do
End If
Loop

ts.Close
Set ts = Nothing
Set fso = Nothing
End Function

—

5. アーキテクトからの助言:システム間連携の要諦

大規模な図面管理システムを構築する際、この「ヘッダー解析」は単なる機能の一部に過ぎない。真のプロフェッショナルは、「情報の取得」と「情報の更新」を完全に分離する。

1. インデックスサーバーの構築: バックグラウンドでファイルシステムを監視し、このバイナリ解析手法でメタデータを抽出、SQLデータベースに書き出す。
2. UI層からのクエリ: ユーザーが図面を開く際は、CADエンジンを呼ぶのではなく、データベース上のメタデータをまず表示する。

このアーキテクチャこそが、何万ファイルもの図面を扱う現場における、唯一の生存戦略である。

AutoCAD VBAは、単なるマクロの集合体ではない。APIの隙間を縫い、OSの制約を理解し、計算資源を極限まで効率化する。その技術の先にあるのは、ただの「自動化」ではなく「秩序」である。

君たちのコードが、次なる伝説のシステムを支えることを期待している。

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