こんにちは!AutoCAD VBAの世界へようこそ。
マクロの記録ボタンを押すだけの自動化から一歩抜け出し、「自分の手で図面を意のままに操りたい」と願うあなたにとって、今日は記念すべき一日になりますよ。
ここをクリアすれば、AutoCAD VBAの基本はバッチリです。一緒にエンジニアとしての階段を駆け上がっていきましょう!
—
なぜ、ハッチングの自動化でつまずくのか?
実務で図面を修正しているとき、こんなストレスを感じたことはありませんか?
「境界線の四角形をストレッチで広げたのに、中のハッチングが取り残されてスカスカになっている……!」
人間なら、古いハッチングを削除して、新しい境界線を選び直して……と手作業で修正できますが、これをVBAでやろうとすると、多くの人が最初の壁にぶつかります。
「ハッチングの形を変えるって、一体どういうこと?」
「オブジェクトを新しく作り直さなきゃいけないの?」
いいえ、その必要はありません。AutoCAD VBAの心臓部である「オブジェクトモデル」と「AppendLoopメソッド」の正しい使い方を知っていれば、既存のハッチングを生き返らせ、新しい形状へ鮮やかに追従させることが可能なのです。
今日はその極意を、優しく、そして深く伝授します。
—
AutoCAD VBAの根幹:AcadApplicationとAcadDocument
コードを書く前に、私たちが操作している世界(AutoCADのメモリ空間)の構造を軽く整理しておきましょう。
1. `AcadApplication` (最上位の神様)
- AutoCADというソフトそのものです。画面の裏側ですべてを統括しています。
2. `AcadDocument` (今、目の前にある図面)
- アクティブな図面ファイルです。線を描いたり、文字を入れたりする「キャンバス」そのものですね。
そして、そのキャンバスの中にいるのが、線(`AcadLine`)や文字(`AcadText`)、そして今回主役となるハッチング(`AcadHatch`)たちです。
ハッチングというのは、実は見た目以上に複雑な構造をしています。外側の「境界(ループ)」があって、その内側を塗りつぶしている。つまり、形状を変えるということは「古い境界の輪郭(ループ)を捨てて、新しく生まれ変わらせる」というライフサイクルをコードで指示してあげる必要があるのです。
—
核心に迫る:AppendLoopメソッドによる形状追従
ハッチングの形を再定義するフローは、実はとてもシンプルです。
1. 対象となる `AcadHatch` オブジェクトを特定する。
2. 既存の境界ループを一度すべて消去する(`DeleteLoop`)。
3. 新しい境界となる図形(ポリラインや線の配列)を `AppendLoop` メソッドで追加する。
4. 最後に `Evaluate` メソッドを呼び出し、AutoCADに再計算(描画更新)を命じる。
これだけです。言葉で聞くと難しそうですが、実際のコードを見れば「なーんだ、こういうことか!」と腑に落ちるはずです。
—
【実践】図面内の全ハッチング境界を再定義するマクロ
それでは、開発の現場でそのままコピペして使える実用的なコードをお見せします。
今回は分かりやすく、「モデル空間にあるすべてのハッチングに対し、新しい境界(例として特定のポリラインなど)を再設定する」というシナリオを想定したコードです。
Sub UpdateHatchBoundaries()
‘ — 宣言セクション —
Dim acadApp As AcadApplication
Dim acadDoc As AcadDocument
Dim entry As AcadEntity
Dim hatchObj As AcadHatch
‘ 安全なエラーハンドリングの準備
On Error GoTo ErrorHandler
‘ 1. AutoCADのアプリケーションと、現在アクティブなドキュメントを取得
Set acadApp = ThisDrawing.Application
Set acadDoc = acadApp.ActiveDocument
‘ ユーザーへの優しいフィードバック
acadDoc.Utility.Prompt vbCrLf & “— ハッチング境界の再定義処理を開始します —” & vbCrLf
‘ 2. モデル空間の全エンティティを巡回 (For Eachループの基本)
For Each entry In acadDoc.ModelSpace
‘ 拾い上げたオブジェクトが「ハッチング」かどうかを判定
If TypeOf entry Is AcadHatch Then
Set hatchObj = entry
‘ 【重要】Hatchのライフサイクル管理
‘ 既存の境界ループが存在する場合、インデックス0のループを削除する
‘ ※実務では複雑な多重ループ構造もありますが、基本は「削ってから付け直す」です
If hatchObj.NumberOfLoops > 0 Then
hatchObj.DeleteLoop 0
End If
‘ —————————————————————–
‘ 3. 新しい境界ループの準備
‘ —————————————————————–
‘ 実務ではここで新しい境界となるAcadEntityの配列(Variant型)を作成します。
‘ 今回は概念を伝えるため、仮の配列作成ロジック(実際には選択セットや
‘ 周囲のオブジェクトから取得した配列をここに代入します)を想定しています。
Dim newLoop(0) As AcadEntity
‘ ※注: ここには新しく境界にしたいLineやPolylineのオブジェクトを代入してください
‘ 例: Set newLoop(0) = acadDoc.ModelSpace.Item(…)
‘ 4. AppendLoopメソッドで新しい境界をねじ込む!
‘ acHatchLoopTypeDefault は通常の外部境界を指定する定数です
hatchObj.AppendLoop acHatchLoopTypeDefault, newLoop
‘ 5. 最重要:EvaluateでAutoCADに再計算を強制する
‘ これを忘れると、内部データは変わったのに画面表示が更新されない「幽霊現象」が起きます
hatchObj.Evaluate
‘ 関連付け(アソシエイティブ)の有効化
hatchObj.AssociativeHatch = True
End If
Next entry
acadDoc.Utility.Prompt vbCrLf & “— 処理が正常に完了しました! —” & vbCrLf
Exit Sub
ErrorHandler:
‘ 予期せぬエラーでマクロがフリーズするのを防ぐ優しさ
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “AutoCAD VBA 実行エラー”
End Sub
—
陥りやすいエラーと、プロが教える回避の極意
このコードや、実務でハッチングを操作するプログラムを書いているとき、あなたはおそらく次のエラーに直面するはずです。
1. 「エラー 438: オブジェクトは、このプロパティまたはメソッドをサポートしていません」
- 原因: 取得したオブジェクトが実はハッチングではなく、ブロック参照やグループだった場合に `DeleteLoop` や `AppendLoop` を叩こうとして起きています。
- 回避策: コード内にある `If TypeOf entry Is AcadHatch Then` という「型ガード(Type Guard)」を絶対にサボらないこと。AutoCAD VBAでは、型を確認するひと手間がプログラムの寿命を延ばします。
2. 「境界が閉じられていません」というサイレントエラー
- 原因: `AppendLoop` に渡した線(`newLoop` の中身)の端点同士がピッタリ繋がっていない場合、AutoCADのエンジニアリング計算が弾き返します。
- 回避策: 境界にする図形は、必ずあらかじめ閉じたポリライン(Closed Polyline)にするか、端点が完全に一致している線群を渡すように設計してください。
3. 見た目が変わらない「幽霊ハッチング」
- 原因: コードは完璧に走ったのに画面が古いまま。これは `hatchObj.Evaluate` を書き忘れた、またはタイミングがずれていることが原因です。
- 回避策: 形状や境界をいじったら、必ずセットで `Evaluate` を呼ぶ。これを呪文のように覚えておいてください。
—
おわりに
お疲れ様でした!
「ハッチングの境界再定義」という、一見すると泥臭く難解な処理も、オブジェクトの構造(ループの削除と追加)と、AutoCADへの再描画命令(`Evaluate`)の仕組みさえ分かってしまえば、怖くありませんよね。
マクロの記録では絶対に到達できない、この「オブジェクトをダイレクトに支配する快感」こそが、AutoCAD VBAの醍醐味です。
あなたの設計業務が、このコードによってさらにスマートで快適なものになることを、心から応援しています。
それでは、次のレッスンでお会いしましょう!
