【入門編】【上級者向け】置換処理の「Undo(元に戻す)」をプログラムで制御するグループ化 – Word VBA解析バイブル

スポンサーリンク

こんにちは! Word VBAの世界へようこそ。
マクロの記録ボタンを押してコードを眺める段階を卒業し、「自分の手で自由自在にドキュメントを操りたい」と感じ始めているなら、あなたは今、最もエンジニアとして面白い領域に足を踏み入れています。

さて、今回はWord VBAの上級者が必ずぶつかる壁であり、かつ実務で圧倒的な差をつける「Undo(元に戻す)の制御」についてお話しします。

「複数の置換処理を走らせたら、Ctrl+Zで戻すときに1回ずつしか戻せなくてユーザーが困っている……」
そんな現場の悲鳴を解決する、プロの技を授けましょう。ここをクリアすれば、あなたの作るマクロは一気に「プロフェッショナルなアプリケーション」の品格を帯びます。

—

なぜ、通常の置換マクロは「元に戻す(Undo)」がつらいのか?

Word VBAで `Find.Execute` を使ってドキュメント内の文字をガンガン置換していく処理を書いたとします。例えば、全角英数を半角にしたり、独自の専門用語を統一したりと、5つの置換を連続して実行したとします。

処理が終わった後、ユーザーが「あ、やっぱり今の置換、全部ナシにしたい!」と思って「Ctrl + Z(元に戻す)」を押すとどうなるでしょうか?

なんと、1回「Ctrl + Z」を押しても、5つの置換のうち「最後の1つ」しか戻りません。
ユーザーは「Ctrl + Z」を5回も連打しなければならず、場合によっては文書がぐちゃぐちゃになってしまいます。これでは実務で使ってもらうには少し不安ですよね。

この問題を解決するのが、Word 2010から導入された `UndoRecord`(アンドゥレコード)オブジェクト です。

—

救世主 `UndoRecord` とは?

`UndoRecord` は、一言で言うと「複数のVBAの動きを、ユーザー目線での『1つの操作』に束ねるマジックボックス」です。

このボックスの中に「置換処理A」「置換処理B」「置換処理C」を入れておくと、Wordはそれをまとめて1つの履歴として認識します。そのため、ユーザーが「Ctrl + Z」を1回押すだけで、ボックスの中の処理がまとめて一網打尽に「元に戻る」ようになるのです。

図解:Undoの挙動イメージ

  • 通常の実装:

`[置換1]` (Ctrl+Z) ⬅ `[置換2]` (Ctrl+Z) ⬅ `[置換3]` (Ctrl+Z) ※バラバラ

  • UndoRecord適用後:

`[ まとめて1つの操作として記録されたブロック ]` ⬅ これが「Ctrl+Z」1回で消える!

—

実践! 複数の置換を1つに束ねるプロのコード

百聞は一見に如かず。実際に `UndoRecord` を使った堅牢な置換処理のコードを見てみましょう。
そのままコピペして、WordのVBAエディタ(Alt + F11)に貼り付けて動かしてみてください。

Sub BatchReplaceWithUndo()
Dim objUndo As UndoRecord
Dim rngTarget As Range

‘ 1. 処理対象の範囲を定義(今回は文書全体)
Set rngTarget = ActiveDocument.Content

‘ 2. UndoRecordオブジェクトの取得
Set objUndo = Application.UndoRecord

‘ 3. 「元に戻す」のひとかたまり(カスタム単位)を開始する
‘ 引数には、Ctrl+Zを押したときに「元に戻す:〇〇」と表示される名前を指定します
objUndo.StartCustomDocumentRecord “一括置換処理(専門用語の統一)”

On Error GoTo ErrorHandler ‘ 予期せぬエラー時にUndoを確実に閉じるための保険

‘ — ここから実際の置換処理(複数) —

‘ 置換その1:「VBA」を「Visual Basic for Applications」に
With rngTarget.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = “VBA”
.Replacement.Text = “Visual Basic for Applications”
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = True
.Execute Replace:=wdReplaceAll
End With

‘ 置換その2:「エクセル」を「Excel」に
With rngTarget.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = “エクセル”
.Replacement.Text = “Excel”
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.Execute Replace:=wdReplaceAll
End With

‘ 置換その3:「ワード」を「Word」に
With rngTarget.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = “ワード”
.Replacement.Text = “Word”
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.Execute Replace:=wdReplaceAll
End With

‘ — 置換処理ここまで —

ErrorHandler:
If Err.Number <> 0 Then
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
End If

‘ 4. 必ずUndoRecordの記録を終了する(これが超重要!)
objUndo.EndCustomDocumentRecord

‘ オブジェクトの解放
Set objUndo = Nothing
Set rngTarget = Nothing

MsgBox “一括置換が完了しました。「Ctrl + Z」で一気に元に戻せるか確認してみてください。”, vbInformation
End Sub

—

コードの核心:ここがポイント!

上記のコードで、特に重要なポイントを3つ解説します。

① `Application.UndoRecord` でインスタンス化する

Wordのアプリケーション全体を管理する `Application` オブジェクトから、Undoの記録係を呼び出します。これがグループ化の窓口となります。

② `StartCustomDocumentRecord` と `EndCustomDocumentRecord` で挟む

この2つのメソッドの間で行われたWordの変更(今回は置換)は、すべて1つのグループとしてパッケージングされます。
`StartCustomDocumentRecord` の引数に渡した文字列(例: `”一括置換処理(専門用語の統一)”`)は、Wordの「元に戻す」ボタンの横に小さく表示される名前になります。ここを分かりやすく書いておくと、ユーザー親切度が爆上がりします。

③ エラーハンドリング(`On Error GoTo`)との組み合わせ

ここがエンジニアとしての腕の見せ所です。
もし `StartCustomDocumentRecord` を呼び出した後にVBAのエラーでプログラムが強制終了してしまったらどうなるでしょうか? Wordは「記録中」のフリーズ状態のままになり、最悪の場合ドキュメントが破損したり、Word自体が不安定になります。

そのため、必ずエラー時や終了時を想定し、どんな状況でも確実に `EndCustomDocumentRecord` を通る仕組み(または安全な閉じ方)を作っておくことが、実務で耐えうる堅牢なコードの絶対条件です。

—

先輩エンジニアからの温かいアドバイス

今回は「複数の置換を1つにまとめる」というテーマで `UndoRecord` を解説しましたが、これは置換だけでなく、「複数箇所の表の整形」「スタイルの動的適用」「一括削除と挿入のセット」など、あらゆるマクロに応用できます。

「動けばいいや」のコードから、「使う人の使いやすさと安全性まで配慮された」プロのコードへ。
この `UndoRecord` を使いこなせるようになったあなたなら、もう初級者ではありません。自信を持って、周囲を驚かせるような自動化ツールを作ってくださいね。

ここをクリアできれば、Word VBAの表現力は一気に何倍も広がります。
あなたの自動化ライフが、より素晴らしいものになりますように!

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