ブックのドキュメントプロパティを操作する


ドキュメントプロパティとは

ブックには「タイトル」や「作成者」などの情報を記録できます。

こうした情報を、ブックのドキュメントプロパティと呼びます。

ドキュメントプロパティには、「タイトル」や「作成者」など、Excelがあらかじめ定義している「組み込みのドキュメントプロパティ」と、任意の名前やデータを記録できる「ユーザー設定のドキュメントプロパティ」の2種類があります。

どちらのドキュメントプロパティもDocumentPropertyオブジェクトなのですが、「組み込みのドキュメントプロパティ」はBuiltinDocumentPropertiesコレクションで操作し、「ユーザー設定のドキュメントプロパティ」はCustomDocumentPropertiesコレクションで操作します。

組み込みのドキュメントプロパティ

組み込みのドキュメントプロパティを操作するときは、BuiltinDocumentPropertiesコレクションを使って、

  • BuiltinDocumentProperties(インデックス番号)
  • BuiltinDocumentProperties(プロパティ名称)

いずれかの方法でアクセスします。

まず、組み込みのドキュメントプロパティには、どんな種類があるかを調べてみましょう。次のコードは、操作できる組み込みのドキュメントプロパティの一覧を、アクティブシートに出力します。

Sub Sample1()
    Dim i As Long
    On Error Resume Next
    With ActiveWorkbook
        For i = 1 To .BuiltinDocumentProperties.Count
            Cells(i, 1) = .BuiltinDocumentProperties(i).Name
            Cells(i, 2) = .BuiltinDocumentProperties(i).Value
        Next i
    End With
End Sub

こんな感じに表示されたと思います。A列に入力されているのが、ドキュメントプロパティの名称です。もし何か値が設定されていればB列に代入されます。また、行番号が、ドキュメントプロパティのインデックス番号に該当します。ドキュメントプロパティは、Excel専用ではなく、ほかのOffise製品でも使われています。段落数を表す「Number of paragraphs」などは、おそらくWordで使われるドキュメントプロパティなのでしょう。そんな関係で、組み込みのドキュメントプロパティすべてにアクセスできるとは限りません。操作しようとするとエラーになるドキュメントプロパティもありますので、上記のコードではエラーを無視しています。

組み込みのドキュメントプロパティを操作するには、BuiltinDocumentPropertiesコレクションに、インデクス番号またはプロパティ名称を指定します。次のコードは、「サブタイトル」に任意の文字列を設定します。

Sub Sample2()
    Dim buf As String
    With ActiveWorkbook
        MsgBox "現在のサブタイトルは「" & .BuiltinDocumentProperties("Subject").Value & "」です"
        buf = InputBox("新しいサブタイトルは?")
        .BuiltinDocumentProperties("Subject").Value = buf
    End With
End Sub

マクロでドキュメントプロパティを操作する機会は、それほど多くありません。そもそも、ドキュメントプロパティを活用しているユーザーは少ないです。それどころか、ドキュメントプロパティを自由に設定できるということを知らない人も珍しくありません。

ドキュメントプロパティは、活用するとけっこう便利なんですよ。たとえば、ブックを開いていなくても、エクスプローラ上からドキュメントプロパティを表示することができます。やり方は簡単です。ただ、マウスポインタを合わせるだけでです。

また、ファイルを右クリックして[プロパティ]を実行すると、[プロパティ]ダイアログボックスの[詳細]タブで、すべてのドキュメントプロパティを確認できます。

確認できるだけではありません。実は、このダイアログボックス上で、ドキュメントプロパティを編集することもできるんです。

参考までに、任意のフォルダにあるすべてのブックに対して、ドキュメントプロパティを設定するマクロをご紹介します。次のコードは、C:\sampleフォルダに存在する全ブックの「作成者」に"田中亨"を設定します。

Sub Sample3()
    Dim Target As String, wb As Workbook
    Const Path As String = "C:\Sample\"
    Target = Dir(Path & "*.xls")
    Do While Target <> ""
        With Workbooks.Open(Path & Target)
            .BuiltinDocumentProperties("Author").Value = "田中亨"
            .Close SaveChanges:=True
        End With
        Target = Dir()
    Loop
End Sub

ユーザー設定のドキュメントプロパティ

ユーザー設定のドキュメントプロパティは、CustomDocumentPropertiesコレクションで操作します。

基本的な考え方は同じですが、ユーザー設定のドキュメントプロパティは、独自の項目を作成することができます。独自のドキュメントプロパティを作成するには、CustomDocumentPropertiesコレクションのAddメソッドを使います。

次のコードは、「会議日」というドキュメントプロパティを作成し「2009/11/22」というデータを設定します。

Sub Sample3()
    ActiveWorkbook.CustomDocumentProperties.Add _
                            Name:="会議日", _
                            LinkToContent:=False, _
                            Type:=msoPropertyTypeDate, _
                            Value:="2009/11/22"
End Sub

Addメソッドの引数は、次の通りです。

  • Name (必須):プロパティの名前を指定します
  • LinkToContent (必須):プロパティとセルをリンクさせるかどうかをTrue/Falseで指定します。詳しくは後述します
  • Type (省略可能):プロパティのデータ型を次の定数で指定します。msoPropertyTypeBoolean、msoPropertyTypeDate、msoPropertyTypeFloat、msoPropertyTypeNumber、msoPropertyTypeString
  • Value (省略可能):LinkToContentにTrueを指定した場合は省略可能です。LinkToContentにFalseを指定した場合は必ず指定します。プロパティに設定する値を指定します
  • LinkSource (省略可能):LinkToContentにTrueを指定して、プロパティとセルをリンクさせる場合は、リンクするセルに定義した名前を指定します

引数Typeで指定するデータ型は、けっこうシビアに扱われます。試しに、日付データを文字列として設定してみましょう。

Sub Sample4()
    ActiveWorkbook.CustomDocumentProperties.Add _
                            Name:="納品日", _
                            LinkToContent:=False, _
                            Type:=msoPropertyTypeString, _
                            Value:="2009/11/25"
End Sub

2つのプロパティは、返り値の型が異なります。

Sub Sample5()
    Dim msg As String
    With ActiveWorkbook
        msg = msg & "会議日:" & TypeName(.CustomDocumentProperties("会議日").Value) & vbCrLf
        msg = msg & "納品日:" & TypeName(.CustomDocumentProperties("納品日").Value)
    End With
    MsgBox msg
End Sub

文字列型の値をシリアル値のように計算しようとするとエラーになります。

Sub Sample6()
    Debug.Print ActiveWorkbook.CustomDocumentProperties("納品日").Value + 1
End Sub

ドキュメントプロパティとセルをリンクさせる

ユーザー設定のドキュメントプロパティは、セルとリンクすることができます。ドキュメントプロパティとセルをリンクさせるには次のようにします。

  1. リンクさせたいセルに名前を定義します。ここでは、セルA6に「データ合計」という名前を定義しました。セルに名前を定義するときは、そのセルを選択して、名前ボックスに定義したい名前を入力すると簡単です
  2. [ブックのプロパティ]ダイアログボックスを開き、[ユーザー設定]タブを開きます
  3. [プロパティ名]ボックスに、定義したいプロパティ名称を入力します
  4. [内容にリンク]チェックボックスをオンにすると、左の[リンク元]ボックスで、セルに定義した名前を選択できるようになります
  5. リンクした名前を選択して[追加]ボタンをクリックすると、セルとリンクしたドキュメントプロパティが設定できます

こうして、セルとリンクしたドキュメントプロパティは、セルの値が変化すると、自動的にドキュメントプロパティの値も変化します。

この操作をVBAで行うには、次のようにします。

Sub Sample7()
    ActiveWorkbook.CustomDocumentProperties.Add _
                            Name:="集計項目", _
                            LinkToContent:=True, _
                            Type:=msoPropertyTypeNumber, _
                            LinkSource:="データ合計"
End Sub

ブックを開かないでドキュメントプロパティを取得する

ドキュメントプロパティは、積極的に活用すると便利な機能です。上で解説したように、ブックを開かなくてもエクスプローラから「作成者」や「タイトル」などを閲覧することができますし、ドキュメントプロパティの値でファイルを検索することも可能です。

しかし、それらはいずれも手動操作による活用であって、VBAからDocumentPropertyオブジェクトにアクセスするには、一度Excelでブックを開かなければなりません。それが、すごく、歯がゆいです(笑)。何とか、ブックを開かないでドキュメントプロパティを取得できないものでしょうか。

開いていないブックから、「組み込みのドキュメントプロパティ」を取得するのは、実は意外と簡単です。これには、Window Scripting Host(WSH)を使います。ここでは、次のように、C:\Sampleフォルダに、3つのブックが存在するものとします。3つのブックには、それぞれ適当なドキュメントプロパティを設定しています。

次のコードは、C:\Sampleフォルダに存在するブックの「タイトル」「作成者」など組み込みのドキュメントプロパティを取得します。

Sub Sample8()
    Dim Shell As Object, Folder As Object, Target As String, cnt As Long
    Const Path As String = "C:\Sample\"
    Set Shell = CreateObject("Shell.Application")
    Set Folder = Shell.Namespace(Path)
    Target = Dir(Path & "*.xlsx")
    Do While Target <> ""
        cnt = cnt + 1
        Cells(cnt, 1) = Folder.GetDetailsOf(Folder.ParseName(Target), 0)    ''ファイル名
        Cells(cnt, 2) = Folder.GetDetailsOf(Folder.ParseName(Target), 20)   ''作成者
        Cells(cnt, 3) = Folder.GetDetailsOf(Folder.ParseName(Target), 21)   ''タイトル
        Cells(cnt, 4) = Folder.GetDetailsOf(Folder.ParseName(Target), 22)   ''サブタイトル
        Target = Dir()
    Loop
    Set Folder = Nothing
    Set Shell = Nothing
End Sub

結果は下図の通りです。うまくいきました。Excel上にブックを開いていませんので、とても高速です。

GetDetailsOfメソッドの引数に指定する数値は、OSによって異なりますので注意が必要です。上記の

  • 20 → 作成者
  • 21 → タイトル
  • 22 → サブタイトル

は、Windows VistaやWindows 7での数値です。ちなみに、Windows XPでは

  • 9 → 作成者
  • 10 → タイトル
  • 11 → サブタイトル

となります。何番がどの項目かは、次のようにして調べられます。

Sub Sample9()
    Dim Shell As Object, Folder As Object, i As Long
    Set Shell = CreateObject("Shell.Application")
    Set Folder = Shell.Namespace("C:\")
    For i = 0 To 300
        Debug.Print i, Folder.GetDetailsOf("", i)
    Next i
    Set Folder = Nothing
    Set Shell = Nothing
End Sub

ユーザー設定のドキュメントプロパティも取得したい

この長いコンテンツを、辛抱強く最後まで読んでくれた方には、さらにとっておきの情報をお伝えします。

上で解説したように、Excelのブックでは、ユーザー設定のドキュメントプロパティに、任意のセルをリンクすることができます。セルの値が変化したとき、ドキュメントプロパティの値も自動的に反映させることが可能です。ということは、任意のセルとリンクしたドキュメントプロパティを設定しておいて、そのブックを開かないでドキュメントプロパティを取得できれば、いちいちブックを開かなくても必要なデータを取り出せるわけです。これは、すごい!

先に紹介したWSHでは、組み込みのドキュメントプロパティしか取得できません。ユーザー設定のドキュメントプロパティを取得するには、ほかのプログラムの力を借りなければなりません。それは、

 Microsoft Developer Support OLE File Property Reader

です。いわゆるDsofile.dllですね。このファイルは、Microsoftが作成し無償で公開している、ファイルのプロパティを操作できるライブラリです。以下のページからダウンロードできます(英語版です)。

Microsoftのダウンロードセンター

このDsofile.dllをインストールしておくと、ブックを開かずに、ユーザー設定のドキュメントプロパティを取得できます。

次のコードは、C:\Sample\Book1.xlsxに設定したユーザー設定のドキュメントプロパティ「集計項目」を、ブックを開かずに取得します。

Sub Sample10()
    Dim DSO As Object
    Set DSO = CreateObject("DSOFile.OleDocumentProperties")
    DSO.Open "C:\Sample\Book1.xlsx"
    MsgBox DSO.CustomProperties("集計項目")
    DSO.Close
    Set DSO = Nothing
End Sub

次のコードは、C:\Sampleフォルダに存在するブックに設定したユーザー設定のドキュメントプロパティ「集計項目」を取得します。

Sub Sample11()
    Dim DSO As Object, Target As String, cnt As Long
    Const Path As String = "C:\Sample\"
    Set DSO = CreateObject("DSOFile.OleDocumentProperties")
    Target = Dir(Path & "*.xlsx")
    Do While Target <> ""
        cnt = cnt + 1
        Cells(cnt, 1) = Target
        DSO.Open Path & Target
        Cells(cnt, 2) = DSO.CustomProperties("集計項目")
        DSO.Close
        Target = Dir()
    Loop
    Set DSO = Nothing
End Sub

こちらも、Excel上にブックを開かないので、驚くほど高速です。

Dsofile.dllというExcelとは別のライブラリが必要なので、どのパソコンでも実行できるとは限りません。しかし、ブックを開かないでセルのデータを取得できるのですから、Dsofile.dllのインストールが可能な環境なら、複数ブックの運用が楽になりますね。