Visio PDF出力の「フォント爆弾」を無力化せよ:実務を止めない事前検証ロジック
エンジニア諸君。業務自動化の現場で、VisioのPDF出力時に「フォントの埋め込みに失敗しました」という非情なエラーメッセージに泣かされた経験はないだろうか。
特に、配布されたテンプレートや、継ぎ接ぎされたレガシーな図面を扱う際、このエラーは「PDF出力」というクリティカルなフェーズで突如として牙を剥く。なぜなら、Visioの描画エンジンは、PDF変換の瞬間に初めてフォントのサブセット作成や埋め込み可否を検証するからだ。
今回は、この「地雷」をPDF出力前に確実に検知し、運用を止めることのない堅牢な事前チェックロジックを伝授する。
なぜ「PDF出力時のエラー」を後手に回してはいけないのか
Visioのフォント問題は、単なる「表示」の問題ではない。PDF変換エンジン(Adobe PDFやMicrosoft Print to PDF)の制約、さらにクライアントPCにインストールされているフォントライブラリの不一致が複合的に絡み合う。
出力後にエラーが出てから原因を探るのは、自動化ツールとしては失格だ。「出力前に、図面内に存在する全シェイプのフォント属性を走査し、埋め込み不可(または許可されていない)フォントをリストアップする」。このプロセスを自動化パイプラインに組み込むことが、真のエンジニアリングというものだ。
堅牢な検証ロジック:実装の設計思想
以下のコードでは、以下の3つのレイヤーでフォントを検証する。
1. Page層の走査: 図面内の全ページを巡回。
2. Shape層の走査: `Characters.CharProps` を用いて、各シェイプのフォント属性を抽出。
3. ホワイトリスト方式: 埋め込みを許可するフォント以外を「リスク」として判定。
プロダクションコード:FontValidator
このコードは、モジュールに貼り付けてすぐに使えるよう設計している。
Option Explicit
‘ 埋め込みを許可する安全なフォントのリスト(環境に合わせて拡張せよ)
Private Const ALLOWED_FONTS As String = “MS Gothic,MS PGothic,Arial,Calibri,Segoe UI”
Public Sub ValidateFontsBeforeExport()
Dim doc As Visio.Document: Set doc = ActiveDocument
Dim pg As Visio.Page
Dim shp As Visio.Shape
Dim fontName As String
Dim isErrorFound As Boolean: isErrorFound = False
Debug.Print “— フォント検証開始 —”
For Each pg In doc.Pages
For Each shp In pg.Shapes
‘ シェイプにテキストが存在する場合のみ検証
If shp.Text <> “” Then
‘ CharProps(visCharacterFont) でフォントIDを取得し名称へ変換
fontName = doc.Fonts(shp.Cells(“Char.Font”).ResultIU).Name
‘ ホワイトリストに含まれないフォントを検出
If InStr(ALLOWED_FONTS, fontName) = 0 Then
Debug.Print “警告: 不適切なフォントを検出 -> [Page: ” & pg.Name & “] [Shape: ” & shp.Name & “] Font: ” & fontName
isErrorFound = True
End If
End If
Next
Next
If isErrorFound Then
MsgBox “フォントの埋め込みエラーが発生する可能性があります。” & vbCrLf & _
“デバッグウィンドウで詳細を確認し、フォントを修正してください。”, vbCritical
Else
MsgBox “フォント検証完了:問題なし。”, vbInformation
End If
End Sub
この設計の「鋭さ」
このコードのポイントは、`shp.Cells(“Char.Font”).ResultIU` を使用している点だ。シェイプのプロパティを直接参照するのではなく、Visioの内部セルを参照することで、フォント名が空文字であるような異常なシェイプや、グループ化された複雑な階層構造であっても、確実にフォント属性をキャッチできる。
運用上の注意点
- フォントIDの扱い: `doc.Fonts` コレクションはドキュメントごとに保持される。複数の図面を横断して検証する場合は、常に `ActiveDocument` を正しく指定すること。
- パフォーマンス: 数千のシェイプを持つ巨大な図面では、再帰的なシェイプ探索(`Shape.Shapes` のネスト)が必要になる場合がある。その際は、再帰関数を別途定義してスタックオーバーフローを回避する設計が必須となる。
最後に:自動化とは「予防」である
エラーハンドリングを「事後処理」と考えるのは三流だ。真の自動化エンジニアは、システムがエラーを吐く前に、その原因を論理的に遮断する。
今回紹介したロジックを、PDF出力ボタンの「前処理」として組み込むだけで、あなたのチームの生産性は劇的に向上するはずだ。明日から、エラーで止まるツールをゼロにしよう。質問があればいつでも受け付ける。健闘を祈る。
