【テクニカル・上級編】【初心者向け】AcadDocument.Utility.AngleFromPointで「2点間の角度」を取得し、テキストの回転角に自動適用する – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD VBAを掌握する極限の知見:2点間の幾何学ベクトルからテキスト自動整列を極める

AutoCAD VBA(Visual Basic for Applications)の領域において、表面的なオブジェクト操作の羅列は、実務の現場では何の意味も持たない。メモリ管理の不全、COMオブジェクトのライフサイクル無視、そして座標変換(UCSとWCS)の無理解は、数千回におよぶループ処理の末にCADを沈黙させ、現場のエンジニアを絶望の淵に追い込む。

今回は、初心者向けと称されながらも、その実、AutoCADの数学的コアとCOMアーキテクチャの基本思想が凝縮されたテーマ「AngleFromPointによる2点間角度の取得とテキストへの自動適用」を、シニアエンジニアおよび社内システム管理者の視座から再定義する。

単に動くコードの提示ではない。背後にあるベクトルの概念、AutoCADデータベースの挙動、そして実務で通用する堅牢なエラーハンドリングまでを網羅した、極限の知見をここに公開する。

—

1. 幾何学の核心:なぜ `AngleFromPoint` なのか

図面内における「傾き」をプログラムに認識させる時、多くの初心者は三角関数(`Atan2`など)を自前で実装しがちだ。しかし、AutoCAD VBAには `AcadUtility` オブジェクトという強力な数学的エンジンが備わっている。

`AngleFromPoint` メソッドは、指定された基点からもう1つの点へ向かうベクトルが、現在のUCS(ユーザー座標系)のX軸正方向となす角度(ラジアン)を瞬時に返す。

ここで重要なのは、「どの座標系(WCS/UCS)で計算されているか」という点だ。実務の現場では、ビューポートごとにUCSが回転しているカオスな図面が日常茶飯事である。この本質を理解せずにコードを書くと、他の人の画面で実行した瞬間にテキストが明後日の方向を向くというバグを生む。

—

2. 実装:堅牢性とメモリ最適化を極めたプロフェッショナルコード

以下のコードは、単に動作するだけでなく、COMオブジェクトの解放、エラーハンドリング、そして実用的な対話型入力を考慮したプロダクションレベルのマクロである。

Option Explicit

‘ ==============================================================================
‘ 処理名: AlignTextByTwoPoints
‘ 概要: ユーザーが指定した2点の傾きを計算し、選択したテキストの回転角に適用する
‘ 著者: チーフアーキテクト
‘ ==============================================================================
Public Sub AlignTextByTwoPoints()
‘ 1. エラーハンドリングの要塞化
On Error GoTo ErrorHandler

Dim acadApp As AcadApplication
Dim acadDoc As AcadDocument
Dim util As AcadUtility

‘ Applicationインスタンスの取得(早期バインディングによるパフォーマンス最大化)
Set acadApp = ThisDrawing.Application
Set acadDoc = ThisDrawing.ActiveDocument
Set util = acadDoc.Utility

‘ 2. ユーザーからの入力取得(2点間のベクトル定義)
Dim ptBase As Variant
Dim ptTarget As Variant
Dim angleRad As Double

‘ 画面上のクリックから点を取得(CAD標準のプロンプトを使用)
ptBase = util.GetPoint(, vbCrLf & “基準となる始点を指定してください: “)
ptTarget = util.GetPoint(ptBase, vbCrLf & “方向を示す終点を指定してください: “)

‘ 3. 角度の算出 (AngleFromPointの核心)
‘ ※注意: ptBase と ptTarget は Variant型(3要素の倍精度実数配列)として返される
angleRad = util.AngleFromPoint(ptBase, ptTarget)

‘ 4. 対象となるテキストエンティティの選択
Dim acadObj As AcadEntity
Dim pickPt As Variant

util.GetEntity acadObj, pickPt, vbCrLf & “角度を適用するテキスト(文字またはマルチテキスト)を選択: ”

‘ 5. オブジェクトの型チェック(Typeof と SafeCast の思想)
If TypeOf acadObj Is AcadText Then
Dim txtObj As AcadText
Set txtObj = acadObj
txtObj.Rotation = angleRad
‘ 変更を強制的にドキュメントに反映
txtObj.Update
MsgBox “テキストの回転角を ” & Format(angleRad (180 / 3.14159265358979), “0.00”) & ” 度に更新しました。”, vbInformation, “自動化システム”

ElseIf TypeOf acadObj Is AcadMText Then
Dim mtxtObj As AcadMText
Set mtxtObj = acadObj
mtxtObj.Rotation = angleRad
mtxtObj.Update
MsgBox “マルチテキストの回転角を更新しました。”, vbInformation, “自動化システム”

Else
MsgBox “選択されたオブジェクトはテキストではありません。”, vbExclamation, “処理中断”
End If

CleanUp:
‘ 6. COMオブジェクトの明示的解放(メモリリークの完全防止)
‘ ※VBAのガーベージェネレーションを過信せず、スコープを抜ける前に破棄する
Set txtObj = Nothing
Set mtxtObj = Nothing
Set acadObj = Nothing
Set util = Nothing
Set acadDoc = Nothing
Set acadApp = Nothing
Exit Sub

ErrorHandler:
‘ ユーザーがESCキーでキャンセルした場合のエラー(番号: -2147352567 または同等)をハンドリング
If Err.Number <> 0 Then
If Err.Number <> -2147467259 Then ‘ 通常のキャンセル以外のエラー
‘ 必要に応じてログ出力等
End If
End If
Resume CleanUp
End Sub

—

3. シニアエンジニアが解説するコードの急所

A. 型安全性と `TypeOf` 演算子

AutoCADの `GetEntity` は、図面内のあらゆるオブジェクト(線分、円、ハッチング等)を `AcadEntity` として取得する。これを安易に特定の型へキャスト(`Dim txt As AcadText` の後に代入等)すると、実行時エラー `Type mismatch` (Error 13) が発生する。
コード内で行っているように、`TypeOf … Is …` による厳密な型ガードを行うことが、プラント設計や大規模図面を扱うシステムにおける絶対の鉄則である。

B. ラジアンと度数の罠

AutoCADの内部計算、およびオブジェクトのプロパティ(`Rotation` など)はすべてラジアン(Radian)で保持される。しかし、人間のエンジニアは「度(Degree)」で思考する。
ログ出力やデバッグ時には、$\frac{180}{\pi}$ による変換を挟むか、自作のヘルパー関数(`RadToDeg` / `DegToRad`)を用意しておくことが、保守性を飛躍的に高める鍵となる。

C. COMオブジェクトのライフサイクルとメモリマネジメント

VBAの裏側では、AutoCADのC++コア(ObjectARX)とCOMインターフェースを介して通信が行われている。
スクリプト終了時に `Set xxx = Nothing` を明示的に行わない場合、特に巨大な図面やループ処理を伴うバッチ処理において、COMの参照カウントが適切にデクリメントされず、ExcelやAutoCADがメモリリーク(メモリ肥大化)を起こす。「取得した順序とは逆に、参照を完全に断ち切る」。これがプロフェッショナルの作法である。

—

4. システム間連携・レガシー保守への応用

この `AngleFromPoint` による角度取得ロジックは、単一のテキスト回転だけに留まらない。

  • 外部データベース(Excel / Access / SQL Server)からの属性同期:

配管の方向ベクトルを本プログラムで自動計算し、その角度データを外部DBのアイソメ図情報と紐付けて自動更新する。

  • ブロック参照(`AcadBlockReference`)への拡張:

文字だけでなく、バルーン(引き出し線付き番号)や方向性を持つシンボルブロックの挿入角度(`Rotation` プロパティ)の動的制御へと、そのままアルゴリズムをスケールさせることが可能だ。

—

総括

AutoCAD VBAにおける基礎とは、決して「お絵描きマクロの初歩」ではない。そこにあるのは、座標変換、メモリ管理、そして厳密な型システムという、あらゆるモダン開発に通じるエンジニアリングの縮図である。

この `AngleFromPoint` を起点としたベクトルの掌握こそが、あなたの手動作業を「完全自動化された堅牢なエンジニアリングパイプライン」へと昇華させる第一歩となる。コードの細部に宿る神を恐れず、しかし確実に、日々の作図自動化を極めてほしい。

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