UndoRecordオブジェクトというものがある(Word)

UndoRecordオブジェクトというものがある

前回の

akashi-keirin.hatenablog.com

に、id:imihito さんからコメントをいただいた。

曰く、

また、Undoの履歴は、以下のようにするとひとまとめに出来たはずです
```vb
Application.UndoRecord.StartCustomRecord
'処理
Application.UndoRecord.EndCustomRecord
```

と。

な、なんだってー!(MMR風)

さっそくやってみた。

UndoRecordオブジェクトを使う

例によって公式のUndoRecordオブジェクトの項を見ると、

UndoRecord オブジェクト (Word)

元に戻すスタックにエントリ ポイントを提供します。

注釈

作成し、Word の [元に戻すスタックにユーザー定義の undo レコードを変更するには、 UndoRecordオブジェクトを使用します。

次のコード例は、 UndoRecordオブジェクトをインスタンス化します。

VB
Dim objUndo As UndoRecord 
Set objUndo = Application.UndoRecord

だそうである。機械的な飜訳だからか、異様に読みづらい。

英語版で見てみよう。

UndoRecord object (Word)

Provides an entry point into the undo stack.

Remarks

Use the UndoRecord object to create and modify custom undo records in the Word undo stack.

Example

The following code example instantiates an UndoRecord object.

VB
Dim objUndo As UndoRecord 
Set objUndo = Application.UndoRecord

Wordのアンドゥ情報を積んでおく場所への入り口を提供する、みたいな感じ?

メソッドやプロパティへのリンクが記事中にないので、サイドバーみたいなところから、MethodsStartCustomRecordへと辿っていく。すると、

UndoRecord.StartCustomRecord method (Word)

Initiates the creation of a custom undo record.

Syntax

expression.

expression A variable that represents an 'UndoRecord' object.

Parameters
Name Repuired/Optional Data type Description
Name Optional String Specifies the name of the custom undo record. This string is limited to 64 characters. If a longer string is supplied, the string is truncated to 64 characters.
注意

If this parameter is omitted or is an empty string, Word uses the name of the first command executed as the name of the undo record.

Remarks

StartCustomRecord begins the creation of a custom undo record, which records all actions done to the application while it is active under a record defined by Name .

Example
VB
Sub TestUndo() 
Dim objUndo As UndoRecord 
 
Set objUndo = Application.UndoRecord 
objUndo.StartCustomRecord ("My Custom Undo") 
    'Add some actions here 
objUndo.EndCustomRecord 
     
End Sub

UndoRecordオブジェクトを作成して、そのStartCustomRecordメソッドとEndCustomRecordメソッドを、アンドゥの対象とする処理の前後で実行すれば良いようだ。

使ってみる

前回のリスト1を少し改変する。

リスト1 標準モジュール
Public Sub test()
  Dim winAPI As New WindowsAPI
  Dim startTime As Long
  startTime = winAPI.getNowTickCount
  Dim Doc As Document
  Set Doc = ThisDocument
  Dim targetChar As Range
  Dim tmpUndo As UndoRecord    '……(1)'
  Set tmpUndo = Doc.Parent.UndoRecord
  Call tmpUndo.StartCustomRecord("TempUndo")
  For Each targetChar In Doc.Characters
    With targetChar
      If .HighlightColorIndex = wdYellow Then
        .HighlightColorIndex = wdNoHighlight
      End If
    End With
  Next
  Call tmpUndo.EndCustomRecord    '……(2)'
  Dim endTime As Single
  endTime = (winAPI.getNowTickCount - startTime) / 1000
  Call MsgBox("処理時間:" & endTime & vbCrLf & _
              "文字数 :" & Doc.Characters.Count)
End Sub

前回から変わったのは、(1)、(2)のところ。

(1)からの3行

Dim tmpUndo As UndoRecord
Set tmpUndo = Doc.Parent.UndoRecord
Call tmpUndo.StartCustomRecord("TempUndo")

では、変数tmpUndoUndoRecordオブジェクトをぶち込んで、StartCustomRecordメソッドを実行。

メインの処理の記述の後、(2)の

Call tmpUndo.EndCustomRecord

EndCustomRecordメソッドを実行する。

これで、コード実行後、アンドゥで元に戻せることになる。

やってみる

f:id:akashi_keirin:20181215140403j:plain

ひとまず、この状態でリスト1を実行。

f:id:akashi_keirin:20181215140412j:plain

こうなる。

んで、「元に戻す」アイコンにマウスカーソルを当てると、

f:id:akashi_keirin:20181215140431j:plain

「元に戻す TempUndo」と表示されている。

なるほど、StartCustomRecordメソッドの引数は、こんなところに生きるのか。

f:id:akashi_keirin:20181215140420j:plain

「元に戻す」アイコンをクリックすると、

f:id:akashi_keirin:20181215140510j:plain

おおっ! マーカが復活した!

おわりに

控え目に言っても、これは超便利ではなかろうか。

id:imihito さん、本当にありがとうございました!