【入門編】【中級者向け】複数のVSDXファイルを結合し、1つのPDFファイルとして出力する際のページ順序制御 – Visio VBA解析バイブル

スポンサーリンク

こんにちは! Visio VBAの世界へようこそ。
マクロの記録ボタンを押して「動いたはいいけれど、中身が全然読めない……」と頭を抱えていませんか? 大丈夫、ここをクリアすれば、あなたも立派なVisio自動化エンジニアの仲間入りです。

今回は、現場で本当によくある要望――「複数の別々なVisioファイル(.vsdx)を1つに結合し、綺麗なページ順に並べ替えてから、一発でPDF出力する」というテーマを深掘りします。

単にファイルを開いて閉じるだけなら簡単ですが、「ページ順序のコントロール」と「Visio特有の重いメモリ管理」を意識しないと、あっという間にVBAがフリーズしたり、ページがバラバラの迷子PDFが出来上がったりします。

先輩エンジニアが、実戦でそのまま使える極上のコードと共にお手伝いします。一緒に見ていきましょう!

—

1. なぜ複数VisioのPDF化は一筋縄ではいかないのか?

Visioファイルを結合してPDFにする際、初学者が直面する壁は主に2つあります。

1. ページの「絶対順序」の罠
Visioのドキュメントは、それぞれが独立した「ページ(Pageオブジェクト)」を持っています。ファイルをただ順番に開くだけでは、PDF化したときに「ファイルAのページ1 ➔ ファイルBのページ1 ➔ ファイルAのページ2……」のような意図しない順番になってしまいがちです。これを「ファイル単位できれいに連結」するには、ページの移動・挿入ロジックが必要です。
2. メモリリークとオブジェクトの寿命(Life Cycle)
VisioはOffice製品の中でも特にグラフィック描画のメモリ消費が激しいアプリケーションです。「開いて、処理して、閉じる」を雑に行うと、背後でプロセスが残り続け、PCが重くなったりエラー落ちしたりします。

これらを綺麗に解決するスマートなコードを書いていきましょう。

—

2. 全体アーキテクチャ:どうやって結合するのか?

今回の戦略はこうです:

1. マスターとなる新規Visioファイルを作る(これが結合後の受け皿になります)。
2. 結合したいファイルのリストを上から順に読み込む。
3. 読み込んだファイルの各ページを、マスターファイルの末尾にコピー(または移動)していく。
4. 最後に、マスターファイルを意図したページ順に並べ替え、一気にPDFとして書き出す。
5. 開いたファイルは確実にメモリから解放(アンロード)する。

言葉だけだと難しそうですが、コードにすると非常にエレガントです。

—

3. 実装コード:一撃でPDF化する魔法のマクロ

以下のコードを、VisioのVBE(Visual Basic Editor)の標準モジュールに貼り付けてください。

Option Explicit

Sub MergeVisioFilesToPDF()
‘ =========================================================================
‘ 複数VSDXファイルを結合し、1つのPDFとして出力するマクロ
‘ =========================================================================

Dim masterDoc As Visio.Document
Dim targetDoc As Visio.Document
Dim targetPage As Visio.Page
Dim newPage As Visio.Page

‘ 結合したいファイルのパス(実際の環境に合わせて変更してください)
Dim filePaths(1 To 2) As String
filePaths(1) = “C:\VisioData\Part1.vsdx”
filePaths(2) = “C:\VisioData\Part2.vsdx”

Dim pdfOutputPath As String
pdfOutputPath = “C:\VisioData\MergedOutput.pdf”

On Error GoTo ErrorHandler

‘ 画面描画を停止して処理を爆速化&チラつき防止
Application.ScreenUpdating = False
Application.ShowAlerts = False

‘ 1. 受け皿となるマスタードキュメントを新規作成(空白の図面)
Set masterDoc = Documents.Add(“”)

‘ 初期作成時に含まれているデフォルトの余分なページを後で整理するため保持
Dim initialPageCount As Long
initialPageCount = masterDoc.Pages.Count

Dim i As Long
Dim j As Long

‘ 2. 対象ファイルを順番に開いて、ページをマスターに集約する
For i = LBound(filePaths) To UBound(filePaths)
‘ 読み取り専用(“OpenRO”)かつバックグラウンドで開く
Set targetDoc = Documents.OpenEx(filePaths(i), visOpenRO + visOpenHidden)

‘ 各ファイルの全ページをループ
For j = 1 To targetDoc.Pages.Count
Set targetPage = targetDoc.Pages(j)

‘ ページの複製をマスタードキュメントの末尾に追加
‘ ※ Visioでは Page.Duplicate を使うか、図形をコピーする手法がありますが、
‘ 今回はシンプルに「ページを追加して図形を丸ごとコピペ」する王道手法を使います
Set newPage = masterDoc.Pages.Add()
newPage.NameU = “Combined_” & i & “_” & j ‘ 一意の名前をつけておく

‘ ページ全体の図形をコピー&ペースト
targetPage.PageSheet.DrawingChanged ‘ 念のため状態確定
targetPage.Shapes.DropManyStencils Nothing, Nothing ‘ ※簡易的には以下のように全選択コピーが安全です

targetPage.Shapes.SelectAll
ActiveWindow.Selection.Copy
masterDoc.UI.Activate
newPage.Paste
Next j

‘ 読み込んだドキュメントを保存せずに閉じる(メモリ解放の鉄則!)
targetDoc.Close
Set targetDoc = Nothing
Next i

‘ 3. 最初からマスターにあった余分な初期ページを削除
For j = initialPageCount To 1 Step -1
If masterDoc.Pages.Count > 1 Then
masterDoc.Pages(j).Delete
End If
Next j

‘ 4. 1つのPDFとしてエクスポート
‘ Visioの Export メス(メソッド)を使用
masterDoc.ExportAsFixedFormat visFixedFormatPDF, pdfOutputPath, visDocExIntentPrint, visPrintAll

‘ 5. マスタードキュメントを保存せずに閉じる
masterDoc.Close
Set masterDoc = Nothing

‘ 処理終了の通知
Application.ScreenUpdating = True
Application.ShowAlerts = True
MsgBox “PDFの結合と出力が完了しました!” & vbCrLf & pdfOutputPath, vbInformation, “成功”
Exit Sub

ErrorHandler:
‘ エラー時のクリーンアップ(メモリリーク防止)
Application.ScreenUpdating = True
Application.ShowAlerts = True

If Not targetDoc Is Nothing Then
targetDoc.Close
Set targetDoc = Nothing
End If
If Not masterDoc Is Nothing Then
masterDoc.Close
Set masterDoc = Nothing
End If

MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “異常終了”
End Sub

—

4. コードの重要ポイントと「知っておくべき極意」

初学者のうちから意識してほしい、このコードのキモを解説します。

① `Application.ScreenUpdating = False` の絶大な効果

Visioはページをペーストするたびに、画面上のグラフィックを再描画しようとします。これが処理を劇的に重くする原因です。処理の最初に画面描画を止め、最後に復帰させることで、実行スピードが数倍〜十数倍に跳ね上がります。

② `Documents.OpenEx` でスマートに開く

ただの `Documents.Open` ではなく、`visOpenRO + visOpenHidden` を使っています。

  • `visOpenRO`(Read Only): 誤って大元のファイルを書き換えてしまう事故を防ぎます。
  • `visOpenHidden`: ファイルを開くときのウィンドウの「チラつき」を完全に消し去ります。裏側でこっそりスマートに処理するのがプロの技です。

③ エラーハンドリングと `Nothing` 代入の美学

VBAで最も怖いのは、途中でエラーが起きたときにファイルが開いたままプロセスに残ることです。
`ErrorHandler:` ラベルを用意し、万が一の際にも必ず `targetDoc.Close` や `masterDoc.Close` を通るように設計しています。さらに使い終わったオブジェクト変数には `Set targetDoc = Nothing` を入れてメモリを即座に解放する。これがVisio VBAで絶対にバグらせないための極意です。

—

5. よくあるつまずきポイント(Q&A)

Q. ページをコピーしたときに、図形の位置やサイズがズレてしまいます。
A. Visioのページサイズ(用紙サイズ)が結合元ファイル同士で異なっていると、コピー先のページサイズに引きずられてレイアウトが崩れることがあります。あらかじめ結合するすべてのVisioファイルの「デザイン > ページ設定」で用紙サイズ(例:A4横など)を統一しておくのが、綺麗にPDF化する最大のコツです。

Q. ページ順序を自分の好きな順番に並べ替えたいです。
A. Visioのページは、作成された順番(インデックス番号)で管理されています。もし並び順をコントロールしたい場合は、コード内でページを追加する順番を制御するか、追加したあとに `Page.Position` プロパティを使ってページの並び順をプログラムから入れ替えてみてください。

—

まとめ

今回は「複数のVSDXファイルを結合し、綺麗な順序でPDF化する」という、実務で非常に価値の高いテーマを解説しました。

  • 画面描画を止めて爆速化する
  • 裏側でひっそり開いて(Hidden)、読み取り専用(RO)で安全に処理する
  • 使い終わったら確実に閉じ、`Nothing` でメモリを掃除する

この3つを抑えておけば、Visio VBAの扱いはもう初心者卒業です。
ぜひご自身の業務環境に合わせてファイルパスなどを書き換え、自動化の爽快感を味わってみてくださいね。

ここをクリアすれば、あなたのVBAライフはもっと自由で楽しいものになりますよ!それでは、次回の記事もお楽しみに。

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