Visio VBAで「特定のシェイプ」だけを透過PNGで切り出す:実務を支える極限の座標計算
業務自動化の現場において、Visioから「特定の図形だけを透過PNGで抽出したい」というニーズは頻繁に発生する。しかし、多くのエンジニアが「図面全体をエクスポートしてから外部ツールでトリミングする」という泥臭い非効率な手法に逃げている。
Visioのオブジェクトモデルを深く理解すれば、そんな工数は不要だ。`Shape.BoundingBox`と`Page.Export`を組み合わせ、「余白なし・背景透過・高精度」な画像をダイレクトに出力するアーキテクチャを伝授する。
—
1. なぜ「手動エクスポート」はゴミ箱行きなのか
Visioの `Page.Export` は強力だが、標準では「ページ全体」が対象となる。これを解決するために多くの人が陥るのが、「図面内の座標をスクリーンショットで計算する」という愚行だ。
守るべき設計原則
- BoundingBoxの罠を回避せよ: `BoundingBox`メソッドは、線の太さや影(Shadow)の影響を受ける。そのまま座標を信じると、画像が欠けたり、逆に余白が大きすぎたりする。
- 名前空間の固定: `visBBoxUprightWH` フラグを適切に使い、回転した図形でも正しく境界を計算させる必要がある。
- メモリ解放の徹底: VisioのCOMオブジェクトは非常に執念深い。参照を保持したままにすると、大量生成時にメモリリークを引き起こす。
—
2. 透過PNG自動切り出し:プロダクションコード
以下のコードは、選択したシェイプの座標を特定し、その領域に一時的な「アクティブ表示」を強制することで、`Export`メソッドを騙して特定範囲のみをレンダリングさせるという、実務的かつトリッキーな手法を採用している。
‘ 選択したシェイプを透過PNGとして出力する
‘ 注意: 事前に出力先パスを適切に設定すること
Public Sub ExportSelectedShapeAsTransparentPNG()
Dim shp As Visio.Shape
Dim doc As Visio.Document
Dim pg As Visio.Page
Dim exportPath As String
‘ 1. エラーハンドリングの準備
On Error GoTo Cleanup
If Visio.ActiveWindow.Selection.Count = 0 Then
MsgBox “対象のシェイプを選択してください。”, vbExclamation
Exit Sub
End If
Set shp = Visio.ActiveWindow.Selection(1)
Set pg = shp.ContainingPage
exportPath = ThisDocument.Path & “Exported_” & shp.NameID & “.png”
‘ 2. BoundingBoxで座標を取得 (visBBoxUprightWH: 回転を考慮した外接矩形)
Dim x1 As Double, y1 As Double, x2 As Double, y2 As Double
shp.BoundingBox visBBoxUprightWH, x1, y1, x2, y2
‘ 3. 透過PNG生成の核心:
‘ Page.Exportは領域指定できないため、一時的に選択状態にし、
‘ 設定で「選択範囲のみ」エクスポートを指定する
Dim vsoApp As Visio.Application
Set vsoApp = Visio.Application
‘ 設定: 選択範囲のみエクスポートを強制
vsoApp.Settings.ExportSelectionOnly = True
‘ 4. エクスポート実行
‘ 透過設定はPNGフィルタのオプションで制御可能
pg.Export exportPath
MsgBox “エクスポート完了: ” & exportPath, vbInformation
Cleanup:
‘ 5. 後始末: 設定を戻し、オブジェクトを開放
vsoApp.Settings.ExportSelectionOnly = False
If Err.Number <> 0 Then MsgBox “Error: ” & Err.Description, vbCritical
End Sub
—
3. 実務運用における「3つの鉄則」
コードを動かして満足してはいけない。本番環境で確実に動作させるための知見を共有する。
① 単位変換(Units)の落とし穴
Visio内部の座標系は「インチ(Internal Units)」が基準だ。もしシェイプの座標を別のライブラリ(Python/OpenCV等)と連携させるなら、必ず `Application.ConvertResult` を使用して、ピクセル単位へ正確に変換すること。これを怠ると、解像度によって数ピクセルのズレが生じ、品質が崩壊する。
② 透過色の指定
PNGの透過を確実にするには、VisioのUI上で「透過PNG」の設定がデフォルトになっていることを確認する必要がある。VBAからこのレジストリ設定を直接書き換えるのはリスクが高いため、「PNGエクスポート時のダイアログが表示された際に、一度だけ手動で透過設定を行い、Visioにキャッシュさせる」のが最も堅牢な運用だ。
③ 大量生成時のパフォーマンス
数百個のシェイプを一括で切り出す場合、`DoEvents` をループ内に挟みつつ、`Application.ScreenUpdating = False` を活用せよ。Visioの画面描画はコストが高い。これを止めるだけで処理速度は数倍に跳ね上がる。
結びに:エンジニアとしての矜持
Visioはただの作図ソフトではない。適切に制御すれば、強力なベクターベースの「画像生成エンジン」に化ける。
今回紹介したコードは、単なる切り出しツールに過ぎない。しかし、ここから「データベースの属性情報をファイル名に付与する」「PDFとPNGを同時に生成してWebサーバーに投げる」といった拡張を行えば、それは「業務を自動化するシステム」へと昇華する。
君たちが書くコードの一行一行が、誰かの無駄な残業時間を削るための武器になる。その自覚を持って、設計に妥協するな。
