2010年2月17日水曜日

迷子の文書を捜す

文書をディスカッション形式で表示するビューではフォームの種類として「文書」、「返答」、「返答への返答」の3つがよく使われます。

「文書」で作成した文書を"親"とすると、
「返答」で作成した文書は、「文書」フォームで作成した文書の"子"になり、
「返答への返答」で作成すると、現在開いている文書の"子"になります。

ややこしいですね。

"親"への返答は"孫"を開いている時には作成しない、といった要件の場合、「返答」を使わず「文書」と「返答への返答」の2つでディスカッションを実現することがあります。

と、前置きはここまでにして、本題です。

ディスカッション形式のビューでは、階層の上にある文書が削除されてしまうと、削除された文書の下の階層にあった文書が表示されなくなります。

このように表示されなくなった文書の数を調べるエージェントを作ってみました。
(Declarations)
Dim db As NotesDatabase

Sub Initialize
    Dim ss As New NotesSession
    Dim dc As NotesDocumentCollection
    Dim doc As NotesDocument
    Dim cnt As Long
    Set db = ss.CurrentDatabase
    Set dc = db.Search( |@IsAvailable($Ref)|, Nothing, 0 )
    If dc.Count = 0 Then Exit Sub
    Set doc = dc.GetFirstDocument
    cnt = 0
    While Not ( doc Is Nothing )
        If Not isActiveRef( doc ) Then cnt = cnt + 1
        Set doc = dc.GetNextDocument( doc )
    Wend
    Print "「" & db.Title & "」の迷子文書は " & Cstr( cnt ) & " 件でした。"
End Sub

Function isActiveRef( doc As NotesDocument ) As Boolean
    Dim parent As NotesDocument
    Dim unid As String
    isActiveRef = True
    unid = doc.GetItemValue( "$Ref" )( 0 )
    Set parent = db.GetDocumentByUNID( unid )
    If parent Is Nothing Then '親が存在しない
        isActiveRef = False
    Else
        If Not parent.IsValid Then '親が削除スタブで存在
            isActiveRef = False
        Else
            If parent.HasItem( "$Ref" ) Then '親の親が存在
                If Not isActiveRef( parent ) Then
                    isActiveRef = False
                End If
            End If
        End If
    End If
End Function

簡単にロジックを説明します。

「返答」「返答への返答」で作成した文書には $Ref というアイテムが自動で作成され、値として返答元文書の UNID が設定されます。

つまり $Ref というアイテムがある文書は子文書というわけです。

$Ref の UNID から親文書を探す、つまり階層をさかのぼっていくわけですが、この時
・文書が見つからない
・文書が削除スタブ
の場合、迷子と認定します。

逆に削除スタブでなく $Ref がない文書に辿りつくことができれば、それは迷子ではありません。

0 件のコメント:

コメントを投稿