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

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

AutoCAD VBAの深淵へ:ObjectDBXと正規表現で実現する「図面を開かない」超高速一括置換術

こんにちは。今日も図面データの海と格闘していますか?

「数千枚ある図面の、特定の製品番号や日付をすべて書き換えなければならない……」
「でも、一つずつ図面を開いていたら、日が暮れるどころか日が昇ってしまう」

もしあなたが今、そんな絶望的な状況に直面しているとしたら、おめでとうございます。あなたは今、「マクロの記録」という初級者の殻を破り、真の自動化エンジニアへと進化するための境界線に立っています。

今日は、AutoCAD VBAにおける最強の武器の一つ、「ObjectDBX」と、文字列操作の魔術師「正規表現(Regex)」を組み合わせた、プロフェッショナル向けの極限のテクニックを伝授します。

この記事を読み終える頃には、あなたは「図面を開く」という概念そのものを書き換えているはずですよ。

1. なぜ「図面を開いてはいけない」のか?(オブジェクトのライフサイクル)

まず、基本中の基本、しかし多くのエンジニアが見落としている「重み」の話をしましょう。

通常、VBAで図面を操作するとき、私たちは `Documents.Open` メソッドを使います。これは、AutoCADという巨大なアプリケーションが、図面データ(DWG)を読み込み、グラフィックスエンジンを起動し、ユーザーインターフェース(UI)を構築し、メモリ上に展開するプロセスです。

これを1,000回繰り返すとどうなるか?

  • メモリ消費の爆発: 図面を開くたびにメモリが積み上がり、最終的にAutoCADがクラッシュします。
  • 時間の浪費: 画面を描画するための処理(グラフィックスの更新)に膨大な時間が奪われます。

ここで登場するのが ObjectDBX です。

ObjectDBXとは何か?

ObjectDBXは、AutoCADの「データベース(図面の中身)」だけに直接アクセスするための軽量なインターフェースです。「画面には一切映さない。中身のデータだけを、裏側で高速に読み書きする」。いわば、レストランのホールで食事をするのではなく、厨房に直接入り込んで食材(データ)だけを入れ替えるようなものです。

これを使うことで、処理速度は数十倍、メモリ消費は劇的に抑えられます。

2. 正規表現(Regex)という名の「精密なメス」

次に、検索・置換の精度についてです。

単純な `Replace` 関数では、「製品番号 `PN-12345` を `NEW-12345` に変えたい」という時、もし図面内に `PN-99999` があったらどうしますか? あるいは、日付の形式が `2023/10/27` だったり `2023-10-27` だったりする場合、単純な置換では対応できません。

ここで正規表現(Regular Expressions)の出番です。
「`PN-` の後に続く4桁の数字」といったパターンを指定することで、曖昧なデータの中から、狙ったものだけをピンポイントで撃ち抜くことができます。

3. 実装:全注釈テキストの一括検索・置換エンジン

それでは、魂を込めたコードを見ていきましょう。
このコードを使用するには、VBAエディタのメニューから [ツール] -> [参照設定] を開き、「Microsoft VBScript Regular Expressions 5.5」 にチェックを入れてください。ここを忘れると、魔法は発動しません。

' ==============================================================================
' プログラム名: UltraFastTextReplacer
' 概要: ObjectDBXを使用し、図面を開かずに正規表現でテキストを一括置換する
' 開発者: あなたの成長を願うシニアアーキテクト
' ==============================================================================

Option Explicit

Sub BatchReplaceTextWithObjectDBX()
    Dim fso As Object
    Dim folderPath As String
    Dim file As Object
    Dim dbxDoc As Object
    Dim regex As RegExp
    Dim matches As MatchCollection
    Dim match As Match
    Dim targetPattern As String
    Dim replacementString As String
    
    ' --- 設定エリア ---
    ' 置換対象のフォルダパス(末尾に \ を忘れずに)
    folderPath = "C:\Work\DrawingData\"
    
    ' 正規表現パターン(例: PN-から始まる5桁の数字)
    targetPattern = "PN-\d{5}"
    
    ' 置換後の文字列(例: 新しい製品コード。ここではパターンに依存せず固定値にする例)
    ' ※動的な置換を行いたい場合は、MatchオブジェクトのIndexを利用してロジックを組む
    replacementString = "NEW-PROD"
    ' ------------------

    ' 正規表現オブジェクトの初期化
    Set regex = New RegExp
    With regex
        .Pattern = targetPattern
        .Global = True           ' 全ての一致箇所を対象にする
        .IgnoreCase = True       ' 大文字小文字を区別しない
    End With

    ' ファイルシステムオブジェクトの作成
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    If Not fso.FolderExists(folderPath) Then
        MsgBox "指定されたフォルダが見つかりません。", vbCritical
        Exit Sub
    End If

    ' フォルダ内のファイルをループ
    For Each file In fso.GetFolder(folderPath).Files
        ' DWGファイルのみを対象とする
        If LCase(fso.GetExtensionName(file.Path)) = "dwg" Then
            
            Debug.Print "Processing: " & file.Name
            
            On Error Resume Next
            ' ObjectDBXのインスタンスを作成(現在のAutoCADのバージョンに合わせる)
            ' GetObjectDBXは、現在のドキュメントのDBXサーバーを介して取得するのが最も安全です
            Set dbxDoc = ThisDrawing.ObjectDBXServer.GetObjectDBX(file.Path)
            
            If Err.Number <> 0 Then
                Debug.Print "  [Error] ファイルを開けませんでした: " & file.Name
                Err.Clear
                GoTo NextFile
            End If
            On Error GoTo 0

            ' --- 図面内データの走査 ---
            ' ModelSpace内のエンティティをループ
            Dim ent As Object
            For Each ent In dbxDoc.ModelSpace
                ' Text または MText かどうかを判定
                If ent.ObjectName = "AcDbText" Or ent.ObjectName = "AcDbMText" Then
                    
                    ' 正規表現でパターンに一致するかチェック
                    If regex.Test(ent.TextString) Then
                        ' 置換実行
                        ent.TextString = regex.Replace(ent.TextString, replacementString)
                        ' 変更があった場合、フラグを立てて保存準備
                    End If
                    
                End If
            Next ent

            ' --- 保存処理 ---
            ' 変更があった場合のみ保存(メモリ節約のため、必要に応じてロジックを追加してください)
            dbxDoc.SaveAs file.Path
            Debug.Print "  [Success] 保存完了"
            
            ' ObjectDBXの解放(重要:これを怠るとメモリリークの原因になります)
            Set dbxDoc = Nothing
        End If

NextFile:
    Next file

    MsgBox "すべての処理が完了しました。詳細はイミディエイトウィンドウを確認してください。", vbInformation
End Sub

4. プロフェッショナルのための「極限の知見」

コードをコピペして動かすだけでは、あなたはまだ「使い手」に過ぎません。エンジニアとして一歩先に行くために、以下の3つのポイントを脳に刻んでください。

① メモリ解放の儀式 (`Set obj = Nothing`)

ObjectDBXは非常に強力ですが、強力ゆえに扱いに注意が必要です。ループの中で `Set dbxDoc = Nothing` を忘れると、解放されなかったオブジェクトがメモリを食いつぶし、数分後にはAutoCADが沈黙します。「使い終わったら、必ず手放す」。これはオブジェクト指向における鉄則です。

② エラーハンドリングの重要性

大量のファイルを処理する場合、必ず「壊れたDWG」や「読み取り専用のファイル」に遭遇します。`On Error Resume Next` を使う際は、どこでエラーが起きたのかを `Debug.Print` などでログに残す癖をつけてください。エラーを無視するのではなく、「エラーを管理する」のがプロの仕事です。

③ バージョン互換性の罠

ObjectDBXは、実行しているAutoCADのバージョンに依存します。古いバージョンのAutoCADで作成された、非常に特殊なエンティティが含まれている場合、稀にエラーを吐くことがあります。実運用前には、必ずテスト用のコピーデータで検証を行ってください。

結びに:次は、あなた自身のツールを作ろう

ここまで読んでくれたあなたは、もう「マクロの記録」ボタンを連打していた頃の自分とは別人です。

「図面を開かずに操作する」「パターンで検索する」「メモリを管理する」。
これらの概念を理解したことで、あなたの武器は飛躍的に増えました。

最初はエラーが出るかもしれません。正規表現のパターンが上手くいかないかもしれません。でも、それでいいんです。エラーと格闘し、コードを書き換えるそのプロセスこそが、あなたを伝説的なエンジニアへと押し上げる唯一の道なのですから。

さあ、次はどんな自動化に挑戦しますか? 応援していますよ。

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