【テクニカル・上級編】【上級プロフェッショナル向け】ObjectDBXと正規表現を組み合わせた、図面を開かない「全注釈テキスト」の一括検索・置換保存 – AutoCAD VBA解析バイブル

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

図面データ・ミューテーションの極致:ObjectDBXと正規表現による非表示・高速一括置換アーキテクチャ

エンジニアが「図面を一つずつ開いて修正する」などという、人間の手作業の延長線上にあるような非効率な作業に時間を溶かしているのを見るたび、私は深い溜息を禁じ得ない。

数千、数万のDWGファイルがストレージに眠っているとき、それらを「図面(Drawing)」として扱うのではなく、「データベース(Database)」として扱う思考への転換が必要だ。AutoCADのGUIを起動し、エディタをロードし、描画エンジンを走らせる――そのプロセスは、単なるテキストの置換という目的においては、あまりにも重すぎるオーバーヘッドだ。

本稿では、AutoCAD VBAの深淵、ObjectDBXを利用した「非表示・非介入」によるデータ操作と、VBScript.RegExpによる高度なパターンマッチングを組み合わせた、プロフェッショナル向けのバッチ処理アーキテクチャを解説する。これは単なるコードの提示ではない。メモリ管理、オブジェクトのライフサイクル、そして計算資源の最適化に関する設計思想の伝承である。

1. 概念設計:なぜ「開かない」ことが至上命令なのか

通常の `Documents.Open` メソッドは、AutoCADの全機能をメモリ上に展開する。これは、図面内のエンティティを視覚的に操作するには最適だが、大量のファイルに対する機械的なデータ操作においては、致命的な欠陥となる。

資源の浪費とリスク

1. メモリ・フラグメンテーション: 大量のDWGをGUI経由で開閉すると、AutoCADのヒープ領域は断片化し、最終的にアプリケーションのクラッシュを招く。
2. I/Oのボトルネック: 描画情報のレンダリング、ユーザーインターフェースの更新、コマンドラインの出力。これら全てが、本来不要な計算資源を食いつぶす。
3. スケーラビリティの欠如: 数千ファイル規模では、処理時間は指数関数的に増大する。

ObjectDBXという解

ObjectDBXは、AutoCADのコア・データベース・エンジンに直接アクセスするためのCOMインターフェースだ。GUIを一切介さず、DWGの内部構造(Entity, Layer, Block, Text等)に直接、極めて低いレイヤーでアクセスする。これにより、メモリ消費を劇的に抑え、処理速度を通常の数十倍にまで引き上げることが可能になる。

2. 実装戦略:正規表現による精密なパターンマッチング

製品番号や日付といったデータは、単純な `Replace` 関数では太刀打ちできない。
例えば、`PN-2023-A1` を `PN-2024-B2` へ書き換えたい場合、単なる文字列置換では、意図しない箇所(図面内の他のコードなど)を破壊するリスクがある。

ここで VBScript.RegExp を導入する。正規表現を用いることで、「特定の接頭辞を持ち、特定の桁数の数字が続くパターン」といった、文脈に応じた厳密な抽出と置換が可能となる。

3. 極限のコード・アーキテクチャ

以下に、プロフェッショナルが実装すべき堅牢なモジュールを示す。ここでは、メモリリークを防ぐための「明示的なオブジェクト解放」と、エラーハンドリングによる「バッチ処理の継続性」に重点を置いている。

' **
' Module: Mod_MassTextProcessor
' Description: ObjectDBXを用いた高速・非表示図面一括置換エンジン
' Author: Legendary Chief Architect
' **

Option Explicit

' 参照設定が必要なもの:
' 1. AutoCAD Type Library
' 2. Microsoft VBScript Regular Expressions 5.5 (Late Bindingでも可)

Sub ExecuteMassReplacement()
    Dim targetFolder As String
    Dim fileList As Collection
    Dim dwgFile As Variant
    Dim dbxDoc As Object ' AxDbDocument
    Dim regex As Object
    
    ' --- 設定領域 ---
    targetFolder = "C:\Data\Project_Drawings\" ' 対象フォルダ
    
    ' 正規表現パターンの定義 (例: PN-2023-XXXX を PN-2024-XXXX に置換)
    ' ここでは「PN-2023-」で始まるパターンをターゲットにする
    Dim pattern As String: pattern = "PN-2023-[A-Z0-9]{4}"
    Dim replacement As String: replacement = "PN-2024-NEWV"
    ' ----------------
    
    ' 正規表現オブジェクトの初期化 (Late Binding)
    Set regex = CreateObject("VBScript.RegExp")
    With regex
        .Global = True
        .IgnoreCase = True
        .Pattern = pattern
    End With
    
    ' ファイルリストの取得
    Set fileList = GetFileList(targetFolder & "*.dwg")
    
    Debug.Print "Starting Batch Process: " & fileList.Count & " files found."
    
    ' メインループ
    For Each dwgFile In fileList
        On Error Resume Next ' 個別ファイルのエラーで全体を止めないための防壁
        
        ' 1. ObjectDBXドキュメントの生成
        ' AutoCADのバージョンに合わせたDBXオブジェクトを取得
        Set dbxDoc = CreateObject("ObjectDBX.AxDbDocument." & GetAutoCADVersion())
        
        If Err.Number <> 0 Then
            Debug.Print "Error creating DBX object for: " & dwgFile & " | " & Err.Description
            Err.Clear
            GoTo NextFile
        End If
        
        ' 2. ファイルのオープン (DBX経由)
        dbxDoc.Open dwgFile
        
        If Err.Number <> 0 Then
            Debug.Print "Failed to open: " & dwgFile & " | " & Err.Description
            Err.Clear
            GoTo NextFile
        End If
        
        ' 3. エンティティの走査と置換
        If ProcessEntityCollection(dbxDoc.ModelSpace, regex, replacement) Then
            ' 変更があった場合のみ保存
            dbxDoc.SaveAs dwgFile
            Debug.Print "SUCCESS: " & dwgFile
        Else
            Debug.Print "SKIPPED (No match): " & dwgFile
        End If
        
        ' 4. メモリ解放 (重要: オブジェクトのライフサイクルを厳格に管理)
        Set dbxDoc = Nothing
        
NextFile:
        On Error GoTo 0
    Next dwgFile
    
    Set regex = Nothing
    Set fileList = Nothing
    Debug.Print "Batch Process Completed."
End Sub

' **
' Function: ProcessEntityCollection
' Description: ModelSpace内のTextおよびMTextを走査し、正規表現で置換を行う
' **
Private Function ProcessEntityCollection(ByVal coll As Object, ByRef regex As Object, ByVal replacement As String) As Boolean
    Dim ent As Object
    Dim modified As Boolean
    Dim currentText As String
    Dim newText As String
    
    modified = False
    
    ' コレクション内の全エンティティをループ
    For Each ent In coll
        ' Text または MText オブジェクトを対象とする
        If TypeName(ent) = "AcDbText" Or TypeName(ent) = "AcDbMText" Then
            currentText = ent.TextString
            
            ' 正規表現によるマッチング判定
            If regex.Test(currentText) Then
                ' 置換実行
                newText = regex.Replace(currentText, replacement)
                
                ' 変更がある場合のみ書き戻し
                If currentText <> newText Then
                    ent.TextString = newText
                    modified = True
                End If
            End If
        End If
    Next ent
    
    ProcessEntityCollection = modified
End Function

' **
' Function: GetFileList
' Description: 指定フォルダ内のファイルリストをCollectionとして返す
' **
Private Function GetFileList(ByVal pattern As String) As Collection
    Dim fso As Object
    Dim folder As Object
    Dim file As Object
    Dim col As New Collection
    Dim path As String
    Dim fileName As String
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    path = Left(pattern, InStrRev(pattern, "\") - 1)
    fileName = Mid(pattern, InStrRev(pattern, "\") + 1)
    
    Set folder = fso.GetFolder(path)
    
    For Each file In folder.Files
        ' 簡易的なワイルドカード判定
        If file.Name Like Replace(fileName, "*", "?*") Then
            col.Add file.Path
        End If
    Next
    
    Set GetFileList = col
End Function

' **
' Function: GetAutoCADVersion
' Description: 現在実行中のAutoCADのバージョン番号を返す (DBX用)
' **
Private Function GetAutoCADVersion() As String
    ' AutoCADのバージョンに応じて、ここを調整するか、
    ' もしくは Application.Version を利用して動的に取得するロジックを実装する
    ' 例: AutoCAD 2024 なら "24.3"
    GetAutoCADVersion = Application.Version
End Function

4. アーキテクトの視点:運用における極限の知見

このコードを実戦投入するにあたり、シニアエンジニアが留意すべき「真の課題」が3点ある。

I. メモリの「明示的解放」の重み

VBAのガベージコレクションは、COMオブジェクトに対しては必ずしも即時的ではない。`Set dbxDoc = Nothing` をループの各ステップで実行することは、単なる作法ではなく、「メモリの枯渇を防ぎ、長時間稼働させるための生存戦略」である。これを怠ると、数千ファイルの途中で `Out of Memory` エラーに遭遇することになる。

II. エラーハンドリングの階層化

`On Error Resume Next` は諸刃の剣だ。本実装では、ファイルオープン失敗やDBX生成失敗といった「致命的なエラー」を個別にキャッチし、そのファイルをスキップして次のファイルへ進む「回復力(Resilience)」を持たせている。システム管理者は、エラーが発生したファイル名をログに残し、後で手動リカバリできる設計にしなければならない。

III. バージョン互換性の壁

ObjectDBXは、AutoCADのバージョンに極めて敏感だ。`ObjectDBX.AxDbDocument.24.3` のように、バージョン番号を動的に指定する必要がある。レガシーな環境(AutoCAD 2010など)を保守する場合、実行環境のバージョンを `Application.Version` から取得し、適切なプロバイダーを呼び出すロジックを組み込むことが、プロフェッショナルの仕事だ。

結論

図面データの操作を「描画」の文脈から「データ処理」の文脈へと昇華させること。それこそが、自動化エンジニアに求められる真の能力である。ObjectDBXと正規表現をマスターしたとき、君はもはや図面という迷宮に翻弄されることはない。君自身が、その迷宮を支配する管理者となるのだ。

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