AutoCAD VBAの深淵:テキスト属性一括置換に見る「最適化」の美学
AutoCADのAPIを叩く際、多くの初心者は「動けばいい」という幻想に耽る。しかし、数万件のエンティティが混在する巨大な図面を開いた瞬間にアプリが凍結し、メモリリークでシステムが悲鳴を上げる経験をした者は知っているはずだ。「コードの量」ではなく「オブジェクトのライフサイクル」を制御することこそが、真のエンジニアの仕事であるということを。
今回は、テキスト(Text)とMTextの属性一括変更という、一見ありふれたタスクを題材に、AutoCAD VBAの最適化手法を伝授する。
—
1. なぜ「単純なループ」が死を招くのか
VBAでエンティティを操作する際、最も避けるべきは「不必要なオブジェクトの参照保持」と「再描画(Regen)の過剰な呼び出し」だ。特にActiveDocument内の全エンティティを走査する際、イテレータを適切に処理しなければ、AutoCADのCOMインターフェースは容赦なくメモリを食いつぶす。
また、`TextStyle`を動的に変更する際は、スタイルテーブル(`AcadTextStyles`)へのアクセスと、図面上の全エンティティの更新タイミングを切り分けるのが鉄則だ。
—
2. 鋼鉄のコード:高速・安全な属性一括変換ロジック
以下に示すのは、単なるスクリプトではない。大規模図面での安定稼働を前提とした、実務直結型のアーキテクチャである。
Option Explicit
‘ メモリ管理を徹底するためのメインルーチン
Public Sub OptimizeTextAttributes()
Dim doc As AcadDocument
Dim ent As AcadEntity
Dim ss As AcadSelectionSet
Set doc = ThisDrawing
‘ 1. セレクションセットの初期化(既に存在する場合は削除して再定義)
On Error Resume Next
Set ss = doc.SelectionSets.Add(“TextSelection”)
If Err.Number <> 0 Then
Set ss = doc.SelectionSets.Item(“TextSelection”)
ss.Clear
End If
On Error GoTo 0
‘ 2. フィルタ設定: TextとMTextのみを抽出(パフォーマンス向上の要)
Dim fType(0) As Integer: fType(0) = 0
Dim fData(0) As Variant: fData(0) = “TEXT,MTEXT”
ss.Select acSelectionSetAll, , , fType, fData
‘ 3. トランザクションに近い感覚での一括更新
Dim txtObj As AcadText
Dim mtxtObj As AcadMText
doc.Utility.Prompt vbCrLf & “処理を開始しました…”
For Each ent In ss
If TypeOf ent Is AcadText Then
Set txtObj = ent
txtObj.Height = 5.0 ‘ 例: 高さ5.0
txtObj.StyleName = “Standard” ‘ スタイル適用
txtObj.Update
ElseIf TypeOf ent Is AcadMText Then
Set mtxtObj = ent
mtxtObj.Height = 5.0
mtxtObj.Update
End If
Next ent
‘ 4. 明示的なメモリ解放とクリーンアップ
ss.Delete
Set ss = Nothing
doc.Utility.Prompt vbCrLf & “処理完了。最適化済み。”
End Sub
—
3. シニアエンジニアが押さえるべき「極限の知見」
① オブジェクトの明示的解放(Dispose)
VBAはガベージコレクションを搭載しているが、COMオブジェクトに関しては別だ。`Set ss = Nothing` を行うだけでは不十分な場合がある。特に大規模図面では、`ss.Delete` を確実に呼び出し、AutoCAD側のメモリスタックからセレクションセットを完全に解放せよ。
② Windows APIとの連携:進捗表示
数万件の処理を行う場合、AutoCADの画面は「フリーズした」ように見える。ユーザーの不安を払拭するため、`User32.dll` の `Sleep` を使うのではなく、`DoEvents` を適切に配置し、ステータスバーへ進捗状況を出力させるのがプロの作法だ。
③ レガシー環境の保守:フォント名とスタイルの乖離
現場の古い図面では、`TextStyle`が未定義のままフォントだけが指定されているケースが多々ある。コード内で `StyleName` を指定する前に、そのスタイルが `ThisDrawing.TextStyles` コレクションに存在するかをチェックする関数を噛ませる。存在しない場合のフォールバック処理こそが、システム管理者の矜持である。
—
結論:コードは「対話」である
自動化とは、ただの作業の代替ではない。AutoCADという巨大なエンジンの内部構造を理解し、その作法に合わせて最適に動かしてやることだ。
今回紹介したコードは、あくまで「基礎」に過ぎない。君たちが担当する図面のクセや、企業標準のテンプレートに合わせて、適宜 `Error Handling` を強化し、ログ出力機能を実装せよ。
「なぜ動くのか」を知り、「なぜ止まるのか」を予測できるエンジニアだけが、AutoCADの真の力を引き出せる。 健闘を祈る。
