【実務・中級編】【全対象】PDF出力後のファイルサイズをVBAでチェックし、規定値を超えた場合に警告を出す – Visio VBA解析バイブル

スポンサーリンク

【Visio VBA極限ノウハウ】肥大化したPDFを見逃すな!VBAによる動的ファイルサイズ監視&品質管理システムの構築

開発プロジェクトの現場において、Visioで作成した図面をPDF化して関係者に配布するプロセスは日常茶飯事だ。しかし、ここで一つの深刻な問題が発生する。
「気づいたらPDFのファイルサイズが数十MBに膨れ上がり、メールサーバーの容量制限を突破して送信エラーを引き起こす」というトラブルだ。

CADデータや高解像度のラスタ画像が図面に埋め込まれた瞬間、VisioのPDF出力は暴走する。これを人力の目視チェックに頼るなど、エンジニアリングの放棄に他ならない。

今回は、Visio VBAを用いて図面のPDFエクスポートを実行し、その直後にファイルシステム(FSO)で厳密にサイズを検証。規定値を超過した場合には即座にアラートを発出する、実務直結の「品質管理オートメーション」の全貌を伝授する。

—

1. なぜ「力技のPDF出力」は現場を崩壊させるのか?

多くのプログラマブルでないVBA初心者は、単に `Document.Export` メソッドを叩いて処理を終わらせる。

‘ 【アンチパターン】エラーハンドリングもサイズチェックもない危険なコード
ActiveDocument.Export “C:\Output\NetworkDiagram.pdf”

このアプローチが実務で破綻する理由は明確だ。
1. サイレント肥大化: 誰かが図面に重い画像を貼り付けても、出力するまで誰も気づかない。
2. サイレントエラー: ディスク容量の枯渇やファイルロックによる書き込み失敗を検知できない。
3. トレーサビリティの欠如: 「どの図面が、いつ、何MBで出力されたか」のログが残らないため、トラブルシューティングが不可能。

我々が目指すべきは、「出力・計測・検証・通知」のライフサイクルを完全自動化し、人の手によるミスをシステム的に排除した堅牢なアーキテクチャである。

—

2. 堅牢な設計思想:ファイルサイズ監視システムの要件

今回のプロダクションコードで実装するコアロジックの要件は以下の通りだ。

  • 完全修飾パスの動的生成: 実行時のカレントディレクトリに依存せず、VSDX本体と同じ階層、あるいは指定された安全なパスへ確実に出力する。
  • Scripting.FileSystemObject (FSO) による厳密なバイト数取得: `FileLen` 関数よりも堅牢なFSOを使い、正確なファイルサイズ(MB換算)を算出する。
  • スレッショルド(閾値)の定数化: 警告を発報する境界値(例: 5.0 MB)をコード上部で一元管理する。
  • 拡張エラーハンドリング: PDFエクスポート中の予期せぬCOM例外や、ファイルアクセス競合を確実にキャッチする。

—

3. 【プロダクションコード】全自動PDF品質管理マクロ

以下のコードをVisioの標準モジュールに貼り付けて実行してほしい。実務の現場でそのまま稼働する、エラー耐性の高い実装だ。

Option Explicit

‘ ==============================================================================
‘ モジュール名: modPdfQualityControl
‘ 概要: Visio図面のPDF出力と、ファイルサイズに基づく品質管理(警告)を行う
‘ 著者: チーフアーキテクト
‘ ==============================================================================

‘ 許容する最大ファイルサイズ (MB)
Private Const MAX_ALLOWABLE_SIZE_MB As Double = 5.0

Public Sub ExportAndValidatePdf()
Dim targetDoc As Visio.Document
Dim vdxPath As String, pdfPath As String
Dim fso As Object
Dim targetFile As Object
Dim fileSizeMB As Double

‘ 1. アクティブドキュメントの存在確認
If Visio.Application.Documents.Count = 0 Then
MsgBox “処理対象となる図面が開かれていません。”, vbCritical, “致命的エラー”
Exit Sub
End If

Set targetDoc = Visio.ActiveDocument

‘ 2. 未保存ドキュメント(新規図面)の場合はパスがないため弾く
If targetDoc.Path = “” Then
MsgBox “この図面はまだ保存されていません。一度保存してから実行してください。”, vbExclamation, “未保存ドキュメント”
Exit Sub
vbExit:
End If

‘ 3. 出力パスの動的構築 (VSDXと同階層、同名で拡張子をPDFに置換)
vdxPath = targetDoc.FullName
pdfPath = Left(vdxPath, InStrRev(vdxPath, “.”) – 1) & “.pdf”

On Error GoTo ErrorHandler

‘ 4. PDFエクスポートの実行
‘ ※ VisioのExportメソッドは指定パスに同名ファイルがある場合、確認なしで上書きする
Debug.Print “PDFエクスポート開始: ” & pdfPath
targetDoc.Export pdfPath

‘ 5. FileSystemObject (FSO) によるファイルサイズ検証
Set fso = CreateObject(“Scripting.FileSystemObject”)

If Not fso.FileExists(pdfPath) Then
Err.Raise 9999, “ExportAndValidatePdf”, “PDFファイルの生成を確認できませんでした。”
End If

Set targetFile = fso.GetFile(pdfPath)

‘ バイトからメガバイトへ変換 (1MB = 1,024 1,024 bytes)
fileSizeMB = targetFile.Size / (1024 1024)

‘ オブジェクトの解放
Set targetFile = Nothing
Set fso = Nothing

‘ 6. 閾値判定と結果通知
If fileSizeMB > MAX_ALLOWABLE_SIZE_MB Then
‘ 規定値を超過した場合の警告(赤信号)
MsgBox “【品質警告】生成されたPDFのファイルサイズが規定値を超過しています!” & vbCrLf & vbCrLf & _
“・ファイル名: ” & fso.GetFileName(pdfPath) & vbCrLf & _
“・実測サイズ: ” & Format(fileSizeMB, “0.00”) & ” MB” & vbCrLf & _
“・許容上限: ” & Format(MAX_ALLOWABLE_SIZE_MB, “0.00”) & ” MB” & vbCrLf & vbCrLf & _
“図面内の不要な高解像度画像やCADデータの肥大化を確認してください。”, _
vbExclamation + vbSystemModal, “PDFサイズオーバー警告”
Else
‘ 正常終了
MsgBox “PDFのエクスポートおよび品質チェックが完了しました。” & vbCrLf & _
“ファイルサイズ: ” & Format(fileSizeMB, “0.00”) & ” MB (正常)”, _
vbInformation, “処理完了”
End If

Exit Sub

ErrorHandler:
‘ 7. 異常系ハンドリング
Dim errDesc As String
errDesc = Err.Description

‘ オブジェクトの確実な解放
If Not targetFile Is Nothing Then Set targetFile = Nothing
If Not fso Is Nothing Then Set fso = Nothing

MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“内容: ” & errDesc, vbCritical, “システムエラー”
End Sub

—

4. チーフアーキテクトが解説する実装の急所

このコードを実務展開するにあたり、エンジニアが押さえておくべき「設計上の肝」を解説する。

① `FileLen` ではなく `Scripting.FileSystemObject` を使う理由

VBA標準の `FileLen` 関数は、ファイルが何らかのプロセス(プレビューウィンドウや他のアプリ)によってロックされている場合や、ネットワークパスの遅延時に不安定になる特性を持つ。
一方、FSOの `GetFile(path).Size` は、OSレベルのファイルストリームからダイレクトかつ正確にバイト数を取得できるため、エンタープライズ環境において圧倒的に信頼性が高い。

② ファイルロックとアトミック性への配慮

Visioの `Export` メソッドは非常に強力だが、巨大な図面を描画・変換する際、OSのファイル書き込み完了とVBAの制御復帰にわずかなタイムラグが生じる危険性がある。
今回のコードでは、`Export` 実行直後にFSOで `FileExists` とサイズ取得を行っているが、もし超巨大図面で「ファイルサイズが0バイトで取得される」あるいは「書き込み競合エラー」が発生する場合は、以下のようなウェイト(スリープ)を挟むロジックに拡張すると完璧だ。

‘ 必要に応じたウェイト挿入の例(APIによるミリ秒待機)
‘ DoEvents を挟むことでVisioのUIフリーズを回避

③ `vbSystemModal` によるアテンションコントロール

警告メッセージボックスに `vbSystemModal` を付与している点に注目してほしい。
バックグラウンドで大量の図面処理(バッチ処理)を行う際、通常のモーダルダイアログだと他のウィンドウの裏に隠れてしまい、オペレーターが気づかずに処理がストップしてしまう。システムモーダルにすることで、ユーザーに必ず警告を認知させることが可能になる。

—

5. さらなる高みへ:データベース・メール連携への拡張

このコードを単なる「ポップアップ警告」で終わらせてはならない。真の自動化エンジニアであれば、ここからさらにシステムを拡張する。

1. ログのDB蓄積:
`fileSizeMB` が閾値を超えた瞬間、ADODBを使って社内のSQL ServerやSQLiteへ「誰が・どの図面を・何MBで出力したか」を自動INSERTする。これにより、組織全体のドキュメント肥大化トレンドを可視化できる。
2. Teams / Slack Webhook連携:
閾値オーバー時に、VBAから直接Microsoft TeamsやSlackのIncoming WebhookへJSONをPOSTし、開発チャネルにアラートを飛ばす。

‘ (イメージ)チャット通知用HTTPリクエストの骨子
‘ Dim http As Object
‘ Set http = CreateObject(“MSXML2.XMLHTTP”)
‘ http.Open “POST”, “https://hooks.slack.com/services/…”, False
‘ http.Send “{“”text””:””【警告】図面のPDFサイズが上限を超過しました: ” & fileSizeMB & “MB””}”

—

総括

「動けばいい」という妥協の産物は、必ず現場の運用コストとなって自分に跳ね返ってくる。
今回紹介したVisio VBAによるPDFサイズ監視メカニズムは、単なるコード片ではなく、「組織の品質を守るためのディフェンスライン」である。

あなたのプロジェクトにこのコードを組み込み、野放図に肥大化するドキュメント文化をエンジニアリングの力でねじ伏せてほしい。

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