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

スポンサーリンク

ようこそ、Word VBAの深淵なる世界へ。
私はチーフアーキテクトとして、これまで数多くの巨大な自動化システムを設計してきましたが、Word VBAほど「奥が深く、そして愛すべき」ツールは他にありません。

マクロの記録を卒業し、自分でコードを書き始めたあなたが次に直面する壁。それは「ユーザーへの優しさ(UX)」です。

想像してみてください。あなたの作った「100箇所の表記揺れを一括修正する魔法のマクロ」を実行した後、ユーザーが「あ、やっぱり今の無し!」と思って「元に戻す(Undo)」ボタンを押したときのことを。
もし、100回連続でCtrl+Zを連打しなければならなかったら……それは魔法ではなく、呪いになってしまいます。

今日は、複数の置換処理をたった一度の「元に戻す」で完結させる、プロの必須テクニック「UndoRecord」について伝授しましょう。ここをクリアすれば、あなたのマクロは「ツール」から「製品」へと進化しますよ。

—

1. なぜ「UndoRecord」が必要なのか?

Wordの標準機能では、マクロで行った操作は「一つひとつ」が履歴(Undoスタック)に積み重なります。
例えば、5回の置換(Find.Execute)を行うコードを書いた場合、Wordの履歴には「置換」が5行並びます。

これをひとまとめの「パッケージ」にするのが、今回紹介する `UndoRecord` オブジェクト です。
これを使うことで、どれだけ複雑な処理をマクロで行っても、ユーザーはたった一回の「元に戻す」で実行前の状態に完璧に戻ることができるようになります。

—

2. UndoRecordの基本構造

使い方は非常にシンプルです。特定の「箱」の中に処理を閉じ込めるイメージを持ってください。

1. 箱を開ける (`StartCustomRecord`)
2. 中身(置換など)を実行する
3. 箱を閉じる (`EndCustomRecord`)

ただし、プロのエンジニアとして最も注意すべきは「エラーが起きた時でも必ず箱を閉じる」という点です。箱が開いたままだと、その後のWordの操作履歴がおかしくなってしまうからです。

—

3. 実践:複数の置換を一つにまとめる極限のコード

では、具体的なコードを見ていきましょう。ここでは「特定のビジネス用語の表記揺れを修正する」という実用的なシナリオを用意しました。

Sub Professional_BulkReplace_WithUndo()
‘————————————————————————-
‘ 目的: 複数の置換処理を1つのUndo履歴に統合し、安全に実行する
‘ 開発者: チーフアーキテクト
‘————————————————————————-
Dim objUndo As UndoRecord
Set objUndo = Application.UndoRecord

‘ 1. エラーハンドリングの設定(途中で失敗しても必ずUndoRecordを閉じるため)
On Error GoTo ErrorHandler

‘ 2. カスタムUndoレコードの開始
‘ 引数には、Wordの「元に戻す」メニューに表示させたい名前を指定します
objUndo.StartCustomRecord “表記揺れの一括修正”

‘ 3. 置換処理の本体
‘ ここでは例として2つの置換を実行します
Call PerformReplace(“コンピュータ”, “コンピューター”)
Call PerformReplace(“サーバー”, “サーバ”)
Call PerformReplace(” “, ” “) ‘ 連続する半角スペースを1つに

‘ 4. カスタムUndoレコードの終了
objUndo.EndCustomRecord

MsgBox “修正が完了しました。Ctrl+Zで一括で元に戻せますよ。”, vbInformation
Exit Sub

ErrorHandler:
‘ 万が一エラーが発生した場合も、開いたレコードは必ず閉じる
‘ これを忘れるとWordのUndo機能が不安定になります
If Not objUndo Is Nothing Then
objUndo.EndCustomRecord
End If
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical
End Sub

‘————————————————————————-
‘ 汎用的な置換ルーチン
‘————————————————————————-
Private Sub PerformReplace(findText As String, replaceText As String)
With ActiveDocument.Content.Find
.ClearFormatting ‘ 検索条件の初期化
.Replacement.ClearFormatting ‘ 置換後の書式の初期化
.Text = findText
.Replacement.Text = replaceText
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = False

‘ 全て置換を実行
.Execute Replace:=wdReplaceAll
End With
End Sub

—

4. コードの解説と「プロのこだわり」

4.1 `Application.UndoRecord` の宣言

これはWord全体を管理する「Undoの司令塔」を呼び出す処理です。このオブジェクトを操作することで、履歴のスタックを制御できます。

4.2 `StartCustomRecord` の名前選び

`objUndo.StartCustomRecord “表記揺れの一括修正”` と書いた部分は、実際にWordの画面上部の「元に戻す」ボタンの横にある「▼」をクリックした時に表示される名前になります。ここを丁寧に書くことで、ユーザーは「この操作は何をしたのか」を一目で理解できます。

4.3 `On Error GoTo ErrorHandler` の重要性

これが今回の最も重要なポイントです。
もし置換処理の途中でエラー(ファイルが読み取り専用だった、など)が発生してマクロが止まってしまった場合、`EndCustomRecord` が実行されません。すると、Wordは「まだ記録中」だと勘違いし続け、その後の手動操作まで一つの履歴にまとめられてしまうという悲劇が起きます。
「開けたら閉じる」。これは自動化エンジニアの鉄則です。

—

5. 陥りやすい罠:ネスト(入れ子)の制限

`UndoRecord` は入れ子にすることができますが、複雑にしすぎると管理が困難になります。
基本的には、「1つのマクロにつき、1つのUndoRecord」にするのが、設計として最も美しく、保守性が高いです。

もし、すでに `UndoRecord` が開始されているかどうかをチェックしたい場合は、`objUndo.CustomRecordLevel` を確認します。これが `0` より大きければ、すでに記録が始まっているという証拠です。

—

6. まとめ:さらなる高みへ

お疲れ様でした!今回の「UndoRecord」の活用術、いかがでしたか?

単に「動くコード」を書くだけなら簡単です。しかし、「ユーザーが安心して使えるコード」を書くためには、今回のようなライフサイクル管理が不可欠です。

  • UndoRecordで操作をパッケージ化する
  • エラーハンドリングで「閉じ忘れ」を防ぐ
  • ユーザーに分かりやすい操作名を付ける

この3点を守るだけで、あなたのWord VBAのスキルは、マクロの記録レベルから「プロフェッショナル・ツール」のレベルへと一気に引き上げられます。

一歩ずつ、着実に。こうした細かい配慮の積み重ねが、誰からも信頼されるエンジニアへの道となります。応援していますよ!

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