ブックには「タイトル」や「作成者」などの情報を記録できます。
こうした情報を、ブックのドキュメントプロパティと呼びます。
ドキュメントプロパティには、「タイトル」や「作成者」など、Excelがあらかじめ定義している「組み込みのドキュメントプロパティ」と、任意の名前やデータを記録できる「ユーザー設定のドキュメントプロパティ」の2種類があります。
どちらのドキュメントプロパティもDocumentPropertyオブジェクトなのですが、「組み込みのドキュメントプロパティ」はBuiltinDocumentPropertiesコレクションで操作し、「ユーザー設定のドキュメントプロパティ」はCustomDocumentPropertiesコレクションで操作します。
組み込みのドキュメントプロパティを操作するときは、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メソッドの引数は、次の通りです。
引数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
ユーザー設定のドキュメントプロパティは、セルとリンクすることができます。ドキュメントプロパティとセルをリンクさせるには次のようにします。
こうして、セルとリンクしたドキュメントプロパティは、セルの値が変化すると、自動的にドキュメントプロパティの値も変化します。
この操作を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によって異なりますので注意が必要です。上記の
は、Windows VistaやWindows 7での数値です。ちなみに、Windows XPでは
となります。何番がどの項目かは、次のようにして調べられます。
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が作成し無償で公開している、ファイルのプロパティを操作できるライブラリです。以下のページからダウンロードできます(英語版です)。
この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のインストールが可能な環境なら、複数ブックの運用が楽になりますね。