こんにちは! Visio VBAの自動化の世界へようこそ。
マクロの記録ボタンを押してコードを覗いてみたものの、「なんだか呪文みたいなコードばかりで、どう直したらいいかわからない……」と悩んでいませんか?
大丈夫、安心してください。ここをクリアすれば、あなたのVisio VBAスキルは確実に次のステージへと進みます。
今回は、実務の現場で「おっ、やるな!」と思わせるスマートなテクニック、`Document.Saved`プロパティを使った無駄な上書きセーブを防ぐ設計術を徹底解説します。
自動処理が終わったあとに、変な保存確認ダイアログが出て作業がストップするイライラとは、今日でお別れしましょう。
—
なぜ「保存確認ダイアログ」にイライラするのか?
Visioでマクロを組んで大量の図形を整列させたり、データを流し込んだりする自動化処理を作ると、最後に必ずこんな壁にぶつかります。
- 「処理は一瞬で終わったのに、閉じる時に『変更を保存しますか?』と聞いてくる」
- 「プログラムで勝手に上書き保存したら、変更してないファイルまでタイムスタンプが更新されて管理が面倒くさい」
マクロが走ったのだから、何かしらファイルに手が加わっているはず……と思ってしまいますよね。でも、「プログラムで処理を実行したけれど、結果的に図面の中身は1ミリも変わっていない」というケースは実務ではよくあります。
そんなとき、人間が判断するのではなく、Visioのドキュメント自身に「ねえ、ボクのどこか変わった?」と賢く問いかける方法が、今回お伝えする`Document.Saved`プロパティです。
—
Document.Savedプロパティの正体
Visioの裏側では、すべてのドキュメント(`Document`オブジェクト)が「最後に保存されてから変更されたかどうか」の状態を、真偽値(`True` または `False`)でこっそり持っています。
それが `Document.Saved` です。
- `ActiveDocument.Saved = True`
「最後に保存されてから、中身は一切変わっていません!」(未保存の変更なし)
- `ActiveDocument.Saved = False`
「おっと、どこかが変更されましたよ!」(未保存の変更あり)
非常にシンプルですが、ここにはプログラミングにおける極めて重要な本質が隠されています。
実はこのプロパティ、「読む(取得する)」だけでなく「書く(代入する)」こともできるのです。ここを使いこなせるかどうかが、初心者から脱却するための大きな分かれ道になります。
—
実践!スマートに判定して閉じるVBAコード
百聞は一見に如かず。実際の現場でそのまま使える、極めて洗練されたコードを見てみましょう。
このコードは、「マクロが実行された結果、本当に図面が変化したときだけ保存するかどうかをユーザーに尋ねる(あるいは自動保存する)」というスマートな制御を行います。
Sub SmartCloseDrawing()
Dim orgSavedState As Boolean
‘ 1. 現在の「保存状態」を退避しておく
orgSavedState = ActiveDocument.Saved
On Error GoTo ErrorHandler
‘ ————————————————–
‘ ここに実際の自動化処理を書く(例としてシェイプを動かすなど)
‘ ————————————————–
Dim shp As Visio.Shape
For Each shp Ex In ActivePage.Shapes
‘ 例:すべてのシェイプのデータを読み取るだけ(=中身は変えない)
‘ Debug.Print shp.Text
Next shp
‘ 2. 処理の結果、本当に変更があったかを判定
If ActiveDocument.Saved Then
‘ 変更がない場合:ダイアログを出さずに、変更フラグも戻して静かに閉じる
MsgBox “図面に変更はありませんでした。保存せずに閉じます。”, vbInformation
ActiveDocument.Close
Else
‘ 変更がある場合:必要に応じて保存処理を行う
Dim answer As VbMsgBoxResult
answer = MsgBox(“変更が加えられています。上書き保存しますか?”, vbYesNo + vbQuestion, “確認”)
If answer = vbYes Then
ActiveDocument.Save
ActiveDocument.Close
Else
‘ ユーザーが保存したくないと言った場合、SavedをTrueに偽装して強制終了も可能
‘ ActiveDocument.Saved = True
ActiveDocument.Close
End If
End If
Exit Sub
ErrorHandler:
‘ エラーが発生した場合は、元の保存状態を復元して異常終了を知らせる
ActiveDocument.Saved = orgSavedState
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
End Sub
コードのここがポイント!
1. 処理前の状態を退避 (`orgSavedState`)
万が一エラーで処理が途中で止まったときのために、マクロが始まる直前の「保存されていたかどうか」の状態を変数に控えておきます。プロフェッショナルなコードには、こうした「後始末への配慮」が欠かせません。
2. 無駄なダイアログの回避
`If ActiveDocument.Saved Then` で判定することで、プログラムが「何も変えていない」と判断した場合は、ユーザーに余計なクリックの手間を一切取らせません。
—
陥りやすい罠:VBAで何かすると、すぐ「False」になる
ここで、初心者が必ずハマる注意点をひとつ。
Visio VBAで図形を選択したり、色を変えたり、データを読み書きしたりすると、「たとえ見た目が変わっていなくても、内部的にドキュメントが『汚された(Dirtyになった)』と判定され、`ActiveDocument.Saved` は容赦なく `False` になります」。
例えば、「マクロで図形の位置をちょっと計算し直して、元の位置に戻した」という場合でも、Visioくんは「なんか触ったな? なら未保存フラグ立てとくか!」と判断してしまいます。
これを防ぐために、「本当に意味のある変更が加わったときだけ、手動でフラグをコントロールする」という高度なアプローチも覚えておくと完璧です。
‘ 意味のない変更(レイアウトの微調整など)であれば、強制的にSavedをTrueに戻してしまうテクニック
ActiveDocument.Saved = True
※ただし、本当にユーザーの重要な変更を消してしまわないよう、この手法を使うときは「この処理の後は保存しなくていい」と確信があるロジックの末尾だけに限定してくださいね。
—
まとめ:小さな気配りが、自動化ツールの「品格」を決める
今回は、`Document.Saved`プロパティを使ったスマートなファイル制御について解説しました。
- `ActiveDocument.Saved` でドキュメントの「変更の有無」を正確に知る。
- 変更がない場合は、無駄な保存確認を出さずにスマートに閉じる。
- エラー時や例外処理への備えを忘れない。
たったこれだけの気配りですが、毎日何度もこのマクロを使う現場のユーザーにとっては、ストレスが劇的に軽減される素晴らしいアップデートになります。「動けばいいや」のコードから、「使う人の気持ちを考え抜いた美しいコード」へ。
ここをクリアしたあなたなら、もう立派なVisio VBAエンジニアです。ぜひ、次の自動化ツールにこの知見を組み込んでみてくださいね!
