Option Declare
Sub Initialize
%REM
DESCRIPTION:
This agent loop through documents listed in ViewDelete and marks documents that duplicates column
values of another doc. If set it also deletes duplicates docs found in that view.
NOTES:
Design of ViewDelete:
- View should consist of at least one sorted column. To check if documents duplicate more then
one value, the appropriate number of sorted columns should be added.
- The last column in view should be UNSORTED, and got formula which names the field marking
duplicates (It's the best if there are no values displayed in the last column). Example
formula: MARK_DUPLICATES
Customizing agent:
- set nameViewDelete apropriate if you want to use your own name of view
- markOnly - set true if you want agent only to set field marking duplicates, not to
delete duplicates phisically; set false if you want to delete duplicates phisically
- doCheckMarkTags - set true if you want to preserve field names clash (agent stops if it finds
documents that already got field with name the same as field marking duplicates; set false to
delete all documents which have fields named as field marking duplicates with value valueTagItem
- set valueTagItem if you wants to mark duplicates with another value
HISTORY:
2001-09-05, T.Zoltowski, created
%END REM
'name of search view
Const nameViewDelete = "ViewDelete"
'hard delete or just marking
Const markOnly = False
'do check if there is already a field marking duplicates on doc
Const doCheckMarkTags = True
'value marking duplicates
Const valueTagItem = "1"
Dim session As New NotesSession
Dim db As NotesDatabase
Set db = session.CurrentDatabase
Dim viewDelete As NotesView
Set viewDelete = db.GetView(nameViewDelete)
If viewDelete Is Nothing Then
Print |View "| & nameViewDelete & |" not found !? Exiting.|
Exit Sub
End If
Dim numberColumns As Integer
numberColumns = Ubound(viewDelete.Columns) + 1
'check if there is apropriate number of columns
If numberColumns < 2 Then
Print |There should be at least 2 columns in view "| & nameViewDelete & |" ! Exiting.|
Exit Sub
End If
Dim columnIndex As Integer
'check if apropriate columns are sorted (it's a MUST to correctly find duplicates)
For columnIndex = 0 To numberColumns - 2
If Not viewDelete.Columns(columnIndex).IsSorted Then
Print |Column | & (columnIndex + 1) & | in view "| & nameViewDelete & |" isn't sorted (it should be!) ! Exiting.|
Exit Sub
End If
Next
'check if last column is unsorted (don't want to resort docs in view at any chance)
If viewDelete.Columns(columnIndex).IsSorted Then
Print |Last column in view "| & nameViewDelete & |" is sorted (it shouldn't be!)! Exiting.|
Exit Sub
End If
Dim nameTagItem As String
'taking the name of field marking duplicates
nameTagItem = viewDelete.Columns(columnIndex).ItemName
'actual doc
Dim doc As NotesDocument
'doc preceding actual doc in view
Dim docPrev As NotesDocument
Set doc = viewDelete.GetFirstDocument
'are there any docs ?
If doc Is Nothing Then Exit Sub
'do any checks
If checkMarkTags(doc, nameTagItem, doCheckMarkTags) Then
Print |Doc has item "| & nameTagItem & |" - there could be marking clash (try another name)! Exiting.|
Exit Sub
End If
Set docPrev = doc
Set doc = viewDelete.GetNextDocument(doc)
If checkMarkTags(doc, nameTagItem, doCheckMarkTags) Then
Print |Doc has item "| & nameTagItem & |" - there could be marking clash (try another name)! Exiting.|
Exit Sub
End If
Dim countProcessed As Long
countProcessed = 1
Dim countDuplicates As Long
countDuplicates = 0
Do Until doc Is Nothing
If checkMarkTags(doc, nameTagItem, doCheckMarkTags) Then
Print |Doc has item "| & nameTagItem & |" - there could be marking clash (try another name)! Exiting.|
Exit Sub
End If
Dim isDuplicate As Variant
'we assume that actual doc is "identical" as previous
isDuplicate = True
For columnIndex = 0 To numberColumns - 2
If docPrev.ColumnValues(columnIndex) <> doc.ColumnValues(columnIndex) Then
'there is a difference in column values - it's not a duplicate
isDuplicate = False
Exit For
End If
Next
If isDuplicate Then
'mark duplicate
Call doc.ReplaceItemValue(nameTagItem, valueTagItem)
Call doc.Save(True, True)
countDuplicates = countDuplicates + 1
End If
countProcessed = countProcessed + 1
Print "Processed " & countProcessed & ", duplicates " & countDuplicates
'move to actual doc to next doc (move previous doc too)
Set docPrev = doc
Set doc = viewDelete.GetNextDocument(doc)
Loop
If countDuplicates > 0 Then
'we found some duplicates
If markOnly Then
'only mark - already done
Print "Finished processing document: " & countDuplicates & _
| found. Delete all docs with field "| & nameTagItem & |" set to "| & valueTagItem & |" manually.|
Else
'do hard delete
Print "Deleting duplicates"
'reference to doc being deleted (temporary)
Dim docRemove As NotesDocument
'we are moving upright starting at last doc - it preserves before sliding docs in view after
'deleting docs and refreshing index
Set doc = viewDelete.GetLastDocument
Dim countDeleted As Long
countDeleted = 0
Do Until doc Is Nothing
'reset reference to deleted doc
Set docRemove = Nothing
If doc.HasItem(nameTagItem) Then
If doc.GetItemValue(nameTagItem)(0) = valueTagItem Then
'if it's doc marked to removing
Set docRemove = doc
End If
End If
Set doc = viewDelete.GetPrevDocument(doc)
If Not docRemove Is Nothing Then
'if there is doc to delete
Call docRemove.Remove(True)
countDeleted = countDeleted + 1
Print "Deleted " & countDeleted & " of " & countDuplicates
End If
Loop
End If
End If
End Sub
Function checkMarkTags(doc As NotesDocument, itemName As String, doCheck As Variant) As Variant
If doCheck Then
If doc.HasItem(itemName) Then
checkMarkTags = True
Exit Function
End If
End If
checkMarkTags = False
End Function