Word2007限定:ファイル読込直後にShift+F5を効かせる

2011/07/18 : 間違えましたすいません。詳細は下記追記にて。

結論:以下の VBA コードを Normal.dotm に追加すれば OK。

(a) 標準モジュール ( 「Module1」など )

Sub AutoExec()
    KeyBindings.Add _
          KeyCode:=BuildKeyCode(wdKeyShift, wdKeyF5) _
        , KeyCategory:=wdKeyCategoryMacro _
        , Command:="JumpShiftF5_2007"
End Sub

Sub JumpShiftF5_2007()
    If ActiveDocument.Bookmarks.Exists("_GoBack") Then
        Selection.GoTo What:=wdGoToBookmark, Name:="_GoBack"
        ActiveDocument.Bookmarks("_GoBack").Delete
    Else
        Application.GoBack
    End If
End Sub

(b) クラスモジュール ( 「clsGoBack」 )

Public WithEvents appGoBack As Word.Application

Private Sub appGoBack_DocumentBeforeSave( _
    ByVal Doc As Document, SaveAsUI As Boolean, Cancel As Boolean)

    If Application.Documents.Count = 0 Then Exit Sub
    If ActiveDocument.Bookmarks.Exists(bmGoBack) Then
        ActiveDocument.Bookmarks(bmGoBack).Delete
    End If
    ActiveDocument.Bookmarks.Add _
          Name:=bmGoBack _
        , Range:=ActiveDocument.ActiveWindow.Selection

End Sub
以下、手順。
  1. Word2007 を起動します。
  2. Alt+F11 で、VBAエディタを起動します。
  3. プロジェクトエクスプローラ ( Ctrl+Rで表示されます ) から「Normal」を右クリックし、[挿入]-[標準モジュール] を選択します。
    「Normal」に何も手を入れていなければ、[Normal]-[標準モジュール] の下に、「Module1」が追加されます。
  4. 3. で作成した「Module1」をダブルクリックします。
    「Module1」が開き、コードエディタに表示されます。
  5. 上述のコード (a) をコピーして、「Module1」のコードエディタに貼り付けます。
  6. プロジェクトエクスプローラから「Normal」を右クリックし、[挿入]-[クラスモジュール] を選択します。
    「Normal」に何も手を入れていなければ、[Normal]-[標準モジュール] の下に、「Class1」が追加されます。
  7. 6. で作成した「Class1」をダブルクリックします。
    「Class1」が開き、コードエディタに表示されます。
  8. プロパティウィンドウ ( F4 で表示されます ) から、「(オブジェクト名)」を「clsGoBack」に変更します。
  9. 上述のコード (b) をコピーして、「clsGoBack」のコードエディタに貼り付けます。
  10. Word2007のウィンドウに戻って、終了します。
    5.、9. で貼り付けた内容は自動的に保存されますので、特に保存操作をしなくても大丈夫です。


先日Twitterで、冴子先生2010 ( @saeko2010 ) のツイートから

Word2007では、起動時に Shift+F5 ( GoBack コマンド ) を押しても
前回終了時のカーソル位置へジャンプしない

ということを知りました。がびーん。

どうりでなんか Shift+F5 が効かないなーとか思っていたわけですよ。

2003までは有効で、2010で復活した機能なんだそうですが。
私は、自宅の Office は 2010 ですが、今の仕事場では 2007 なんですね。でもってけっこう Word2007 で文書こしらえたりするんですよ。

こいつぁいけねぇ。
Wordってものぁ書きかけの文書読み込んだ直後に Shift+F5 で前回の最終カーソル位置にさくっと飛んですぐさま作業の続きを始められるようでなくっちゃあいけねぇよ。

つことで、ちょっと仕組みを調べてみました。


Wordは、直前のカーソル位置とか文書の最初とか最後とか、ジャンプしたい特殊な位置を 定義済みブックマーク というシステムブックマークで管理しているようです。

直前のカーソル位置は \PrevSel1 、そのもうひとつ直前のカーソル位置は \PrevSel2 として管理しています。これはカーソル移動や文字入力のたびに書き換えられ、GoBack コマンド ( インストール時設定で Shift+F5 および Alt+Ctrl+Z に割り当てられています ) でひょいひょいと戻っていくんですね。

って、ここまでの情報は 

WD2000: Word の組み込み (定義済み) のブックマークを使用します。

から。Word2000 用の資料ですが、互換性もあって~2010までここらへんの仕組みは基本同じようです。

ちなみに、上記ページの 示される\Para をうっかり訳してしまったものです。機械翻訳ならではの妙味ですね。原文は こちら からどうぞ。


この直前のカーソル位置を示すシステムブックマーク \PrevSel1 は、保存時に .docx ファイルに保存されます。
ので、次回読込直後に Shift+F5 を押すと、前回終了時のカーソル位置へめでたくジャンプできる、というシカケなわけですが。

2007 では、保存時にこれらのシステムブックマークを破棄しているんではないか、という話が出てきました。まじですかい。

Word2007で、閉じる前のページ・位置へ素早く移動するには?(Word3003の"Sh – Microsoft Answers 

…なんだかページタイトルがちょっと怪しいような気がしますが、まあそこはご愛嬌で。

ここの回答で ikutawasabi さんが

残念ながら、2007では、その機能が廃止になりました。

Word2007から、上書き保存をした時に、そのブックマークが消滅してしまうようにプログラムされたため、無効になりました。

と発言されておりまして。

ソースは米国のMVPサイトなんだそうですが、具体的に元ページは提示いただいていないので、ちょっと裏が取れません。
しかたがないので自分なりに探してみました。

GoBack (Shift+F5) doesn't work in some newly-opened documents

あたりではないかなーと思ったんですが。これは、

Wordで文書をひとつしか開いていない時に、最終変更を保存せずにWordを閉じ、「保存しますか?」に「はい」と答えて保存した時に限り、最終カーソル位置が保存されない

というバグなんだそうで。

これを回避するために提示されている VBA コードは、「最後の 1 ファイルを終了させる直前に、見えないようにもうひとつファイルを新規作成して『最後のひとつ』というバグの発生条件を回避する」というものでした。
これはこれでおもしろい解決方法です。

しかし、

Shift+F5 doesn't work in Word 2007 – Microsoft Office

で Word MVP の Jay Freedman さんが、

Word2007で「ファイル読込直後に Shift+F5 が効かない」のはまったく別の問題だ。

と言われてまして、うーん ikutawasabi さんの発言は、たぶんこのへんを指しているのかなあ。


ではやっぱり、2007では最終カーソル位置を保存しない仕様になっちゃってるのかなあ。

とあきらめ気味で、Word2007 で作成した文書を Word2010 で開いて Shift+F5 を押してみました。

…あれっ?ちゃんと前回保存時の最終カーソル位置へジャンプするよ?

これは、Word2007 で保存してもちゃんと最終カーソル位置は保存されてるってことじゃないですか。
あー、そもそも、最終カーソル位置は .docx にどんな形で保存されてるんだろう。

.docx ファイルの調査は割と簡単です。
2007 以降の Office ファイルは Office Open XML というやつでして、xml で書かれた各種情報を入れ子になったフォルダにいくつかのファイルという形で格納し、 zip 圧縮かけて拡張子を変えただけのものです。
ので、拡張子を .zip に変えてやれば、中身は全部 xml ファイルとしてチェックできるわけですね。
まったく同じ文書で最終カーソル位置だけ変えて保存した 2 つのファイルを用意して、zip ファイルとして展開し、フォルダごと WinMerge などで突き合わせてみればいいんです。

結果、\word\document.xml に

<w:bookmarkStart w:id="0" w:name="_GoBack"/>

というタグで埋め込まれていることがわかりました。
これは 2007 でも 2010 でもまったく同じでした。
これは 2010 の場合であり、2007 ではこのタグは存在しません。

ただし、2010 で作成した文書を 2007 で読込→保存、再度 2010 で読み込むと、2010 で保存した時の最終カーソル位置へジャンプしました。

つことは、Word2007 で 読込直後に GoBack コマンド ( Shift+F5 ) が効かないのは、

保存時ではなく読み込み時の不具合だ

ということになります。

追加検証として、Word2010 で作成した .docx ファイルを 2007 で読み込んでも、やはり SHift+F5 は効きませんでした。
それをもう一度 Word2010 で読み込むと効きます。2007 で読み込んで保存して 2010 で読み込んでも効きました。


さて。

上述の Microsoft サポート情報 では、GoBack コマンドがジャンプする先には \PrevSel1 というシステムブックマークが埋め込まれているというお話でした。

実際、文書読込直後に

ActiveDocument.Bookmarks.Count

でブックマーク数を確認すると 0 なんですが、Word2010 ではこの状態で

Selection.GoTo What:=wdGoToBookmark, Name:="\PrevSel1"

を実行すると、正常に前回保存時の最終カーソル位置にジャンプします。
ジャンプした途端に \PrevSel1 はジャンプ直前の位置にブックマークし直されますので、ファイルをオープンするたびに 1 回こっきりのジャンプチャンスなんですけどね。

でも、ファイル上は _GoBack って名前で保存してるわけですから、読込時に

 _GoBack ってブックマークタグがあったら \PrevSel1 として展開する

という処理が入っているんではないかなー、と推測できます。

2007 では読み込み時にこの処理がされていない、ということになるんですが、もし仕様変更でこの処理を明示的に削除したのではない、ただのうっかりぽんバグなのであれば、

手動で組み込んだ他のブックマークと同様に、
_GoBack という名前のままで展開しちゃってる

んではないか? と、さらに推測してみました。

で、確認のために
では 2007 ではファイル中の _GoBack ブックマークタグがどういう扱いになっているかというと、

Selection.GoTo What:=wdGoToBookmark, Name:="_GoBack"

ってVBA コードを 2007 で実行してみると、

…正常に前回保存時の最終カーソル位置へジャンプしました。

なんだようっかりぽんかよ!やってくれるぜ Word2007!

で前回保存時の最終カーソル位置へジャンプすることがわかりました。
保存時、読込時ともに \PrevSet1 ⇔ _GoBack の取扱いがすっぽり抜けているので、_GoBack ブックマークタグがそのまま取り込まれるという動作なわけですね。

てことで、基本的には Selection.GoTo コマンドでイケるということがわかりました。
てことで、_GoBack ブックマークへジャンプさせれば、2007 でも 2010 で作った文書に対して 読込直後の Shift+F5 と同様の動作になります。


じゃあ、2007 で作成した文書の場合はどうすればいいかというと、

_GoBack ブックマークを直接埋め込む

という手法を取れます。いやなんともベタですが。
ブックマークの入力ダイアログでは、「_」などの記号から始めるブックマークは追加できませんが、VBA からなら追加可能です。

実際にやってみると、2007で新規作成→保存した文書の中に、2010 同様

<w:bookmarkStart w:id="0" w:name="_GoBack"/>
タグが追加されました。
これなら Word の仕様そのものですので、他のバージョンの Word 製文書とも互換が取れます。
ただし、保存時に _GoBback ブックマークタグを埋め込むにも VBA コードが必要ですので、上記のコードを埋め込んでいない 2007 で作成した文書では読込直後の Shift+F5は効かない、という状況は変わりません。残念ですが、ここまでが限界のようですね。

あとは、VBA コードのつじつま合わせです。

手動で組み込んだ他のブックマークと同様 の扱いになっちゃっていますので、ジャンプしても _GoBack ブックマークは消えません。
ので、ジャンプと同時に _GoBack ブックマークを削除してやることにします。
ジャンプまたは普通に編集を行うと、他のバージョンの Word と同様に \PrevSel1 ブックマークは制御されますので、_GoBack ブックマーク削除後は従来の GoBack コマンドを呼び出せば OK ですね。


以上で、バージョン間の互換性も含めて、Shift+F5 が Word2010 と同じ動作となる VBA コードができました。
他のマシンの Word2007 で作った文書にも有効ですので、なんとか独自のブックマークを用意するなどの小手先技に走らずに済みました。わーい。

~2003 のファイルでどう動作するかちょっと確認できていないんですが、もしうまく動作しないようであれば、ファイルをご提供いただければ善処できるかもしれません。


2011.07.18 追記

すいません。検証の途中で、2007 で新規作成した文書と、2010 で新規作成して 2007 で上書き保存した文書の取扱いを間違えてしまったようです。

本エントリアップ後、自分の仕事で 2007 を使って文書を

新規作成→保存→読込→ Shift+F5 →「効かない!?」
→ _GoBack ブックマークタグが存在しないぞ!?→うわあぁぁ

となりました。

というわけで、2007 で文書保存時に _GoBack ブックマークを埋め込む VBA コードを追記し、そのあたりの説明も訂正しました。
取り消し線が削除部分、青字が追記部分です。

うっかりぽんバグなどと誤った推測をしてしまい、申し訳ありませんでした。お恥ずかしい。

コメントを投稿