こんにちは!AutoCAD VBAの世界へようこそ。
マクロの記録ボタンを押して「動いた!」と喜んでいた時期を通り越し、「いよいよ本格的な自動化ツールを作りたい!」と一歩を踏み出したあなたへ。
今日は、AutoCAD VBAのエンジニアなら誰もが最初に躓き、そしてプロとアマの決定的な分水嶺となる超重要ポイントをお伝えします。
それが、`ThisDrawing` と `AcadApplication.ActiveDocument` の決定的な違いと、その使い分けの罠です。
ここをクリアすれば、複数図面を同時に開いても暴走しない、堅牢でプロフェッショナルなコードが書けるようになりますよ。さあ、一緒に本質を紐解いていきましょう!
—
1. そもそもAutoCAD VBAの「ドキュメント参照」とは?
AutoCADは、複数の図面(DWGファイル)を同時に開いて作業できるマルチドキュメント環境です。
VBAでコードを書くとき、私たちはコンピュータに対して「今から、どの画面(図面)の線を描いたり消したりすればいいの?」と指示を出してあげる必要があります。
この「操作対象の図面を指定する手段」として登場するのが、今回主役となる `ThisDrawing` と `AcadApplication.ActiveDocument` です。
文字面が似ているので「どっちを使っても同じでしょ?」と思われがちですが、これが大間違いの罠なのです。
—
2. 決定的な違い:それぞれの正体を知る
まずは、それぞれのオブジェクトが何を指しているのかを、キャラクターに例えてスッキリ理解しましょう。
① `ThisDrawing`(この図面)
- 正体: コードが書かれているVBAプロジェクトを宿している「親の顔」のような図面。
- 特徴: 複数図面を開いていようとも、このコードが存在するファイル(.dvb や図面内のVBA)と運命を共にします。外野がどう変わろうと、私は私。ブレません。
② `AcadApplication.ActiveDocument`(現在アクティブな図面)
- 正体: ユーザーが今まさに画面の最前面でクリックして「操作している現在の画面」。
- 特徴: ユーザーの操作次第で、コロコロと対象が変わります。移り気なアイドル的存在です。
—
3. 【実録】なぜ、ActiveDocumentを使うと現場で事故が起きるのか?
ここで、現場でよくある恐ろしい事故のストーリーをお話します。
あなたは、A図面の集計を行うための素晴らしいマクロを作りました。そのコードの中で `AcadApplication.ActiveDocument` を使って図面オブジェクトを取得していました。
1. あなたはマクロを実行しました。
2. マクロが処理を行っている、ほんの一瞬の隙に、ユーザー(あるいはあなた自身)がマウスで別の「B図面」をクリックして画面を切り替えてしまいました。
3. 【悲劇】 VBAは「おっ、いまアクティブなのはB図面に変わったぞ!」と勘違いし、B図面に対して残酷なデータ書き換えや削除を実行してしまいました。A図面はボロボロになり、B図面は関係ないデータで汚染されます。
……ゾッとしましたか?
これが、複数図面を扱う現場で `ActiveDocument` を安易に使うときに潜む最大の罠です。
—
4. 状況に応じた「正しい使い分け」の黄金律
では、私たちはどのように使い分ければいいのでしょうか? 結論から言います。
- 基本はすべて `ThisDrawing` を使え!
- `ActiveDocument` は、「今ユーザーが開いている画面を相手に何かしたい」という極めて限定的な場面(あるいは標準モジュールでのエントリーポイント)でのみ使え!
これをさらに深掘りするために、コードの配置場所による挙動の違いを見てみましょう。
パターンA:図面内VBA(図面ファイルにマクロが埋め込まれている場合)
この場合、迷わず `ThisDrawing` を使ってください。
Sub DrawCircleInThisDrawing()
‘ 【推奨】コードが属している図面の原点に円を描く
‘ ユーザーがどの画面を見ていようとも、安全にこの図面に描画されます
Dim circObj As AcadCircle
Dim centerPoint(0 To 2) As Double
Dim radius As Double
centerPoint(0) = 0#: centerPoint(1) = 0#: centerPoint(2) = 0#
radius = 50.0
Set circObj = ThisDrawing.ModelSpace.AddCircle(centerPoint, radius)
MsgBox “この図面への円の作図が完了しました!”, vbInformation
End Sub
パターンB:外部標準モジュール(.dvbやグローバルマクロ)から操作する場合
もし、あなたがすべての図面から呼び出せる共通のツールを作っている場合、`ThisDrawing` は使えません(どの図面のことを指しているか分からないため)。
このときは `ActiveDocument` を使わざるを得ませんが、「変数に代入してロックする」という防衛策をとります。
Sub ProcessActiveDrawingSafely()
‘ 宣言と同時に、その瞬間の「アクティブな図面」を変数に固定(キャプチャ)する
Dim targetDoc As AcadDocument
Set targetDoc = AcadApplication.ActiveDocument
‘ 以降は ActiveDocument ではなく、変数 targetDoc を操作する!
‘ これにより、途中でユーザーが画面を切り替えても、処理対象がブレません。
MsgBox “現在処理している図面名: ” & targetDoc.Name, vbInformation
‘ 例:レイヤ一覧を取得してイミディエイトウィンドウに出力
Dim lay As AcadLayer
For Each lay In targetDoc.Layers
Debug.Print lay.Name
Next lay
Set targetDoc = Nothing
End Sub
—
5. まとめ:プロのエンジニアへの第一歩
いかがでしたでしょうか?
`ThisDrawing` と `AcadApplication.ActiveDocument` の違いは、単なる書き方の好みの問題ではありません。「意図しないデータ破損を防ぎ、ツールの信頼性を担保するための防衛プログラミングの基礎」そのものです。
- 自信を持って「この図面を処理するんだ」と言えるときは `ThisDrawing`
- グローバルなツールで、今目の前にある画面を捉えたいときは `AcadApplication.ActiveDocument`(ただし変数に即座に退避させる)
この原則を守るだけで、あなたの書くAutoCAD VBAコードの品質は跳ね上がります。エラーに怯える日々から脱却し、同僚から「お、頼りになるな!」と言われる自動化ライフを楽しみましょう。
ここをクリアしたあなたなら、もうAutoCAD VBAの基礎はバッチリです。次のステップへ進みましょう!
