Visio VBAの深淵:Shape.DeleteExで制御する「削除の流儀」
Visioで自動化ツールを組む際、多くの開発者が直面する最初の壁が「削除」です。
`Shape.Delete`を安易に呼び出し、「意図せぬコネクタの消失」や「孤立した図形によるドキュメントの汚染」に頭を抱えた経験はないでしょうか?
Visioのオブジェクトモデルにおいて、削除は単なるメモリの解放ではありません。それは「接続関係の動的再構成」という重いイベントを伴う処理です。本稿では、Visio 2013以降の標準装備である`Shape.DeleteEx`を使いこなし、堅牢かつインテリジェントな削除ロジックを設計する極意を伝授します。
—
1. なぜ `Shape.Delete` は危険なのか
既存の`Shape.Delete`は、いわば「強制削除」です。接続されているコネクタ(Connector)が存在する場合、Visioのエンジンは自動的にそれらのコネクタも道連れにして削除を試みます。
- 予期せぬ連鎖削除: 重要なフローチャートの起点となる図形を消した際、全コネクタが消滅し、ドキュメントの整合性が崩壊する。
- イベントの暴走: `Document.ShapeDeleted`イベントが想定外の回数発火し、再帰処理のバグを誘発する。
これらを防ぐための唯一の回答が、削除の挙動を引数で制御できる`Shape.DeleteEx`です。
—
2. Shape.DeleteEx のアーキテクチャ
`Shape.DeleteEx`には、削除の挙動を決定づける以下のフラグが存在します。
- visDeleteNormal: 通常の削除。
- visDeleteNoHeal: 接続を維持(Heal)せずに削除。コネクタが「浮いた」状態になります。
- visDeleteNoContainerOrder: コンテナ内の順序を再計算せずに削除。
実務的判断:
通常、業務ツールでは「コネクタを削除させない」という要件が圧倒的に多いです。`visDeleteNoHeal`を適切に制御することで、図形だけを抜き取り、接続線をそのまま残す(あるいは後続の処理で再接続する)という高度な制御が可能になります。
—
3. 実装コード:プロダクションレベルの削除メソッド
現場で使える、保守性を考慮した削除ラッパー関数を紹介します。このコードは、エラーハンドリングとオブジェクトの生存確認を徹底しています。
”’
”’
”’ 削除対象のShapeオブジェクト
”’ Trueならコネクタを維持(切断)する
Public Sub SafeDeleteShape(ByRef shp As Visio.Shape, Optional ByVal preserveConnectors As Boolean = True)
‘ ヌルチェック:生存していないオブジェクトへの操作は例外を招く
If shp Is Nothing Then Exit Sub
On Error GoTo Err_Handler
‘ 削除フラグの決定
‘ visDeleteNoHeal を指定することで、接続線を道連れにせず切断のみ行う
Dim flags As Integer
If preserveConnectors Then
flags = Visio.VisDeleteFlags.visDeleteNoHeal
Else
flags = Visio.VisDeleteFlags.visDeleteNormal
End If
‘ 削除実行
shp.DeleteEx flags
Exit Sub
Err_Handler:
‘ ログ出力やエラーハンドリングをここに記述
Debug.Print “削除失敗: ” & Err.Description
End Sub
—
4. 開発現場で陥る罠と回避策
① ファイル・DB連携時の注意
Visioの図形ID(`Shape.ID`)は、削除によって再利用されることがあります。DBにIDを保存している場合、「IDだけで図形を特定する」のは論理的破綻の元です。必ず`UniqueID`プロパティ(GUID)を使用してください。
② 大量削除のパフォーマンス問題
ページ内の多数の図形をループで削除する場合、毎回`DeleteEx`を呼ぶと再描画コストが肥大化します。
- 最適解: 削除時は`Application.ScreenUpdating = False`を併用し、処理終了後に一括で再描画を強制する。
③ コンテナ図形(Container)の扱い
コンテナ内に図形が含まれている場合、コンテナを削除すると中身も消えます。`DeleteEx`のフラグを駆使しても、親子の依存関係は強力です。コンテナから図形を排出する処理(`ContainerProperties.RemoveMember`)を事前に行うか、あるいはコンテナごと消去するのか、仕様を明確に分ける設計が不可欠です。
—
5. 最後に:エンジニアとしての心構え
VisioのAPIは一見古臭く感じられるかもしれませんが、その背後にあるオブジェクトモデルは極めて論理的です。`DeleteEx`という小さな武器を使いこなすことは、単にコードを書くことではなく、「ドキュメントの状態管理を掌握する」ことに他なりません。
「動けばいい」という考えを捨て、削除という破壊的行為に対してさえ「整合性を担保する」という姿勢を持つこと。それこそが、伝説的なオートメーションエンジニアへの第一歩です。
さあ、あなたのツールから「意図せぬ図形の消失」というバグを根絶してください。それができるのは、この設計指針を理解したあなただけです。
