こんにちは!AutoCAD VBAの世界へようこそ。
マクロの記録ボタンを押すだけの自動化から一歩抜け出し、「真のAutoCADの支配者」になりたいあなたへ。
今回は、中級者から上級者への登竜門であり、大規模な設計プロジェクトで絶大な威力を発揮するテーマ「Sheet Set Manager (SSM) の完全自動制御」について解説します。
「複数の図面にまたがるシート番号の振り直し、手作業でやって疲弊していませんか?」
「図面枚数が100枚を超えたあたりから、整合性を保つだけで残業が消えていく……」
そんな絶望を華麗に解決するのが、今回紹介する `AcadApplication.GetInterfaceObject` を使った高度なCOMプログラミングです。ここをクリアすれば、あなたのAutoCAD VBAスキルは間違いなくプロの領域に達します。温かく、かつ妥協のない技術の深淵へ、一緒に足を踏み入れてみましょう!
—
1. なぜ「Sheet Set Manager (SSM)」の操作は難しいのか?
AutoCAD VBAの基本を学んだ方なら、`ThisDrawing.ModelSpace` や `AcadDocument` といったオブジェクトの扱いはもうお手のものだと思います。
しかし、複数の図面を束ねる「シートセット(.dstファイル)」は、通常の `AcadDocument` の中にはいません。AutoCADの裏側で独立して動いている「外部のCOMコンポーネント(API)」だからです。
ここで登場するのが、伝説のメソッド `AcadApplication.GetInterfaceObject` です。
これを使うと、AutoCADのプロセス外(あるいは特殊なメモリ空間)に存在するコンポーネントを、VBAの変数に直接召喚できるようになります。つまり、AutoCADの画面を開くことすらなしに、裏側でシートセットをゴリゴリと操作できてしまうというわけです。
—
2. 現場で使える!シート番号一括自動採番の全コード
百聞は一見に如かず。まずは、指定したシートセット(.dstファイル)を読み込み、含まれているシートの番号をルールに従って一括で振り直す、プロ仕様の実用コードをプレゼントします。
ご自身の環境に合わせて、コード内のパス(`dstPath`)を書き換えて使ってください。
Option Explicit
‘ ==============================================================================
‘ 【上級】Sheet Set Manager (SSM) 自動操作サンプル
‘ 複数図面に跨るシート番号のプレフィックス付与と連番一括更新
‘ ==============================================================================
Sub AutoNumberingSheetSet()
On Error GoTo ErrorHandler
‘ 1. 操作対象のシートセット(.dstファイル)のフルパスを指定
Dim dstPath As String
dstPath = “C:\Projects\MegaStructure\Structural_Design.dst”
‘ ファイルの存在確認
If Dir(dstPath) = “” Then
MsgBox “指定されたシートセットファイルが見つかりません: ” & vbCrLf & dstPath, vbCritical, “パスエラー”
Exit Sub
End If
‘ 2. グローバルなAutoCAD Applicationインスタンスの取得
Dim acadApp As AcadApplication
Set acadApp = ThisDrawing.Application
‘ 3. GetInterfaceObject を用いた SSM (AcadSheetSetMgr) の召喚
‘ ※これが今回の最も重要なキモです!
Dim ssMgr As Object
Set ssMgr = acadApp.GetInterfaceObject(“Agcl.AcadSheetSetMgr.18”)
If ssMgr Is Nothing Then
MsgBox “Sheet Set Managerのインターフェースを取得できませんでした。”, vbCritical, “COMエラー”
Exit Sub
End If
‘ 4. .dstファイルを開いてデータベース(AcadSheetSet)を取得
Dim dbRoot As Object
Set dbRoot = ssMgr.Open(dstPath)
Dim rootSheetSet As Object
Set rootSheetSet = dbRoot.GetSheetSet()
MsgBox “シートセット [” & rootSheetSet.name & “] の読み込みに成功しました。” & vbCrLf & _
“これからシート番号の自動再採番を開始します。”, vbInformation, “処理開始”
‘ 5. 再帰的にシートを走査して番号を書き換える
Dim counter As Integer
counter = 1
‘ ルート直下のサブセット・シートを巡回
Call ProcessSubElements(rootSheetSet.GetSet(), counter)
‘ 6. 変更をデータベースに保存 (Lock/Unlockの概念が裏で働いています)
dbRoot.UpdateAll
‘ 7. クリーンアップ
ssMgr.Close dbRoot
MsgBox “すべてのシート番号の更新が完了しました!”, vbInformation, “処理完了”
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“Error No: ” & Err.Number & vbCrLf & _
“Description: ” & Err.Description, vbCritical, “致命的なエラー”
‘ 確実にオブジェクトを開放する
If Not ssMgr Is Nothing And Not dbRoot Is Nothing Then
On Error Resume Next
ssMgr.Close dbRoot
End If
End Sub
‘ ==============================================================================
‘ 再帰的(レカージョン)にサブセットとシートを巡回するヘルパープロシージャ
‘ ==============================================================================
Private Sub ProcessSubElements(elementCollection As Object, ByRef currentNo As Integer)
Dim elem As Object
Dim i As Long
‘ コレクションの要素を走査
For i = 0 To elementCollection.Count – 1
Set elem = elementCollection.Item(i)
‘ 要素が「シート(AcadSheet)」であるか、さらに下層の「サブセット(AcadSubset)」であるかを判定
‘ TypeNameを利用した安全な型チェック
If TypeName(elem) = “IAcadSelectionSet” Or TypeName(elem, 2) = “AcSmSubset” Then
‘ サブセットの場合は再帰呼び出し
Call ProcessSubElements(elem.GetSet(), currentNo)
ElseIf TypeName(elem) = “IAcadSheet” Or TypeName(elem, 2) = “AcSmSheet” Then
‘ シートの場合:番号を強制採番(例: “S-001”, “S-002” …)
Dim formattedNo As String
formattedNo = “S-” & Format(currentNo, “000”)
‘ プロパティの書き換え
elem.Number = formattedNo
‘ デバッグ用イミディエイト出力
Debug.Print “Updated Sheet Name: ” & elem.name & ” -> New Number: ” & formattedNo
currentNo = currentNo + 1
End If
Next i
End Sub
—
3. コードの急所を徹底解説!
このコードのどこが「上級」なのか、エンジニアの視点で重要なポイントを3つに絞って解説します。
① `GetInterfaceObject` の正体とバージョン依存性
Set ssMgr = acadApp.GetInterfaceObject(“Agcl.AcadSheetSetMgr.18”)
通常の `CreateObject` ではなく、なぜ `AcadApplication.GetInterfaceObject` を使うのでしょうか?
それは、AutoCADのセッションと安全にライフサイクルを同期させるためです。文字列 `”Agcl.AcadSheetSetMgr.18″` はSSMのPROGIDですが、末尾の `.18` はAutoCADのバージョン(AutoCAD 2013/2014世代を基準とするCOMバージョン)を示しています。
もしご自身の環境で動かない場合は、お使いのAutoCADのバージョンに応じたCOMライブラリの登録状況を確認してください。
② `TypeName` による安全なオブジェクト型判定
シートセットの中身は、「フォルダのような役割のサブセット」と「個々の図面を指すシート」がツリー構造で入り組んでいます。
VBAの `TypeOf … Is` はCOMオブジェクトの深い階層ではうまく機能しないことがあるため、`TypeName()` 関数を用いて確実に型を判別し、再帰処理(自分自身を呼び出す関数)で全ノードを網羅しています。
③ 容赦ないエラーハンドリングとメモリ解放
COMオブジェクトを扱う上で最も恐ろしいのは、「VBAのエラーによってAutoCADの裏側でプロセス(ファイルロック)が残ってしまう現象」です。
今回のコードでは `On Error GoTo ErrorHandler` を厳格に配置し、万が一途中でエラーが発生しても、確実に `ssMgr.Close` を呼んでファイルを解放する設計にしています。プロフェッショナルは、後始末まで美しく書くものです。
—
4. 陥りやすい罠とトラブルシューティング
- エラー「オートメーション エラーです」が発生する
- 原因: 指定した `.dst` ファイルが、別のAutoCADユーザーや自分自身の別のセッションで既に排他ロックされている可能性があります。
- 対策: 対象の `.dst` ファイルをCADやエクスプローラーから一旦閉じ、ファイルパスが正しいことを確認してください。
- 番号が変わるのに、図面のタイトルブロックに反映されない
- 仕様の注意: このスクリプトは「シートセットのデータベース上のメタデータ(番号)」を書き換えています。図面内の文字(フィールド等)に反映させるには、SSMの「フィールドの更新」や、図面を開いての再描画が必要になる場合があります。大規模なプロジェクトでは、夜間バッチの一部として組み込むのが定石です。
—
まとめ:ここをクリアすれば、もう怖くない!
今回は、AutoCAD VBAの基礎の枠を大きく飛び越え、`GetInterfaceObject` を駆使した Sheet Set Manager の自動制御について解説しました。
「画面をポチポチ操作する自動化」から、「背後のデータ構造を直接ねじ伏せる自動化」へ。
この領域に踏み込んだあなたなら、今後どんなに巨大な図面群を押し付けられても、恐れることはありません。
VBAの可能性は無限大です。ぜひ自分のプロジェクトに応用して、定時退社を勝ち取ってくださいね!
それでは、次回の極限知見でお会いしましょう。
