【実務・中級編】【初心者向け】AutoCADのシステム変数(SETVAR)をVBAで制御!OSNAPやPICKBOXの設定を自動で最適化する – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD VBAを掌握する極限の知見:システム変数を制する者は、作図自動化を制する

開発プロジェクトのリーダーである私から、現場で即座に使える「本物の知識」を授けよう。

AutoCAD VBAによる自動化ツール開発において、初心者が最も陥りやすい罠、そしてベテランとの決定的な差がどこにあるか知っているか? それは「環境への配慮の有無」だ。

ボタン一つで図形を爆発的に生成するマクロを作ったはいいが、実行が終わった後にユーザーのOSNAP(スナップ)設定が狂い、PICKBOX(選択ボックス)のサイズが変わり果てていたらどうなるか? ユーザーからのクレームの嵐、あるいは「あのツールを使うとAutoCADがおかしくなる」という悪評が立ち、せっかく作った自動化ツールは社内で完全に廃れていくだろう。

プロのエンジニアが書くコードには、「自己完結性(Self-containment)」「環境の不可侵性」が宿っている。今回は、`AcadDocument` の `GetVariable` と `SetVariable` を駆使し、作図効率に直結するシステム変数を制御、そして「確実に元の状態へ復元する」ための極限の設計手法を伝授する。

なぜ `SETVAR` の直接操作や、野良マクロは危険なのか?

AutoCADのシステム変数は、図面の挙動を決定するメタデータだ。OSNAP(`OSMODE`)、PICKBOX(`PICKBOX`)、GRIPS(`GRIPS`)、FILEDIA(`FILEDIA`)など、数え切れないほどの変数が存在する。

素人がやりがちな最悪のコードがこれだ:

‘ 【アンチパターン】絶対にやってはいけない書き方
Sub BadExample()
‘ いきなりシステム変数を書き換える
ThisDrawing.SetVariable “OSMODE”, 0 ‘ スナップを完全オフ
ThisDrawing.SetVariable “PICKBOX”, 50 ‘ 選択ボックスを巨大化

‘ ここに処理…(エラーが起きたらどうなる?)

‘ 運良くここまで来たら戻す(来なかったら?)
ThisDrawing.SetVariable “OSMODE”, 4133
ThisDrawing.SetVariable “PICKBOX”, 3
End Sub

もし、処理の途中でエラーが発生したら? 予期せぬ例外でマクロが中断されたら?
システム変数は書き換わったまま放置され、ユーザーのCAD環境は破壊される。これが「野良マクロ」が現場で嫌われる理由だ。

我々はプロだ。「エラーが起きようとも、処理が正常終了しようとも、環境を元の状態に1ミリの狂いもなく復元する」。この鉄則をコードに落とし込む。

実務で直結する! システム変数制御のベストプラクティス設計

堅牢なツールを構築するためには、以下の3つの要件を満たす必要がある。

1. 一元管理と自動退避: 変更するシステム変数の初期値を実行前に自動取得する。
2. クリーンアップの保証: `On Error` 構文を利用し、いかなる例外発生時でも必ず復元処理を通す。
3. バッチ処理時の高速化: 画面描画(`REGEN`)やOSNAPの無効化により、図形生成のパフォーマンスを極限まで引き上げる。

プロダクションコード:安全・高速なシステム変数制御テンプレート

以下のコードは、私が実際の大型プラント設計や建築BIMの現場で標準採用しているテンプレートの核心部分だ。そのままコピー&ペーストし、プロジェクトの基盤として活用してほしい。

Option Explicit

‘ ==============================================================================
‘ 担当者: チーフアーキテクト
‘ 概要: システム変数を安全に制御し、作図処理の高速化と環境復元を保証するテンプレート
‘ ==============================================================================
Sub ExecuteOptimizedDrawingTask()
Dim targetDoc As AcadDocument
Set targetDoc = ThisDrawing

‘ 1. 退避用配列の定義 (変数名, 初期値)
Dim sysVarNames(2) As String
Dim originalValues(2) As Variant

sysVarNames(0) = “OSMODE” ‘ オブジェクトスナップ設定
sysVarNames(1) = “PICKBOX” ‘ 選択ボックスサイズ
sysVarNames(2) = “REGENMODE”‘ 自動再描画モード

Dim i As Long

‘ 2. エラーハンドリングの有効化(ここからクリーンアップが絶対保証される)
On Error GoTo ErrorHandler

‘ — 【環境の退避と最適化の適用】 —
For i = LBound(sysVarNames) To UBound(sysVarNames)
‘ 現在値を退避
originalValues(i) = targetDoc.GetVariable(sysVarNames(i))
Next i

‘ 作図パフォーマンスと正確性を最大化するための一時設定
targetDoc.SetVariable “OSMODE”, 0 ‘ スナップを一時無効化(誤作動防止)
targetDoc.SetVariable “PICKBOX”, 3 ‘ 標準的な選択ボックス
targetDoc.SetVariable “REGENMODE”, 0 ‘ 連続図形生成時の無駄な再描画を抑制し爆速化

‘ ==============================================================================
‘ 3. メインの重たい処理(ここに実際の自動作図ロジックを記述)
‘ ==============================================================================
Call HeavyDrawingProcess(targetDoc)

‘ 正常終了時の復元
GoTo CleanUp

ErrorHandler:
‘ 異常終了時のログ出力およびリカバリ通知
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “致命的エラー”

CleanUp:
‘ ==============================================================================
‘ 4. 【最重要】いかなる場合でも必ず実行される環境復元処理
‘ ==============================================================================
On Error Resume Next ‘ 復元時の万が一のエラーを無視して続行を試みる
For i = LBound(sysVarNames) To UBound(sysVarNames)
targetDoc.SetVariable sysVarNames(i), originalValues(i)
Next i

‘ 抑制していたREGENを戻したついでに画面を強制リフレッシュ
targetDoc.Regen acActiveViewport

MsgBox “処理が完了し、システム環境は正常に復元されました。”, vbInformation, “完了”
Exit Sub
End Sub

‘ サンプル用のメイン作図処理(モック)
Private Sub HeavyDrawingProcess(doc As AcadDocument)
‘ ここに大量のLineやBlock挿入などの処理を書く
‘ 例として円を生成するダミー処理
Dim centerPoint(2) As Double
Dim radius As Double
radius = 10.0

Dim j As Long
For j = 1.0 To 1000.0
centerPoint(0) = j 5.0: centerPoint(1) = 0#: centerPoint(2) = 0#
‘ OSMODE=0かつREGENMODE=0のため、このループは圧倒的な速度で完了する
doc.ModelSpace.AddCircle centerPoint, radius
Next j

‘ 意図的にエラーを起こしてテストしたい場合は下のコメントを外せ
‘ Err.Raise 9999, , “テスト用強制エラー”
End Sub

コードの深層解説:プロがこだわる3つの技術的ポイント

1. 配列によるシステム変数のスマートな一括管理

個別変数ごとに `GetVariable` や `SetVariable` を書くのは、コードが冗長になり保守性が下がる。上記のように `String` 型の配列と `Variant` 型の配列をペアにすることで、管理対象のシステム変数が将来増減した際も、配列の定義(`UBound`)を書き換えるだけで対応できるスケーラビリティを持たせている。

2. `REGENMODE` の制御による劇的なパフォーマンス向上

AutoCAD VBAで最もパフォーマンスを殺す要因は、図形を追加するたびに走る暗黙の画面再描画(Regen)だ。数千本の線を引くループの中でこれが走ると、処理時間は何倍にも膨れ上がる。
`REGENMODE` を `0`(オフ)にすることで描画を完全に凍結し、ループ終了後に一度だけ `targetDoc.Regen acActiveViewport` を叩く。この一手間で、処理時間が数秒からコンマ数秒へと劇的に短縮される。これが「現場で使えるエンジニア」の仕事だ。

3. `On Error Resume Next` とクリーンアップの哲学

`CleanUp` ラベル手前で `On Error GoTo ErrorHandler` を抜け、`On Error Resume Next` を挟んでいる点に注目してほしい。
復元処理の最中に万が一AutoCADの内部ステート矛盾等でエラーが起きた場合、そこで処理が止まると二重苦になる。復元フェーズにおいては「可能な限り元の状態に戻す」ことが最優先命題であるため、エラーをいなして最後の最後まで修復を試みるのが、極限環境を生き抜くための防衛的プログラミングの真髄である。

結びにかえて

システム変数の制御は、AutoCAD VBA開発における「基本中の基本」であると同時に、開発者のエンジニアリングとしての品格が最も表れる部分だ。

ユーザーの作業環境を脅かさず、裏で静かに、そして圧倒的なパフォーマンスで仕事をやり遂げる――。このテンプレートをあなたのプロジェクトの武器として組み込み、洗練された自動化ツールを構築してほしい。現場のエンジニアたちは、その確実な動作に必ずや唸ることだろう。

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