【入門編】【上級プロフェッショナル向け】図面保存イベント「BeginSave」をフックした「社内規定チェック」と保存の強制キャンセル – AutoCAD VBA解析バイブル

スポンサーリンク
スポンサーリンク

マクロの記録を卒業しよう。AutoCAD VBAで「設計品質を自動ガードする」プロフェッショナルへの第一歩

こんにちは。現場の設計業務を支えるエンジニアの皆さん。
今日も図面作成、お疲れ様です。

「レイヤー名がルール通りになっていない」「文字スタイルが勝手に作られている」……。
そんな、本来なら設計者が集中すべきではない「形式的なミス」に、時間を削られてはいませんか?

これまで皆さんが行ってきた「マクロの記録」は、いわば「自分の手作業を録画したもの」です。それは素晴らしい第一歩ですが、それだけでは「図面を壊そうとする動き(ルール違反)」を止めることはできません。

今日、皆さんに伝授したいのは、その一歩先にある「イベント駆動型プログラミング」の世界です。
AutoCADが「今から保存しますよ」と宣言した瞬間に、背後で忍び寄り、ルール違反を検閲して、違反があれば保存を阻止する。そんな「守護神」のようなアドインを作る方法を、魂を込めて解説します。

ここをクリアすれば、AutoCAD VBAの基本はバッチリですよ。さあ、始めましょう。

1. 「命令する」から「見守る」へ:イベント駆動の概念

これまでのVBAは、あなたがボタンを押した時や、マクロを実行した時にだけ動く「命令型(Imperative)」でした。

しかし、今回扱う「BeginSave」のような機能は、「イベント駆動型(Event-Driven)」と呼ばれます。
これは、AutoCADという巨大なシステムが「保存ボタンが押された!」「図面が開かれた!」という「出来事(イベント)」を発生させた瞬間に、あらかじめ登録しておいたプログラムを自動的に呼び出す仕組みです。

なぜ「クラスモジュール」が必要なのか?

ここで多くの初心者が躓きます。「なぜ普通のモジュールじゃダメなの?」と。

結論から言いましょう。「イベントを待ち構える能力」は、クラスモジュールにしか宿らないからです。
普通のモジュールは「指示待ち」ですが、クラスモジュールは「監視カメラ」になれる。この違いを理解することが、プロへの分かれ道です。

2. 実装:社内規定チェック・ガードマン

それでは、具体的なコードを見ていきましょう。
今回のミッションは、「保存時にレイヤー名が『STD_』で始まっていない図面があれば、保存を中断させる」というものです。

※注:純粋なVBAの制約上、保存を完全に「無かったこと」にするには高度なテクニックが必要ですが、ここでは「エラーを発生させてユーザーに警告し、保存プロセスを中断させる」という、実務的に最も堅実なアプローチを取ります。

Step 1: 監視カメラを作る(クラスモジュールの作成)

まず、VBAエディタで「挿入」→「クラスモジュール」を選択してください。
プロパティウィンドウで、オブジェクト名を `clsAppEventHandler` に変更してください。

' --- クラスモジュール: clsAppEventHandler ---
Option Explicit

' AutoCADのアプリケーションイベントを受け取るための変数
Private WithEvents AcadApp As AcadApplication

' クラスが初期化された時に呼ばれる(監視開始の準備)
Private Sub Class_Initialize()
    ' 現在動いているAutoCADアプリケーションを監視対象としてセット
    Set AcadApp = ThisDrawing.Application
End Sub

' AutoCADが「保存を開始する(BeginSave)」というイベントを発生させた時に自動実行
Private Sub AcadApp_BeginSave()
    Dim lay As AcadLayer
    Dim errorFound As Boolean
    Dim errorMsg As String
    
    errorFound = False
    errorMsg = "【警告】社内規定違反が見つかりました!" & vbCrLf
    
    ' --- 検査ロジック:レイヤー名のチェック ---
    ' 図面内のすべてのレイヤーを一つずつ調べていきます(ループ処理)
    For Each lay In ThisDrawing.Layers
        ' レイヤー名が "STD_" で始まっていない場合を検知
        If Not lay.Name Like "STD_*" Then
            errorFound = True
            errorMsg = errorMsg & "- 不適切なレイヤー名: " & lay.Name & vbCrLf
        End If
    Next lay

    ' --- 判定と介入 ---
    If errorFound Then
        ' 違反があった場合、メッセージを表示して「エラー」を投げる
        ' これにより、AutoCADの標準的な保存処理を中断させます
        MsgBox errorMsg, vbCritical, "保存キャンセル"
        
        ' Err.Raiseを使って、意図的にエラーを発生させ、保存プロセスをストップさせる
        ' これが「保存の強制キャンセル」のプロの技です
        Err.Raise vbObjectError + 513, "CheckStandard", "規定違反があるため保存できません。"
    Else
        ' 問題なければ、何もしない(そのまま保存が続行される)
        Debug.Print "チェック通過: 保存を許可します。"
    End If
End Sub

Step 2: 監視を開始する(標準モジュールの作成)

クラスを作っただけでは、監視カメラは電源が入っていません。
次に「挿入」→「標準モジュール」を選択し、以下のコードを記述します。

' --- 標準モジュール ---
Option Explicit

' クラスのインスタンスを保持するための変数
' ※ここが重要!プロシージャ内で宣言すると、実行直後にメモリから消えてしまいます
Private MyEventHandler As clsAppEventHandler

' このマクロを実行することで、監視が始まります
Sub StartGuard()
    ' クラスをインスタンス化(メモリ上に実体を作る)
    Set MyEventHandler = New clsAppEventHandler
    
    MsgBox "社内規定チェック・ガードマン、起動しました!" & vbCrLf & _
           "保存時にレイヤー名を自動検査します。", vbInformation
End Sub

' 監視を停止する場合
Sub StopGuard()
    Set MyEventHandler = Nothing
    MsgBox "ガードマンを停止しました。", vbExclamation
End Sub

3. 陥りやすいエラーと、プロの視点

このコードを動かす際、皆さんは必ず以下の「壁」にぶつかるはずです。

① 「監視がすぐに止まってしまう!」問題

`StartGuard` を実行しても、すぐにチェックが効かなくなることがあります。
原因は、「変数のスコープ(有効範囲)」です。

もし `StartGuard` の中で `Dim MyEventHandler As clsAppEventHandler` と書いてしまうと、そのマクロが終わった瞬間に変数が破棄され、監視カメラの電源が切れてしまいます。
必ず、標準モジュールの最上部(宣言部)で宣言してください。これが「オブジェクトのライフサイクル」を管理するということの本質です。

② 「エラーでAutoCADが止まったように見える」問題

`Err.Raise` を使うと、AutoCADは「エラーが発生しました」というダイアログを出します。これは「保存を止める」ための、VBAにおける最も強力な手段です。
ユーザーには「エラー」ではなく「規定違反による中断」であることを理解してもらうため、メッセージボックスで丁寧に案内することが、優れたエンジニアの作法(UXデザイン)です。

③ パフォーマンスの重み

今回はレイヤーのチェックだけですが、もし「数万個のブロック」や「すべての文字スタイル」をチェックしようとすると、保存のたびに数秒待たされることになります。
「イベントの中で重い処理をさせすぎない」。これは、大規模なCAD運用において、エンジニアが常に意識すべき鉄則です。

最後に:ここをクリアすれば、あなたはもう「使い手」ではない

今回学んだことは、単なるコードの書き方ではありません。

1. イベント駆動(システムの変化を察知する)
2. クラスモジュール(状態を保持し、監視する)
3. オブジェクトのライフサイクル(メモリ上でいつまで生きているか)

これらは、AutoCAD VBAのみならず、VB.NET、C#、あるいはあらゆるプロフェッショナルな開発における「共通言語」です。

マクロの記録から脱却し、システムを制御する側へ。
この小さな「ガードマン」を作れたあなたは、もう立派なアドイン開発者の入り口に立っています。

さあ、次は「文字スタイルのチェック」や「図面内の不要な要素の削除」にも、この仕組みを応用してみてください。道は無限に広がっていますよ。

応援しています!

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