こんにちは!AutoCAD VBAの世界へようこそ。
マクロの記録ボタンを押して「なんだか動いた!」と感動したのも束の間、自分でコードを書き始めると、こんな壁にぶつかったことはありませんか?
「あれ? さっき描いたはずの図形が、どこにも見当たらない……あっ、レイアウト画面(ペーパー空間)の中に描き出しちゃった!」
AutoCAD VBAにおいて、モデル空間(図面を描く本番のキャンバス)と、レイアウト空間(印刷用の枠組み)の概念を取り違えるミスは、初心者が必ずと言っていいほど通る「最初の関所」です。
今回は、先輩エンジニアである私が、現在ユーザーがどちらの空間を見ているかを鮮やかに判定し、「あらかじめエラーを防ぐ鉄壁のガード句」の書き方を手取り足取り伝授します。ここをクリアすれば、あなたのVBAスキルは一段上のステージに上がりますよ!
—
1. AutoCADの空間(Space)の正体を知ろう
まず、AutoCADの画面の裏側を覗いてみましょう。
私たちが普段図形を描き込む場所には、大きく分けて2つの「空間」が存在します。
1. モデル空間 (`acModelSpace`)
- 実際に線や円、文字を描き込む無限のキャンバス。いわば「現実世界」です。
2. ペーパー空間 (`acPaperSpace`)
- 印刷するために用紙サイズを意識し、モデル空間の景色を「ビューポート」という窓越しに覗き見る場所。いわば「額縁・レイアウトの世界」です。
VBAのコードで何も考えずに `ThisDrawing.ModelSpace.AddLine` などのメソッドを実行すると、AutoCADは「今ユーザーがどこを見ているか」に関わらず、容赦なくモデル空間に図形を追加しようとします。
しかし、もしユーザーがレイアウト画面(ペーパー空間)を開いている状態で、モデル空間に配置するはずの特殊なプログラムを実行してしまったらどうなるでしょう? 図形はモデル空間の奥底に生成され、画面上では「消えた!?」ように見えてしまうのです。これが配置エラーの正体です。
—
2. 魔法のプロパティ `ActiveSpace` とは?
この悲劇を防ぐために用意されているのが、`AcadDocument` オブジェクトが持つ `ActiveSpace` というプログラミティ(プロパティ)です。
これを使うと、「今、ユーザーがモデル空間を見ているのか、それともレイアウト空間を見ているのか」をコードで一瞬で見抜くことができます。
判定に使われる定数は以下の2つです。
- `acModelSpace` (モデル空間アクティブ)
- `acPaperSpace` (レイアウト空間アクティブ)
これらを組み合わせて、「今ペーパー空間にいるなら、処理を中断して警告を出す」というガード句(Guard Clause)を作ってみましょう。
—
3. 実装コード:鉄壁のガード句を取り入れたマクロ
それでは、実際に現場でそのままコピペして使えるサンプルコードを見ていきましょう。
今回は、「選択した空間がモデル空間でなければ、処理を優しくストップする」という安全設計のプロシージャです。
Sub DrawLineWithGuard()
‘ —————————————————————–
‘ テーマ: アクティブ空間を判定し、モデル空間以外での実行を防ぐガード句
‘ —————————————————————–
Dim acadDoc As AcadDocument
Set acadDoc = ThisDrawing
‘ — 【ガード句の核心】現在のアクティブ空間をチェック —
If acadDoc.ActiveSpace <> acModelSpace Then
‘ もしモデル空間でなければ、ユーザーに優しく警告して処理を抜ける
MsgBox “【エラー防止】” & vbCrLf & _
“このマクロは「モデル空間」でのみ実行可能です。” & vbCrLf & _
“モデルタブに切り替えてから再度実行してください。”, _
vbExclamation, “空間エラー”
Exit Sub ‘ ここで処理を強制終了
End If
‘ — 以下、安全が保証されたモデル空間での処理 —
Dim startPoint(0 To 2) As Double
Dim endPoint(0 To 2) As Double
Dim lineObj As AcadLine
‘ 線の始点と終点を設定
startPoint(0) = 0#: startPoint(1) = 0#: startPoint(2) = 0#
endPoint(0) = 100#: endPoint(1) = 100#: endPoint(2) = 0#
‘ 確実にモデル空間へ線を描画
Set lineObj = acadDoc.ModelSpace.AddLine(startPoint, endPoint)
‘ 画面を更新
acadDoc.Regen acAllViewports
MsgBox “モデル空間に正常に線を描画しました!”, vbInformation, “完了”
End Sub
コードの解説ポイント
1. `acadDoc.ActiveSpace <> acModelSpace`
- 「もしアクティブ空間がモデル空間でないならば」という条件式です。`<>` は「等しくない(ノットイコール)」を意味します。
2. `Exit Sub`
- 条件に一致した場合(ペーパー空間にいる場合)、そこでマクロの実行をスパッと終了させます。これにより、予期せぬ場所への誤描画を完全になくすことができます。
3. 安全な描画処理
- ガード句を突破したコードは、「絶対に今モデル空間にいる」というお墨付きをもらっているため、安心して `ModelSpace.AddLine` を実行できます。
—
4. さらに親切なエンジニアを目指すなら(自動切替というアプローチ)
「わざわざユーザーにモデルタブに切り替えさせるのも面倒だな……」と感じる優秀な読者の方へ。
実は、コードの力で強制的にモデル空間に切り替えてから処理を実行するというスマートなアプローチも可能です。
Sub DrawLineAutoSwitch()
Dim acadDoc As AcadDocument
Set acadDoc = ThisDrawing
‘ もしペーパー空間にいたら、強制的にモデル空間へ切り替える!
If acadDoc.ActiveSpace = acPaperSpace Then
acadDoc.ActiveSpace = acModelSpace
End If
‘ この時点で必ずモデル空間にいるため、安心して描画できる
Dim startPoint(0 To 2) As Double: startPoint(0) = 0: startPoint(1) = 0: startPoint(2) = 0
Dim endPoint(0 To 2) As Double: endPoint(0) = 50: endPoint(1) = 50: endPoint(2) = 0
acadDoc.ModelSpace.AddLine startPoint, endPoint
acadDoc.Regen acAllViewports
MsgBox “モデル空間に切り替えて線を描画しました!”, vbInformation
End Sub
この方法であれば、ユーザーがレイアウト画面を開きっぱなしにしていても、プログラムが自動で軌道修正してくれます。運用のスタイルに合わせて、警告で止めるか、自動で切り替えるかを選んでみてください。
—
まとめ
今回は、AutoCAD VBAにおける「空間の取り違え」を防ぐための `ActiveSpace` の判定とガード句の実装方法について解説しました。
- AutoCADにはモデル空間とペーパー空間がある。
- 何も考えずに描画すると、意図しない空間に図形が迷子になる。
- `ActiveSpace` プロパティで現在の空間を判定し、`Exit Sub` や自動切替でコントロールするのがプロの技。
ここをクリアできれば、あなたの作るVBAマクロは、エラーに強く、ユーザーにも優しい「実用的なプロツール」へと進化します。
ぜひ、ご自身の開発環境でも試してみてくださいね。次回の解説もお楽しみに!
