【入門編】【上級プロフェッショナル向け】ObjectDBXを用いた「超高速」属性検索:1000枚の図面を開かずに特定文字列を抽出・保存 – AutoCAD VBA解析バイブル

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

図面を開かずに、魂を抜き取る。ObjectDBXで実現する「超高速」データ抽出の極意

こんにちは。設計自動化の世界へようこそ。

「1,000枚の図面の中から、特定のプロジェクト番号が書かれた属性情報を抜き出したい」

もしあなたが現場でこう命じられたら、どうしますか? マクロの記録を使って、一つずつ `Documents.Open` で図面を開き、属性を読み取り、閉じる……。そんなコードを書いていたら、処理が終わる頃には日が暮れ、PCは悲鳴を上げ、メモリ不足でAutoCADがクラッシュしてしまうでしょう。

今日は、そんな「力技の自動化」から卒業し、プロフェッショナルの領域へと足を踏み入れるための魔法、ObjectDBX を伝授します。

「図面を開かずに、中身だけを覗き見る」。この感覚を掴めれば、あなたの自動化スキルは劇的に進化しますよ。

1. なぜ「Documents.Open」ではいけないのか?

まず、私たちが避けるべき「重い処理」の正体を知っておきましょう。

通常、VBAで図面を開くときは `ThisDrawing.Documents.Open` を使います。これは、AutoCADの画面上に図面を「描画」し、すべてのレイヤー、線種、ブロック、ユーザーインターフェースをメモリ上に展開することを意味します。

  • 描画のコスト: 画面に線を引く計算は非常に重い。
  • メモリの消費: 図面を開くたびに、GUI(見た目)のためのメモリが大量に消費される。
  • 時間の浪費: 1枚数秒かかるとするだけで、1,000枚では1時間近くかかります。

これに対し、ObjectDBX は、AutoCADの「見た目(UI)」を完全にバイパスし、図面ファイル(DWG)という「データベース」に直接アクセスする技術です。

例えるなら、「家の中に入って家具を一つずつ確認する(Documents.Open)」のではなく、「家の設計図と郵便受けだけを外から超高速でスキャンする(ObjectDBX)」ようなものです。

2. ObjectDBXの実装:実践的なコード例

では、実際にどのように実装するかを見ていきましょう。
ここでは、指定したフォルダ内の全DWGファイルから、特定の「属性値(Attribute)」を探し出すコードを書いていきます。

ここでのポイントは、「Late Binding(遅延結合)」を使うことです。これにより、AutoCADのバージョンが変わってもコードを書き直す必要がなくなります。

Option Explicit

''' <summary>
''' 指定したフォルダ内の全DWGから、特定の属性値を検索するプロシージャ
''' </summary>
Sub UltraFastAttributeSearch()
    Dim targetFolder As String
    Dim fileName As String
    Dim dbxDoc As Object ' ObjectDBX.AxDbDocument を Late Binding で宣言
    Dim dwgVersion As Integer
    Dim foundCount As Long
    Dim searchString As String
    
    ' --- 設定エリア ---
    targetFolder = "C:\Work\Project_Data\" ' 検索対象のフォルダ(最後に \ を忘れないで)
    searchString = "PROJ-2023-X"          ' 探したい文字列
    foundCount = 0
    ' ------------------

    ' AutoCADのバージョンを取得(ObjectDBXのバージョン指定に必要)
    ' 例: AutoCAD 2024なら 24
    dwgVersion = Application.Version
    
    ' ObjectDBXオブジェクトの生成
    ' ここで「ObjectDBX.AxDbDocument.[バージョン]」を指定するのが極意です
    On Error Resume Next
    Set dbxDoc = CreateObject("ObjectDBX.AxDbDocument." & dwgVersion)
    On Error GoTo 0
    
    If dbxDoc Is Nothing Then
        MsgBox "ObjectDBXの初期化に失敗しました。バージョンを確認してください。", vbCritical
        Exit Sub
    End If

    ' フォルダ内のDWGファイルを順次処理
    fileName = Dir(targetFolder & "*.dwg")
    
    Do While fileName <> ""
        Debug.Print "Checking: " & fileName
        
        ' --- ファイルをメモリ上にロード (画面には表示されない) ---
        On Error Resume Next
        dbxDoc.Open (targetFolder & fileName)
        
        If Err.Number <> 0 Then
            Debug.Print "  [Error] ファイルが開けません: " & fileName
            Err.Clear
        Else
            ' --- 属性検索のロジック ---
            ' ブロック参照を走査して属性を探す
            foundCount = foundCount + SearchAttributesInDBX(dbxDoc, searchString)
        End If
        On Error GoTo 0
        
        fileName = Dir() ' 次のファイルへ
    Loop

    MsgBox "検索完了!" & vbCrLf & "見つかった件数: " & foundCount & " 件", vbInformation
    
    ' 後片付け:オブジェクトの解放はプロフェッショナルの作法
    Set dbxDoc = Nothing
End Sub

''' <summary>
''' ObjectDBXドキュメント内を走査して属性を検索する関数
''' </summary>
Private Function SearchAttributesInDBX(ByRef dbxDoc As Object, ByVal targetText As String) As Long
    Dim ent As Object
    Dim blockRef As Object
    Dim attRef As Object
    Dim count As Long
    
    count = 0
    
    ' ドキュメント内のエンティティをループ
    For Each ent In dbxDoc.ModelSpace
        ' エンティティが「ブロック参照」かどうかを確認
        If ent.EntityName = "AcDbBlockReference" Then
            Set blockRef = ent
            
            ' ブロックに属性が含まれているか確認
            If blockRef.HasAttributes Then
                ' 属性をループ
                For Each attRef In blockRef.GetAttributes
                    ' 文字列が含まれているか判定
                    If InStr(1, attRef.TextString, targetText, vbTextCompare) > 0 Then
                        Debug.Print "    [FOUND] File: " & dbxDoc.Name & " | Attr: " & attRef.TagString & " = " & attRef.TextString
                        count = count + 1
                    End If
                Next attRef
            End If
        End If
    Next ent
    
    SearchAttributesInDBX = count
End Function

3. コードの深層解説:ここが「プロ」の分かれ道

初心者の方が「マクロの記録」から脱却する際に、必ず躓くポイントを解説します。

① Late Binding(遅延結合)の重要性

コード内で `CreateObject(“ObjectDBX.AxDbDocument.” & dwgVersion)` としていますね。
通常、VBAの「参照設定」でライブラリを追加すれば、入力補完(インテリセンス)が効いて便利です。しかし、参照設定をしてしまうと、「そのバージョンのAutoCADでしか動かないツール」になってしまいます。
プロの道具は、環境を選ばず動くべきです。`Object` 型として宣言し、実行時にオブジェクトを生成することで、汎用性を極限まで高めています。

② エンティティの「EntityName」判定

`ent.EntityName = “AcDbBlockReference”` という記述。
AutoCAD内部では、すべての図形は特定の名前を持っています。「線」なら `AcDbLine`、「円」なら `AcDbCircle` です。属性は「ブロック参照(Block Reference)」の中に住んでいます。この「図形の正体」を正しく見極めることが、高速検索の第一歩です。

③ メモリ管理とエラーハンドリング

`On Error Resume Next` を使いどころを見極めて使っています。
大量のファイルを処理する場合、「1枚の破損ファイル」のせいで、1,000枚の処理が止まってしまっては本末転倒です。エラーを適切にスキップしつつ、ログ(Debug.Print)に残す。これが、現場で「使える」ツールを作るための鉄則です。

4. 陥りやすい罠:トラブルシューティング

この技術を使う際、以下の3点には特に注意してください。

1. 読み取り専用エラー:
他のユーザーがその図面を開いている場合、ObjectDBXでの `Open` は失敗することがあります。運用ルールとして、ファイルを共有フォルダの適切な場所に集約してから実行するのがベストです。
2. バージョン不一致:
ObjectDBXは、AutoCAD本体のバージョンと密接に紐付いています。`Application.Version` を使って動的に指定するように設計してください。
3. メモリの解放:
ループの中で `Set dbxDoc = Nothing` をしすぎると、逆にオーバーヘッド(処理の重み)が増えます。ループの外で一度だけ生成し、最後に解放するのが、パフォーマンスを最大化するコツです。

最後に:エンジニアとしての視点

ObjectDBXを使いこなせるようになると、「図面を扱う」という感覚が変わります。
「図面は絵(グラフィックス)である」という視点から、「図面は構造化されたデータ(データベース)である」という視点への転換です。

この視点を持つことが、単なる「マクロ使い」を卒業し、真の「業務自動化エンジニア」へと駆け上がるための鍵となります。

一歩ずつ、確実に。
もしエラーが出ても、それは新しい知識を得るためのチャンスです。
さあ、次はどんな巨大なデータを、あなたの手で制御してみますか?

応援していますよ。

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