【テクニカル・上級編】【上級プロフェッショナル向け】ObjectDBXと正規表現を用いた「図面を開かない」全画層名の一括置換と保存 – AutoCAD VBA解析バイブル

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

データベースを「開かない」という選択:ObjectDBXと正規表現による図面一括変換の極致

エンジニアリングの現場において、数千枚の図面を抱えるプロジェクトの管理は、もはや「作業」ではなく「計算資源の制御」へと昇華される。

例えば、設計基準の変更に伴い、全図面の画層(Layer)命名規則を一斉に変更しなければならない局面を想定してほしい。愚直なエンジニアは、`Documents.Open` を用い、GUIを介して一枚ずつ図面を起動し、画層名を書き換え、保存して閉じるというルーチンを組むだろう。しかし、それはプロフェッショナルの仕事ではない。その手法は、AutoCADの描画エンジン、LISPの自動実行、ダイアログのポップアップ、そして膨大なメモリ消費という「重すぎるオーバーヘッド」をすべて引き受けてしまうからだ。

我々が目指すべきは、図面を「見る」ことではなく、図面という「データベースを操作する」ことである。本稿では、AutoCADのバックグラウンド・データベース・アクセス・インターフェースである ObjectDBX と、複雑な文字列操作を完遂する 正規表現 (RegExp) を組み合わせ、極限まで低レイヤに近い状態で図面を書き換える、真の自動化アーキテクチャを解説する。

1. 概念の転換:Document vs. ObjectDBX

まず、我々が扱うオブジェクトの「重み」を理解せよ。

通常の `Document` オブジェクトは、AutoCADのGUI、ビューポート、表示エンジン、そしてユーザーインターフェースに関連付けられた巨大なコンテナである。これを開くことは、一つの「世界」を起動することに等しい。

対して ObjectDBX は、AutoCADの描画機能を完全に切り離し、DWGファイルのデータ構造(データベース)に直接アクセスするための軽量なインターフェースである。GUIを介さないため、メモリ消費は劇的に抑えられ、処理速度は `Documents.Open` と比較して桁違いに高速である。

しかし、ObjectDBXは「生」のデータに触れる。エラーハンドリングとオブジェクトのライフサイクル管理を誤れば、AutoCAD自体がメモリリークを起こし、ゾンビプロセスとしてシステムを占拠することになる。

2. 文字列操作の武器:VBScript.RegExp

画層名の置換は、単なる `Replace` 関数では到底太刀打ちできない。
「`A-WALL-01` を `ARCH_WALL_01` に変える」といった単純なものであれば良いが、実務では「接頭辞が `OLD_` で始まり、その後に数字が続く画層を、`NEW_` に置換し、かつ数字の桁数を揃える」といった複雑なパターンが要求される。

ここで投入するのが `VBScript.RegExp` である。VBA標準の `Like` 演算子とは比較にならない柔軟性と、正規表現エンジンによる高速なパターンマッチングを提供してくれる。

3. 実装:プロフェッショナル・スクリプト

以下に、ObjectDBXを用いた高速一括置換のコア・ロジックを示す。このコードは、Late Binding(遅延結合)を採用しており、AutoCADのバージョンに依存しにくい堅牢な設計としている。

' ==============================================================================
' Module: LayerMassRenamer
' Description: ObjectDBXを用いた、図面を開かない画層名一括置換エンジン
' Author: Chief Architect
' ==============================================================================

Option Explicit

Public Sub ExecuteMassLayerRename()
    Dim targetFolder As String
    Dim fileName As String
    Dim dbxDoc As Object
    Dim regExp As Object
    Dim acadApp As Object
    Dim dwgVersion As String
    
    ' --- 設定セクション ---
    targetFolder = "C:\Project\Drawings\BatchProcess\" ' 対象ディレクトリ
    dwgVersion = "24.3" ' AutoCAD 2021以降のObjectDBXバージョン (要確認)
    ' ---------------------

    On Error GoTo ErrorHandler

    Set acadApp = ThisDrawing.Application
    
    ' 正規表現オブジェクトの初期化
    Set regExp = CreateObject("VBScript.RegExp")
    With regExp
        .Global = True
        .IgnoreCase = True
        .Pattern = "^OLD_([0-9]+)" ' 例: OLD_123 をターゲットにするパターン
    End With

    ' ファイル探索開始
    fileName = Dir(targetFolder & "*.dwg")

    Do While fileName <> ""
        Debug.Print "Processing: " & fileName

        ' ObjectDBXのインスタンス生成 (Late Binding)
        ' バージョン指定により、適切なAxDbDocumentを呼び出す
        Set dbxDoc = CreateObject("ObjectDBX.AxDbDocument." & dwgVersion)
        
        ' 図面データベースをバックグラウンドでロード
        dbxDoc.Open (targetFolder & fileName)

        ' 画層ループの実行
        ProcessLayers dbxDoc, regExp

        ' 変更を保存して閉じる
        dbxDoc.SaveAs (targetFolder & fileName)
        
        ' 【重要】オブジェクトの明示的解放
        ' これを怠ると、ループ内でメモリが指数関数的に増大する
        Set dbxDoc = Nothing
        
        fileName = Dir()
    Loop

    MsgBox "全工程が完了しました。", vbInformation
    Exit Sub

ErrorHandler:
    MsgBox "致命的なエラーが発生しました: " & Err.Description, vbCritical
    ' リソース解放を試みる
    If Not dbxDoc Is Nothing Then Set dbxDoc = Nothing
    Set regExp = Nothing
End Sub

''' <summary>
''' 図面データベース内の画層を走査し、正規表現に基づき置換を行う
''' </summary>
Private Sub ProcessLayers(ByRef dbxDoc As Object, ByRef regExp As Object)
    Dim lay As Object
    Dim oldName As String
    Dim newName As String
    Dim match As Object
    
    ' Layerコレクションを反復
    ' ObjectDBXでは、コレクションの操作中に要素を追加・削除すると不安定になるため
    ' 既存のプロパティを書き換える手法を採る
    For Each lay In dbxDoc.Layers
        oldName = lay.Name
        
        ' 正規表現によるマッチング
        If regExp.Test(oldName) Then
            ' 置換ロジックの構築
            ' 例: OLD_123 -> NEW_000123 (桁合わせの例)
            newName = regExp.Replace(oldName, "NEW_$1")
            
            ' 実際にはここで、置換後の名前が既に存在しないか等のチェックが必要
            On Error Resume Next
            lay.Name = newName
            If Err.Number <> 0 Then
                Debug.Print "Error renaming " & oldName & " to " & newName & ": " & Err.Description
                Err.Clear
            End If
            On Error GoTo 0
        End If
    Next lay
End Sub

4. アーキテクトの視点:極限の最適化と保守

このコードを実戦投入するにあたり、以下の3点を深く理解しておく必要がある。

① オブジェクトのライフサイクル管理 (Memory Management)

VBAにおける `Set obj = Nothing` は、単なる作法ではない。特にObjectDBXのような低レイヤ・インターフェースでは、COMオブジェクトの参照カウンタが適切に減少しない限り、AutoCADのプロセス内に「解放不可能なメモリ領域」が蓄積され続ける。ループの内部で必ず `Set dbxDoc = Nothing` を実行し、各ファイルの処理が終わるたびにメモリをクリーンアップせよ。

② バージョン互換性の罠

`CreateObject(“ObjectDBX.AxDbDocument.XX.X”)` の `XX.X` 部分は、使用しているAutoCADのバージョンに厳密に依存する。

  • AutoCAD 2024 $\rightarrow$ `24.3`
  • AutoCAD 2023 $\rightarrow$ `24.2`

これを動的に取得するロジックを組み込むか、あるいは実行環境のバージョンを事前に特定するプロセスを、システム全体の設計に組み込んでおくべきだ。

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

図面データは「汚い」。壊れたブロック、参照エラー、あるいは読み取り専用属性。これらが一箇所にあるだけで、バッチ処理全体が停止しては意味がない。
`ProcessLayers` 内では `On Error Resume Next` を局所的に使用し、個別の画層名の変更失敗がファイル全体の処理を阻害しないよう、エラーをログに吐き出しつつ、次のステップへ進む「レジリエンス(回復力)」を持たせることが、商用ツールとしての要件である。

結論

ObjectDBXを用いたアプローチは、AutoCAD VBAにおける「破壊的かつ建設的な」手法である。GUIという贅肉を削ぎ落とし、データベースの核心に直接触れることで、我々は圧倒的な処理速度を手に入れる。

しかし、その力は諸刃の剣だ。メモリ管理とエラー制御という、地味で退屈な、しかし極めて重要な基礎の上にのみ、この高速なアーキテクチャは成立する。これこそが、シニアエンジニアが追求すべき「エンジニアリングの本質」である。

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