【実務・中級編】【初心者向け】AcadApplication.WindowStateの制御:処理中にAutoCADを最小化し、Excel側の操作を邪魔させない工夫 – AutoCAD VBA解析バイブル

スポンサーリンク

【AutoCAD VBAを掌握する極限の知見】Excelからの遠隔操作でCADの描画を隠蔽し、ユーザーのストレスを消し去るWindowState制御の極意

開発プロジェクトの現場で、ExcelからAutoCADを自動制御するツールを納品したとき、ユーザーからこんなクレームを受けたことはないだろうか。

  • 「処理が走っている間、AutoCADの画面がガチャガチャと勝手に動いて気持ち悪い」
  • 「大量の図面を一括処理している最中、うっかりAutoCADの画面をクリックしてしまい、エラーで止まった」
  • 「裏で動かしたいだけなのに、CADが前面に出てきてExcelの入力作業が邪魔される」

プログラマーとしての初期衝動のままに `CreateObject(“AutoCAD.Application”)` を叩き、そのまま処理を走らせる——。これは実務の現場においては「素人設計の悪夢」でしかない。

今回は、Excelを司令塔、AutoCADを完全なるバックグラウンドの「作業部隊」として調教し、ユーザーエクスペリエンス(UX)を極限まで高めるための `AcadApplication.WindowState` の制御術を、ロジカルかつシャープに伝授する。

1. なぜ「そのまま動かす」のはプロ失格なのか?

AutoCADという巨大なアプリケーションは、COM(Component Object Model)経由で外部から操作された際、デフォルトでは親切心からそのUIを前面に押し出そうとする。

しかし、業務自動化(RPAやVBAによる一括処理)の文脈において、CADの画面描画やアクティブウィンドウの奪い合いは「百害あって一利なし」だ。

パフォーマンスと安定性のジレンマ

  • 画面描画のオーバーヘッド: AutoCADはウィンドウが表示されている状態(`acNorm` や `acMax`)のとき、C#やVBAから図形エンティティが追加・変更されるたびにビューポートの再描画(Viewport Regeneration)を試みる。これが処理速度を劇的に低下させる。
  • フォーカスの競合: 処理中にユーザーがExcelに戻って他の作業をしようとした瞬間、AutoCADがアクティブになりキーボードフォーカスを奪う。結果、キー入力の誤作動やCOMエラー(エラー 462: リモートサーバーマシンが見つからないか…など)を引き起こす温床となる。

これをスマートに解決するのが、`AcadApplication.WindowState` によるウィンドウ状態の制御だ。

2. WindowStateプロパティの正しい理解

AutoCADのアプリケーションオブジェクトには、ウィンドウの表示状態を制御する `WindowState` プロパティが用意されている。

| 定数名 | 値 | 意味 | 実務での評価 |
| :— | :—: | :— | :— |
| `acVBAAppMaximize` | 3 | 最大化 | 最悪。 画面全体を占領しユーザーを威圧する。 |
| `acVBAAppMinimize` | 2 | 最小化 | 推奨。 タスクバーに格納し、視界から完全に消去する。 |
| `acVBAAppNormal` | 1 | 標準(元のサイズ) | デバッグ時以外は使うべきではない。 |

※注意:AutoCADのバージョンやライブラリの参照設定によっては、定数 `acVBAAppMinimize` が正しく評価されない場合がある。そのため、実務コードではマジックナンバーである `2` を直接用いるか、定数を明示的に定義する堅牢なアプローチをとるのがプロの作法である。

3. 【プロダクションコード】ExcelからAutoCADを完全に「裏で」支配する

それでは、実務の現場でそのままコピペして使える、極めて堅牢なVBAコードを公開しよう。
このコードは、Excel側からAutoCADを起動(または既存センスにアタッチ)、ウィンドウを最小化して視界から消し去った上で、安全に図面処理を行い、最後に元の状態を復元するテンプレートである。

Option Explicit

‘ AutoCADウィンドウ状態の列挙体(参照設定抜け対策として明示的に定義)
Private Const AC_APP_MINIMIZE As Long = 2
Private Const AC_APP_NORMAL As Long = 1
Private Const AC_APP_MAXIMIZE As Long = 3

Public Sub ExecuteBackgroundCADProcess()
Dim acadApp As Object
Dim acadDoc As Object
Dim originalState As Long
Dim isAppStartedByMe As Boolean

‘ 画面描画や警告を停止し、処理速度を極限まで高めるExcel側の定石
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
.DisplayAlerts = False
End With

On Error GoTo ErrorHandler

‘ 1. AutoCADインスタンスの取得(起動していなければ新規起動)
On Error Resume Next
Set acadApp = GetObject(, “AutoCAD.Application”)
If acadApp Is Nothing Then
Set acadApp = CreateObject(“AutoCAD.Application”)
isAppStartedByMe = True
End If
On Error GoTo ErrorHandler

‘ 2. AutoCADが完全に立ち上がるまで待機(COMの遅延対策)
Dim startTime As Double
startTime = Timer
Do While acadApp.Documents Is Nothing
If Timer – startTime > 15 Then
Err.Raise 9999, “CAD_Init”, “AutoCADの起動タイムアウトです。”
End If
DoEvents
Loop

‘ 3. 現在のウィンドウ状態を退避し、最小化を実行
originalState = acadApp.WindowState
acadApp.WindowState = AC_APP_MINIMIZE

‘ 可視化を強制オフ(さらなる高速化とちらつき防止)
acadApp.Visible = True ‘ 非表示(Visible = False)にすると一部のバージョンでCOMが不安定になるため、最小化(+描画抑制)が最も安全

‘ 4. 図面のオープンと実務処理の実行
Dim targetFilePath As String
targetFilePath = ThisWorkbook.Path & “\sample.dwg”

Set acadDoc = acadApp.Documents.Open(targetFilePath)

‘ — 【ここに行政・実務用の重い処理を記述】 —
Call ProcessHeavyDrawingTasks(acadDoc)
‘ ——————————————-

‘ 5. 変更を保存して閉じる
acadDoc.Save
acadDoc.Close False

‘ 正常終了時のクリーンアップ
GoTo Finally

ErrorHandler:
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“詳細: ” & Err.Description, vbCritical, “CAD自動化エラー”

Finally:
‘ 6. AutoCADのウィンドウ状態を元の状態へ復元
If Not acadApp Is Nothing Then
On Error Resume Next
acadApp.WindowState = originalState
On Error GoTo 0
End If

‘ オブジェクトの解放
Set acadDoc = Nothing
Set acadApp = Nothing

‘ Excel側の設定を復元
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
.DisplayAlerts = True
End With

MsgBox “すべての処理が正常に完了しました。”, vbInformation, “完了”
End Sub

Private Sub ProcessHeavyDrawingTasks(ByVal doc As Object)
‘ ここにレイヤー操作やブロック挿入などの重い処理を書く
‘ 例:モデル空間のエンティティ数を出力するだけなら一瞬
Dim entCount As Long
entCount = doc.ModelSpace.Count

‘ デバッグ用(裏で静かに処理される)
Debug.Print “処理対象のエンティティ数: ” & entCount
End Sub

4. チーフアーキテクトが教える「現場の地雷原」と回避策

上記のコードは十分実用的なプロダクション品質だが、AutoCAD VBAの深い闇を知る者として、いくつか追加の警告をしておこう。

地雷その1: `acadApp.Visible = False` は使うな

「最小化するよりも、そもそも `Visible = False` にして完全に隠せばいいのでは?」と考えたそこのあなた。甘い。
AutoCADのCOMコンポーネントは、`Visible = False` の状態で図面を開いたり複雑なジオメトリ演算を行うと、メモリリークを起こしたり、最悪の場合バックグラウンドプロセス(acad.exe)がゾンビ化してタスクマネージャーに残居し続けるという致命的な仕様(バグ)を抱えている。
「ウィンドウは表示(Visible = True)しつつ、WindowStateで最小化(Minimize)する」。これが、幾多の修羅場をくぐり抜けたエンジニアがたどり着いた唯一の正解である。

地雷その2: ユーザーによる「タスクバーからの復元」への対策

処理が数分に及ぶ大規模な一括処理中、ヒマになったユーザーがタスクバーにあるAutoCADのアイコンをうっかりクリックして画面を最大化させてしまうことがある。
これを完全に防ぐことはCOMの仕様上難しいが、コードの冒頭と処理の要所で `acadApp.WindowState = AC_APP_MINIMIZE` を再適用する「防御的プログラミング」を挟むことで、リスクを最小化できる。

5. まとめ:ツールを「作品」から「インフラ」へ昇華させろ

素人が書いたマクロは「動けばいい」というおもちゃの域を出ない。しかし、プロが設計した業務自動化ツールは、ユーザーの存在を忘れさせるほどの静けさと、圧倒的なパフォーマンスを備えた「インフラストラクチャ」でなければならない。

今回紹介した `WindowState` の制御と、徹底的な画面描画の抑制は、そのための第一歩に過ぎない。
しかし、この細部へのこだわりこそが、あなたの作成するツールを「使い物にならない厄介者」から「現場から絶賛される神ツール」へと変える決定的な差となる。

さあ、今すぐあなたのコードにある野暮な `Application.Visible` や最大化の処理を書き換え、エレガントなバックグラウンド制御を実装してほしい。

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