【実務・中級編】【上級者向け】VisioのPDF出力エンジンが生成するPDFのしおり(アウトライン)をVBAでカスタマイズする – Visio VBA解析バイブル

スポンサーリンク

Visioの限界を超えろ:PDFしおり(アウトライン)をVBAで完全掌握する設計思想

Visioを単なる「図面作成ツール」として使っているうちは、二流の自動化エンジニアだ。
一流のアーキテクトは、Visioを「構造化されたデータの視覚化エンジン」として定義し、その出力を後続のビジネスプロセスが最も利用しやすい形で提供する。

実務で最も要求されるのは、数百ページに及ぶ巨大な図面集を、「論理的な階層構造を持つPDF」として出力することだ。
しかし、Visio標準の `ExportAsFixedFormat` メソッドに備わっている `visFixedFormatIncludeBookmarks` オプションは、単にページ名を並べるだけの貧弱な代物であり、プロフェッショナルの要求を満たすことはない。

本稿では、Visio VBAを用いてPDFのしおり(アウトライン)を自在にカスタマイズし、ドキュメントのアクセシビリティと検索性を極限まで高めるための「メタデータ抽出」と「外部ライブラリ連携」の神髄を伝授する。

—

1. なぜ標準機能では不十分なのか

Visioの標準出力が生成するしおりには、以下の致命的な欠陥がある。

1. 階層構造の欠如: ページ間の親子関係を表現できず、フラットなリストになる。
2. ターゲットの曖昧さ: ページ内の特定のシェイプ(例えば「機能ブロック」)へ直接ジャンプさせることができない。
3. 名称の固定化: しおりの名称を、図面上のテキストやデータベース上のIDと動的に同期させることが難しい。

これを解決するには、「Visioで階層構造を定義し、PDF生成後に外部APIでアウトラインを再構築する」という2フェーズの設計が必要になる。

—

2. アーキテクチャ:メタデータ駆動型PDF生成

堅牢なシステムを構築するためのアーキテクチャは以下の通りだ。

1. データ抽出層 (VBA): ページ階層や特定シェイプの座標・名称を抽出し、中間データ(DictionaryまたはXML)を作成する。
2. PDF生成層 (VBA): `ExportAsFixedFormat` でベースとなるPDFを出力する。
3. 構造注入層 (Acrobat API / iTextSharp): PDFの内部オブジェクト(PDF Catalog)にアクセスし、VBAで作成した中間データを基にしおりを再構築する。

ここでは、最も普及している Adobe Acrobat SDK (Acrobat Pro) を利用した実装例を示す。

—

3. 実践:しおり階層を制御するプロダクションコード

以下のコードは、ページ上の特定の「見出しシェイプ」を検出し、それを階層的なしおりとしてPDFに埋め込むための骨格だ。

ステップ1:ブックマーク情報のカプセル化(クラスモジュール: `clsBookmark`)

まずは、しおりの情報を保持するクラスを作成する。これにより、データの整合性を担保する。

‘ clsBookmark (Class Module)
Public Title As String
Public PageNum As Long
Public FitType As String ‘ “FitV” や “FitH” など
Public Parent As clsBookmark
Public Children As Collection

Private Sub Class_Initialize()
Set Children = New Collection
End Sub

ステップ2:メインプロセス(標準モジュール)

ここでは、Visioから情報を抜き出し、Acrobatを介してPDFを再構築する。

Option Explicit

‘ 参照設定:
‘ 1. Microsoft Visio 16.0 Type Library
‘ 2. Adobe Acrobat 10.0 Type Library (Acrobat SDK)
‘ 3. Microsoft Scripting Runtime

Public Sub ExportProfessionalPDF()
Dim vsoDoc As Visio.Document
Set vsoDoc = ActiveDocument

Dim pdfPath As String: pdfPath = Replace(vsoDoc.FullName, “.vsdx”, “.pdf”)
Dim bookmarkList As Collection
Set bookmarkList = New Collection

‘ 1. メタデータの抽出
‘ ここでは例として、ページ名と特定のセル値を持つシェイプを抽出
ExtractBookmarkMetadata vsoDoc, bookmarkList

‘ 2. 標準PDF出力 (しおりなしで高速出力)
vsoDoc.ExportAsFixedFormat visFixedFormatPDF, pdfPath, visDocExIntentPrint, visPrintAll

‘ 3. Acrobat APIによるしおりの再構築
InjectBookmarksWithAcrobat pdfPath, bookmarkList

MsgBox “PDF Customization Complete.”, vbInformation
End Sub

Private Sub ExtractBookmarkMetadata(vsoDoc As Visio.Document, ByRef bookmarkList As Collection)
Dim vsoPage As Visio.Page
Dim bm As clsBookmark

‘ 全ページを走査し、論理構造を構築
For Each vsoPage In vsoDoc.Pages
If vsoPage.Background = False Then
Set bm = New clsBookmark
bm.Title = vsoPage.Name
bm.PageNum = vsoPage.Index – 1 ‘ Acrobatは0ベース

‘ 特定の「章」を示すシェイプがある場合、さらに階層化するロジックをここに記述
‘ 例: Set subBm = New clsBookmark … bm.Children.Add subBm

bookmarkList.Add bm
End If
Next
End Sub

Private Sub InjectBookmarksWithAcrobat(pdfPath As String, bookmarkList As Collection)
Dim gApp As Acrobat.AcroApp
Dim gPDDoc As Acrobat.AcroPDDoc
Dim jso As Object
Dim i As Long

Set gApp = CreateObject(“AcroExch.App”)
Set gPDDoc = CreateObject(“AcroExch.PDDoc”)

If gPDDoc.Open(pdfPath) Then
‘ AcrobatのJavaScript Object (JSO) を利用してしおりを操作
Set jso = gPDDoc.GetJSObject

‘ 既存のしおりを全削除(クリーンな状態にする)
‘ ※JSOのメソッドはAcrobat SDKのリファレンスを参照

Dim bm As clsBookmark
For Each bm In bookmarkList
‘ ルートしおりの追加
‘ jso.bookmarkRoot.createChild(Name, Code, Index)
‘ 第2引数にはJavaScriptのジャンプコードを指定
Dim jsCode As String
jsCode = “this.pageNum = ” & bm.PageNum & “; this.scroll(0, 792);”

jso.bookmarkRoot.createChild bm.Title, jsCode, i
i = i + 1
Next

gPDDoc.Save 1, pdfPath ‘ PDSaveFull = 1
gPDDoc.Close
End If

gApp.Exit
Set gPDDoc = Nothing
Set gApp = Nothing
End Sub

—

4. 現場で差がつく設計の要諦

1. Acrobat SDKの代替案(ライセンスとコスト)

現場によっては、全端末にAcrobat Proを導入できない場合がある。その場合、`pdftk` や `iText7` (C# wrapper) を利用したコマンドライン連携を検討せよ。VBAから `Shell` 関数で外部実行ファイルを叩き、あらかじめ作成したしおり定義ファイル(メタデータ)を読み込ませる手法だ。これは実行速度とコストのバランスにおいて非常に優れている。

2. 座標系の罠:Visio(左下) vs PDF(左上)

Visioの座標系は左下((0,0))が原点だが、PDFの内部座標系(User Unit)は多くの場合左上が原点、あるいは媒体の定義に依存する。特定のシェイプへズームさせるしおりを作る場合、この座標変換をVBA側で計算しておく必要がある。

3. 参照保持とガベージコレクション

VisioやAcrobatのプロセスは非常に重い。VBAの実行が終了してもプロセスが残る「ゾンビプロセス」を防ぐため、`Error Handling` 内でも必ず `Set obj = Nothing` を実行し、明示的に `Quit` メソッドを呼ぶ設計にせよ。

—

5. 結論:ドキュメントは「データ」である

Visio VBAの真価は、図を描くことではなく、「図の中に隠された構造を抽出し、他形式へ完璧にトランスレートすること」にある。

今回紹介したしおりのカスタマイズ手法は、単なる見栄えの問題ではない。数千枚の図面から必要な情報に0.5秒でアクセスできる仕組みを提供することは、組織の生産性を劇的に向上させる「武器」となる。

リファレンスをなぞるだけのコードは卒業しろ。オブジェクトのライフサイクルを支配し、外部エンジンを自在に操る。それが伝説的なエンジニアへの第一歩だ。

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