2020/12/30

文書が追加されているフォルダを調べる

 Notes データベースにある文書を一覧表示するには、通常ビューかフォルダのどちらかを使っていると思います。

フォルダは、そこに表示する文書をユーザー自身で自由に出し入れできるのが特徴です。フォルダからフォルダへの移動はドラッグ&ドロップでも可能なこともあって、文書を分類する用途では非常に便利に使えます。

Notesデータベースを長く使っていると「フォルダ数増大」「フォルダ内文書数増大」などにより分類したはずの文書を探し出せないといった新たな問題が発生することもあります。そんな時、文書がどのフォルダに追加されているのかを調べる方法はあるのでしょうか。


メールデータベースにはそのヒントになるものがあります。「すべての文書」ビューには「フォルダ」という列があり、その列にはメールごとにフォルダ名が表示されるのです。この列の設計を Domino Designer で開くと @WhichFolders という関数が見つかります。フォルダ名をメールデータベース以外のデータベースでビュー上に表示するには、この関数をビューの列式へセットするだけではダメで、その方法は御代さんのブログに詳しく書かれています。


ここでは、LotusScript で調べてみたいと思います。

御代さんのブログにある方法を使い、文書を追加したフォルダの名前が自作データベースのビュー上で表示されることを確認した後、次のようなプログラムを書きました。

Sub Initialize
	Dim ss As New NotesSession
	Dim db As NotesDatabase
	Dim doc As NotesDocument
	Const UNID = "865DD0F4B37A00D94925864D00297C07"

	Set db = ss.Currentdatabase
	Set doc = db.Getdocumentbyunid(UNID)
	ForAll o In doc.Folderreferences
		Print o
	End ForAll
End Sub

NotesDocument クラスの FolderReferences プロパティは、文書が追加されているフォルダの名前を文字列の配列で返します。先ほど @WhichFolders 関数で確認した文書へ UNID を使ってアクセスし、デバッグウィンドウからその文書の FolderReferences プロパティを見たところ、配列の要素が1つだけで値は空っぽ(値なし)でした。

ヘルプには、この FolderReferences プロパティを使ってフォルダ名を取得するために必要なことがあると書かれています。それは次の2つです。

  • NotesDatabase クラスの FolderReferenceEnabled プロパティに True をセットする
  • $FolderInfo, $FolderRefInfo という2つのビューをメールDBからコピーする


そこで Domino Designer を使い、メールデータベースから2つのビューをコピー&ペーストしてビュー索引を更新し、先のコードを次のように変更して FolderReferenceEnabled に True をセットしました。

Sub Initialize
	Dim ss As New NotesSession
	Dim db As NotesDatabase
	Dim doc As NotesDocument
	Const UNID = "865DD0F4B37A00D94925864D00297C07"

	Set db = ss.Currentdatabase
	If Not db.Folderreferencesenabled Then
		db.Folderreferencesenabled = True
	End If
	Set doc = db.Getdocumentbyunid(UNID)
	ForAll o In doc.Folderreferences
		Print o
	End ForAll
End Sub

ところがフォルダ名はまだ空っぽのままです。

そこで、次のコードに書き換えました。新たに作成した文書を PutinFolder メソッドでフォルダへ追加した後に FolderReferences プロパティをみます。

Sub Initialize
	Dim ss As New NotesSession
	Dim db As NotesDatabase
	Dim folder As NotesView
	Dim doc As NotesDocument
	Const fB = "fB"
	
	Set db = ss.Currentdatabase
	Set doc = New NotesDocument( db )
	doc.Subject = "created by agent"
	doc.Save True, False
	
	doc.Putinfolder fB
	
	If Not db.Folderreferencesenabled Then
		db.Folderreferencesenabled = True
	End If
	
	ForAll o In doc.Folderreferences
		Print o
	End ForAll
End Sub

するとようやくフォルダ名が出力されました。

次の画像にはビュー上に2つの文書が表示されています。上のコードによって新たに作成された文書がビューの下側に表示されている文書です。ビューの3列目にあるfolder列には fB というフォルダ名が表示されています。

この文書のプロパティの「フィールド」タブには "$FolderRef" で始まる3つのアイテム($FolderRef, $FolderRefFlags, $FolderRefID )が追加されています。

この3つのアイテムですが、Notes のメニューから「アクション - フォルダから削除」を選び文書をフォルダから削除するとプロパティから消え、「アクション - フォルダへ移動」から再度フォルダへ追加すると再び現れます。※このとき文書の更新日時は変わりません


ビューに表示されている2つの文書のうち、上側の文書は最初に追加した文書です。この文書のプロパティには $FolderRef で始まる3つのアイテムはありません。しかしながらビューの folder 列には2つのフォルダ名(fA, fB)が表示されています(次の画像)。


どうやら、データベースの FolderReferenceEnabled プロパティが True に設定されていて、2つのビュー($FolderInfo, $FolderRefInfo)が存在するにもかかわらず、$FolderRef アイテムが存在しない文書が実はフォルダに追加されている場合があるようです。

このことから、特定の文書が追加されているフォルダ名を調べるために FolderReferences プロパティを使うことは、やめておいたほうが無難であることがわかりました。


次に、ビューの3列目に追加した @WhichFolders 関数の値を、当該文書の NotesViewEntry の ColumnValues プロパティから取得しようと試みました。ColumnValues プロパティは列の値を配列で返しますが、取得できた値の配列要素は2つしかなく、追加した3列目の要素が存在しませんでした。この試みも失敗です。


残念ながら、現状では全てのフォルダを走査するしか手が無いようです。ひねりも工夫もありませんが次のようなコードで調べることができました。

Sub Initialize
	Dim ss As New NotesSession
	Dim nav As NotesViewNavigator
	Dim ent As NotesViewEntry
	Dim dc As NotesDocumentCollection
	Dim doc As NotesDocument
	Dim foldername As String
	Dim docList List As String

	'フォルダ内にある文書をリストへ追加
	ForAll view In ss.Currentdatabase.Views
		If view.Isfolder Then
			foldername = view.Name
			Set nav = view.Createviewnav()
			Set ent = nav.Getfirst()
			While Not ent Is Nothing
				If IsElement(docList(ent.Noteid)) Then
					docList(ent.Noteid) = docList(ent.Noteid) & "," & foldername
				Else
					docList(ent.Noteid) = foldername
				End If
				Set ent = nav.Getnext(ent)
			Wend 
		End If
	End ForAll
	
	'どのフォルダにも追加されていない文書もリストに追加
	Set dc = ss.Currentdatabase.Alldocuments
	Set doc = dc.Getfirstdocument()
	While Not doc Is Nothing
		If Not IsElement(docList(doc.Noteid)) Then docList(doc.Noteid) = ""
		Set doc = dc.Getnextdocument(doc)
	Wend
    
	'リストを出力
	ForAll folder In docList
		Print "note id: " & ListTag( folder ) & ", folder: " & folder
	End ForAll
End Sub

バックグラウンドでも @WhichFolders のようにシンプルに調べることができるといいのになあ...


ちなみに、@WhichFolders を指定した列のプロパティでカテゴリ別を有効にしてみたところ、フォルダ名(列の値)が表示されなくなりました。ソートの昇順/降順を設定しても変化が見られません。相当特殊な関数のようです。

0 件のコメント:

コメントを投稿