私はリチャードのソリューションが本当に好きですが、最近、私が今のところ気に入っている派生物を実装しました。基本的に、各ドキュメントのメタデータを「インデックス」である個別のデータベースに配置し、インデックス ドキュメントを開くと、alldocs.nsf 内のドキュメントが開かれます (インデックス ドキュメントが閉じられます)。
これを行うには、文書が変更または保存されるたびにインデックス文書を作成するエージェントを alldocs.nsf に記述します。インデックス作成に使用するフィールド (メタデータ) のみをコピーする必要があります。インシデントのコピーからメインエージェントにこれを行うためのサンプル コード (サブルーチンや呼び出し関数なし) :
Sub Initialize
Dim session As New NotesSession
Dim maindb As NotesDatabase ' Main SIR
Dim mainincidents As NotesView ' view in Main SIR
Dim maindoc As NotesDocument ' document in Main SIR
Dim projectdoc, nextprojectdoc As NotesDocument ' document in this database
Dim ndc As NotesDocumentCollection ' unprocessed documents in this database
Dim fieldItem As NotesItem
Dim reportnumber, value, formtype As Variant
Dim fieldsToCopy (10) As String
Dim reason As String
On Error GoTo errorhandler
Call StartAgentLogging ( session )
Set thisdb = session.Currentdatabase
' find all unstamped documents
Set ndc = thisdb.Unprocesseddocuments
If ndc.Count = 0 Then
Call agentLog.LogAction ( "No incidents to process" )
Exit Sub
End If
maindbfilepath = DetermineKeyword("MAINSIR")
Set maindb = session.Getdatabase("","")
Call maindb.Open("", maindbfilepath)
If Not maindb.Isopen Then
reason = "Main Security database could not be found at " & maindbfilepath
Call agentLog.LogAction ( reason )
MessageBox reason, 16, "Error"
Exit Sub
End If
Set mainincidents = maindb.Getview("(Incidents for Upload)")
Set projectdoc = ndc.Getfirstdocument()
fieldsToCopy (0) = "ReportType"
fieldsToCopy (1) = "ReportNumber"
fieldsToCopy (2) = "ReportDate"
fieldsToCopy (3) = "IncidentDate"
fieldsToCopy (4) = "ProjectName"
fieldsToCopy (5) = "ProjectCountry"
fieldsToCopy (6) = "ProjectLocation"
fieldsToCopy (7) = "ReporterName"
fieldsToCopy (8) = "ReporterPhone"
fieldsToCopy (9) = "ReporterEmail"
fieldsToCopy (10) = "Appointment"
While Not projectdoc Is Nothing
formtype = projectdoc.GetItemValue ("Form")
If formtype(0) = "Incident" Then
' check to see if that exists in the main SIR
reportnumber = projectdoc.GetItemValue("ReportNumber")
Call agentLog.LogAction ( "Checking " & reportnumber(0) )
Set maindoc = mainincidents.GetDocumentByKey(reportnumber(0), True)
Call agentLog.LogAction ( "Accessing " & reportnumber(0) )
If maindoc Is Nothing Then
Call agentLog.LogAction ( "Main does not contain " & reportnumber(0) & " creating new document." )
' if not, create new document
Set maindoc = maindb.Createdocument()
maindoc.Form = "Incident"
ForAll fieldname In fieldsToCopy
Call agentLog.LogAction ( "Field name: " & fieldname )
Set fieldItem = projectdoc.Getfirstitem(fieldname)
Call maindoc.Copyitem(fieldItem, fieldname)
End ForAll
Call maindoc.Save(True, False)
Call CreateNotice ( maindoc )
Else
Call agentLog.LogAction ( "Main contains " & reportnumber(0) & " updating document." )
' if it does, update data
ForAll fieldname In fieldsToCopy
Call agentLog.LogAction ( "Field name: " & fieldname )
value = projectdoc.GetItemValue(fieldname)
Call maindoc.ReplaceItemValue(fieldname, value(0))
End ForAll
End If
'Path and filename
Call maindoc.Replaceitemvalue("Path", thisdb.Filepath)
Call maindoc.Save(True, False)
Call agentLog.LogAction ( "Saved " & reportnumber(0) )
Else
Call agentLog.LogAction ( "Project form is " & projectdoc.Form(0) )
End If
' stamp document as processed
Set nextprojectdoc = ndc.GetNextDocument(projectdoc)
Call session.Updateprocesseddoc(projectdoc)
Set projectdoc = nextprojectdoc
Wend
exiting:
Exit Sub
errorhandler:' report all errors in a messagebox
reason = "Error #" & CStr (Err) & " (" & Error & ") when creating incident in Main database, on line " & CStr (Erl)
Call agentLog.LogAction ( reason )
MessageBox reason, 16, "Error"
Resume exiting
End Sub
次に、インデックス データベースのインデックス フォームの onLoad イベントにコードを追加する必要があります。私は ToolsRunMacro によって呼び出されるエージェントに私のものを入れましたが、直接入れることもできます。これは私のOpen Project Copyエージェントです。
Sub Initialize
' this button opens the incident report in the project database
Dim ws As New NotesUIWorkspace
Dim session As New NotesSession
Dim reportdb As NotesDatabase
Dim view As NotesView
Dim uidoc As NotesUIDocument
Dim thisdoc, reportdoc As NotesDocument
Dim filepath, reportnumber As Variant
Dim baseurl, opener, unid As String
Call StartAgentLogging ( session )
Set thisdb = session.Currentdatabase
Set uidoc = ws.CurrentDocument
Set thisdoc = uidoc.Document
filepath = thisdoc.GetItemValue ( "Path" )
reportnumber = thisdoc.GetItemValue ( "ReportNumber" )
Set reportdb = session.GetDatabase (thisdb.Server, filepath (0), False )
If reportdb Is Nothing Then
MessageBox ( "Could not find Project Security Incident Report database" & Chr$(10) & thisdb.Server & "\" & filepath(0) )
Call agentLog.LogAction ( "Could not find Project Security Incident Report database" & Chr$(10) & thisdb.Server & "\" & filepath(0) )
Exit Sub
End If
If Not reportdb.Isopen Then
Call reportdb.Open(thisdb.Server, filepath (0))
End If
Set view = reportdb.GetView ( "Incidents" )
Set reportdoc = view.GetDocumentByKey ( reportnumber(0) )
If reportdoc Is Nothing Then
MessageBox ( "Could not find Report #" & reportnumber(0) )
Call agentLog.LogAction ( "Could not find Report #" & reportnumber(0) )
Exit Sub
End If
Call uidoc.Close
unid = reportdoc.UniversalID
baseurl = reportdb.NotesURL
opener = Left$ ( baseurl, InStr ( baseurl, "?" ) -1 ) & "/Incidents/" & unid & "?OpenDocument"
Call ws.URLOpen ( opener )
Call agentLog.LogAction ( "Opened Report #" & reportnumber(0) )
End Sub
これで、インデックス データベースを最新のドキュメントのみに制限したり、すべてのドキュメントが含まれている場合の動作を確認したりできます。ビューで使用できるようにする必要があるデータの量に大きく依存します。
私の状況では、インデックス データベースには多くのデータベースからのドキュメントのインデックス ドキュメントが含まれており、「完全なデータ」データベースの中央アクセス ポイントとして機能します。まだテスト段階なので、うまくいくかどうかはわかりませんが、可能性として提供したいと思います。