【入門編】Shape.ForeignTypeによる挿入オブジェクト判定:OLEオブジェクト・画像・図形の識別処理 – Visio VBA解析バイブル

スポンサーリンク

こんにちは。現場の最前線でVisioの自動化と向き合い続けてきた、あなたの先輩エンジニアです。

Visio VBAの世界へようこそ。マクロの記録を卒業し、自分の手でコードを書き始めると、誰もが最初にぶつかる壁があります。それは、「画面上の見た目は同じ『四角』なのに、中身が全然違うオブジェクトが混ざっている」という問題です。

普通の図形(ベクター)、貼り付けた写真(ビットマップ)、そしてExcelの表を埋め込んだもの(OLEオブジェクト)。これらを区別せずに処理しようとすると、マクロは途端に不安定になります。

今日は、Visio VBAの根幹をなす「Shapeオブジェクト」の正体を見破るための魔法の杖、`ForeignType`プロパティの使い方を伝授します。ここをマスターすれば、Visio VBAの基礎は完璧と言っても過言ではありません。

1. Shapeの「見た目」に騙されないために

Visioのページ上にあるものは、すべて「Shape(シェイプ)」と呼ばれます。しかし、その中身は大きく分けて3つの勢力に分かれています。

1. 純粋な図形: 四角や矢印など、Visioが描画するベクターデータ。
2. 画像(ビットマップ): 写真やスクリーンショット。
3. OLEオブジェクト: Excel、Word、PDFなどが「埋め込まれた」状態のもの。

これらを「一括でサイズ変更したい」「OLEオブジェクトだけ削除したい」と思った時、ただの `For Each shp In Page.Shapes` では不十分です。なぜなら、種類によって持っているプロパティや挙動が異なるからです。

そこで登場するのが、`Shape.Type``Shape.ForeignType` です。

2. 二段構えの識別:Type と ForeignType

オブジェクトを特定するには、まず「大まかな種類(Type)」を確認し、それが「外部由来(Foreign)」だった場合に「詳細な中身(ForeignType)」を覗き込む、という二段構えの手順を踏みます。

第一関門:Shape.Type

まずはそのシェイプの立ち位置を確認します。

| 定数 | 値 | 意味 |
| :— | :— | :— |
| `visTypeShape` | 3 | 通常の図形(単一) |
| `visTypeGroup` | 2 | グループ化された図形 |
| `visTypeForeign` | 4 | 外部データ(画像やOLE) |

私たちが今回注目するのは、この `visTypeForeign` です。これが出たら、「おや、中身は画像かな?それともExcelかな?」と疑うわけです。

第二関門:Shape.ForeignType

`Type` が `visTypeForeign` だった場合のみ、このプロパティが意味を持ちます。

| 定数 | 値 | 意味 |
| :— | :— | :— |
| `visFTOLE` | 1 | OLEオブジェクト(Excel/Word等) |
| `visFTBitmap` | 32 | 画像(JPG/PNG/BMP等) |

3. 実践:図面内のオブジェクトを仕分けする「Shape探偵マクロ」

では、実際に動くコードを見てみましょう。このコードは、アクティブなページにあるすべてのシェイプをスキャンし、その正体をイミディエイトウィンドウに報告するものです。

Option Explicit

‘——————————————————————-
‘ 概要: ページ内の全シェイプを走査し、その属性(図形・画像・OLE)を判別する
‘ 目的: ForeignTypeを理解し、特定のオブジェクトのみを抽出する基礎を作る
‘——————————————————————-
Public Sub IdentifyShapeTypes()
Dim vsoPage As Visio.Page
Dim vsoShape As Visio.Shape
Dim shapeInfo As String

‘ 現在表示されているページを取得
Set vsoPage = ActivePage

Debug.Print “— シェイプ解析開始 —”

‘ ページ内の全シェイプをループ
For Each vsoShape In vsoPage.Shapes

shapeInfo = “名前: ” & vsoShape.Name & ” / ”

‘ 1. まずは大きな分類(Type)をチェック
Select Case vsoShape.Type

Case visTypeForeign
‘ 2. 外部オブジェクトの場合、詳細(ForeignType)をチェック
Select Case vsoShape.ForeignType
Case visFTOLE
shapeInfo = shapeInfo & “[種別: OLEオブジェクト (Excel等)]”
Case visFTBitmap
shapeInfo = shapeInfo & “[種別: ビットマップ画像]”
Case Else
shapeInfo = shapeInfo & “[種別: その他外部データ (Metafile等)]”
End Select

Case visTypeGroup
shapeInfo = shapeInfo & “[種別: グループ図形]”

Case visTypeShape
shapeInfo = shapeInfo & “[種別: 標準的な図形]”

Case Else
shapeInfo = shapeInfo & “[種別: その他 (” & vsoShape.Type & “)]”

End Select

‘ 結果を出力
Debug.Print shapeInfo
Next vsoShape

Debug.Print “— 解析終了 —”
End Sub

コードのポイント解説

  • `Select Case` の活用: `If` 文を重ねるよりも、構造が明確になり、後から「グループ図形の中身も判定したい」といった拡張が楽になります。
  • `visTypeForeign` 判定の重要性: `ForeignType` プロパティは、通常の図形(`visTypeShape`)に対して呼び出すとエラーになることはありませんが、意味のない値(0)を返します。必ず `Type` を先に確認する癖をつけましょう。

4. 現場で役立つ「もう一歩先」の知見

チーフアーキテクトとして、あなたが実務でハマりやすいポイントを2つお伝えします。

① グループ化の罠

画像やOLEオブジェクトが「グループ化」されている場合、外側の `vsoShape.Type` は `visTypeGroup` になります。その中の個別の画像判定をしたい場合は、`vsoShape.Shapes` コレクションを再帰的に探索する必要があります。
「画像を一括削除するマクロを作ったのに、グループ化されている画像だけ消えない!」というのはよくあるトラブルです。

② OLEオブジェクトの重さ

OLEオブジェクト(Excelの埋め込みなど)は、メモリ消費が激しいのが特徴です。
大量のOLEオブジェクトが含まれる図面で `ForeignType` 判定を行いながら、さらにその中身(Excelのセル内容など)を操作しようとすると、Visioがクラッシュしやすくなります。
「判定して抽出する」ことと「操作する」ことは、分けて考えるのがプロの技です。

5. まとめ:ここをクリアすればVisio VBAは怖くない

今回は、Visioの心臓部である `Shape` オブジェクトの「正体」を見分ける方法を学びました。

  • `Type` プロパティで「大枠」を掴む。
  • `visTypeForeign` だったら `ForeignType` で「詳細(画像かOLEか)」を突き止める。

このロジックが書ければ、「図面内の写真だけを特定のフォルダに書き出す」とか、「Excelの埋め込み表だけを最新に更新する」といった、高度な自動化への扉が開きます。

Visio VBAは一見複雑ですが、オブジェクトの階層構造(Application > Document > Page > Shape)さえ掴んでしまえば、これほど強力なツールはありません。

一歩ずつ、楽しみながらコードを書いていきましょう。分からないことがあれば、いつでもまた聞きに来てくださいね。応援しています!

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