残念なRecentFileオブジェクト


Excel 2007では、ファイルを開いた履歴である「最近使用したドキュメント」に新機能が追加されました。

[ファイル]メニューを開くと右に表示されるファイル履歴は、上図のようにピンのアイコンが追加されました。このアイコンをクリックすると緑色になり、そのファイルは履歴から削除されなくなります

さて、この「削除されるかどうか」のオン/オフですが、VBAから取得/設定することはできません。オブジェクトライブラリで確認すると、RecentFileオブジェクトには該当するプロパティが存在しないのです。

たとえば、すべての"ファイル履歴"を取得して表示するには次のようにします。

Sub Sample1()
    Dim msg As String, i As Long
    With Application
        For i = 1 To .RecentFiles.Maximum
            msg = msg & .RecentFiles(i).Name & vbCrLf
        Next i
    End With
    MsgBox msg
End Sub

余談ですが、RecentFileオブジェクトのNameプロパティは、次のようなファイル名を返します。

  • カレントドライブとカレントディレクトリが、ファイルのパスと同じ場合 → 名前だけ
  • カレントドライブは同じだが、カレントディレクトリがファイルのパスと異なる場合 → ドライブ名を除いたパスと名前
  • カレントドライブとカレントディレクトリが、ファイルのパスと異なる場合 → ドライブ名を含むパスと名前

実際にやってみましょう。履歴に登録されているファイルはすべて「C:\Work」フォルダに存在するとします。

・カレントディレクトリが「C:\Work」の場合

・カレントディレクトリが「C:\Tmp」の場合

・カレントディレクトリが「E:\」の場合

なお、RecentFileオブジェクトのPathプロパティは、常にファイルのフルパスを返します。

さて本題に戻りましょう。ファイル履歴のうち、ピンをクリックして「履歴から削除されない」ファイルを見つけるにはどうしたらいいでしょう。適当なプロパティやメソッドがないのならレジストリを調べてみます。ファイルの履歴は

HKCU\Software\Microsoft\Office\12.0\Excel\File MRU

に記録されています。この場所はExcelのバージョンによって異なりますので注意してください。

  • Excel 5.0/95/97 → Recent File List
  • Excel 2000/2002/2003 → Recent Files
  • Excel 2007 → File MRU

レジストリの値を見ると、各データは「item 1」「item 2」という名前で、次のように保存されていました。

[F00000000][T01C71998A01347D0]*C:\Work\Book1.xls

最初の[F00000000]が「履歴から削除するかどうか」の判定に使われているようです。

  • [F00000000] → 削除される(ピンのアイコン:オフ)
  • [F00000001] → 削除されない(ピンのアイコン:オン)

次の[T01C71998A01347D0]は何かのIDに使われているのでしょう。今回のケースとは関係なさそうなので無視します。「*」から後ろにフルパスが記録されています。このレジストリデータを直接参照すれば、履歴に登録されているファイルが「履歴から削除される」かどうかを判定することができそうです。詳細な解説は割愛しますが、次のようなコードでやってみました。

Sub Sample2()
    Dim WSH, RF, i As Long, msg As String, buf As String
    Set WSH = CreateObject("WScript.Shell")
    Set RF = Application.RecentFiles
    For i = 1 To RF.Maximum
        buf = WSH.RegRead("HKCU\Software\Microsoft\Office\12.0\Excel\File MRU\Item " & i)
        If Mid(buf, 10, 1) = "1" Then
            msg = msg & "削除[×]" & Chr(9) & RF(i).Name & vbCrLf
        Else
            msg = msg & "削除[○]" & Chr(9) & RF(i).Name & vbCrLf
        End If
    Next i
    MsgBox msg
    Set WSH = Nothing
End Sub

上記のコードでは、レジストリデータの「10文字目」が「1」かどうかを判定しています。あまり美しいやり方ではありませんが、まぁとにかくこうして判定するということです。コードを簡素化するために、あえてエラー処理などはしていません。

ファイルの履歴が削除されなくなるというのは、ユーザーにとってうれしい新機能です。せっかくの機能なのですから、専用のプロパティを用意して欲しかったですね。そうしたら、マクロからオン/オフを切り替えるなどの使い方もできるのに。