Hi, using this agent posted by Alex Elliot here:
http://www-10.lotus.com/ldd/nd6forum.nsf/55c38d716d632d9b8525689b005ba1c0/dffc9ab974461c20852573cb00209bba?OpenDocument
I modified it to work through selected documents in a view.
How do I tell it that, if it encounters an error, just to leave the current document and move onto the next one?
Sorry, I’m sure this is trivial, but fried brain, 3:30 am in morning, and this is just a side detour in a larger project.
Sub Initialize
Dim Body As NotesRichTextItem
Dim DB As NotesDatabase
Dim Doc As NotesDocument
Dim SearchValue As String
Dim ReplaceValue As String
Dim NoteCollection As NotesDocumentCollection
Dim NoteDoc As NotesDocument
Dim RTNav As NotesRichTextNavigator
Dim RTRange As NotesRichTextRange
Dim RTItemUpdated As Boolean
Dim Session As New NotesSession
On Error Goto HandleErr
Set DB = Session.CurrentDatabase
Set NoteCollection = db.UnprocessedDocuments
Set Doc = NoteCollection.GetFirstDocument()
Set Body = Doc.GetFirstItem("Body")
For i = 1 To NoteCollection.Count
Print "Starting Doc " + Str$(i)
Set RTNav = Body.CreateNavigator
If RTNav.FindFirstElement(RTELEM_TYPE_TEXTPARAGRAPH) Then
RTItemUpdated = False
Set RTRange = Body.CreateRange
SearchValue = "/website/"
ReplaceValue = "/"
While RTRange.FindAndReplace(SearchValue, ReplaceValue, RT_FIND_CASEINSENSITIVE Or RT_REPL_ALL) > 0
RTItemUpdated = True
Call Body.Update ' Must update before looping
Wend
End If
If RTItemUpdated Then
Call Body.Compact
End If
Call Doc.Save (True, False)
Set Doc = NoteCollection.GetNextDocument(Doc)
Next
HandleErr:
Exit Sub
End Sub
Subject: How to get an agent to move onto next doc in view when error encountered.
You can put another label in your code (eg. nextdoc) and point the errorhandler to that label.
…
If RTItemUpdated Then
Call Body.Compact
End If
Call Doc.Save (True, False)
nextdoc:
Set Doc = NoteCollection.GetNextDocument(Doc)
Next
exit sub
HandleErr:
goto nextdoc
End Sub
Subject: How to get an agent to move onto next doc in view when error encountered.
For what it’s worth, I generally deal with this scenario by developing in a more modular fashion.
So, in this instance, I would write your code so that you traverse your document collection, calling a function on each document.
Within the function, set up error handling so that the function just aborts (via exit function)
Briefly, this would look like this:
sub Initialize
'// for each document in your collection
call ProcessDoc(doc)
end sub
function ProcessDoc(doc as notesdocument)
on error goto errorHandler
'//
'// Process your document
'//
exit function
errorHandler:
exit function
end function
On another note, your code has a significant error. You set up the note collection correctly, but you traverse your collection using a for…next loop. The best way to do this common routine is to do this:
dim ndc as NotesDocumentCollection
dim doc as NotesDocument
'// Set up your collection however you like
set doc = ndc.getFirstDocument()
do while not doc is Nothing
'// Process document
set doc = ndc.getNextDocument(doc) '// Sets doc to Nothing if no more docs in collection.
loop
Kind regards
Simon
Subject: RE: How to get an agent to move onto next doc in view when error encountered.
Many thanks to both of you.
For the benefit of those searching in the future, here is the code that works (I didn’t have time to do Simon’s modular approach.)
Note that the strings to search / replace on in the rich text are hardcoded as variables within the script. Ideally, they should be handled as prompts, but again, my deadline for the overall project (of which this was just a side-tool to speed my own work up) is hours away, so I don’t have time to add such prompts. Perhaps someone else can in the future.
Sub Initialize
Dim Body As NotesRichTextItem
Dim DB As NotesDatabase
Dim Doc As NotesDocument
Dim i As Integer
Dim SearchValue As String
Dim ReplaceValue As String
Dim NoteCollection As NotesDocumentCollection
Dim NoteDoc As NotesDocument
Dim RTNav As NotesRichTextNavigator
Dim RTRange As NotesRichTextRange
Dim RTItemUpdated As Boolean
Dim Session As New NotesSession
Dim StringFind As String
Dim StringReplace As String
On Error Goto HandleErr
StringFind = "/website/"
StringReplace = "/"
Set DB = Session.CurrentDatabase
Set NoteCollection = db.UnprocessedDocuments
Set Doc = NoteCollection.GetFirstDocument()
i = 0
Do While Not Doc Is Nothing
i = i + 1
If Doc.hasItem("Body") Then
Set Body = Doc.GetFirstItem("Body")
Print "Processing Doc " + Str$(i)
Set RTNav = Body.CreateNavigator
If RTNav.FindFirstElement(RTELEM_TYPE_TEXTPARAGRAPH) Then
RTItemUpdated = False
Set RTRange = Body.CreateRange
SearchValue = StringFind
ReplaceValue = StringReplace
While RTRange.FindAndReplace(SearchValue, ReplaceValue, RT_FIND_CASEINSENSITIVE Or RT_REPL_ALL) > 0
RTItemUpdated = True
Call Body.Update ' Must update before looping
Wend
End If
If RTItemUpdated Then
Call Body.Compact
End If
Call Doc.Save (True, False)
End If
nextdoc:
Set Doc = NoteCollection.GetNextDocument(Doc)
Loop
Exit Sub
HandleErr:
Goto nextdoc
End Sub
Subject: RE: How to get an agent to move onto next doc in view when error encountered.
Yes, it will work, and the code is better. I hope that you don’t mind if I point out that there is a weakness in your solution. If any error occurs anywhere in the code, even outside the main internal loop, the error handling routine will be invoked. Which will transfer control directly to the inside of a do while loop which was never invoked.
Better to put the on error code just before the do while not doc etc . . .
Better still to use a modular approach; while maybe not here given the constraints you’re working under, consider it in future. The use of functions and subroutines with their own internal error handling helps to make sure that errors are handled ‘within context’.
Also, do you know about the & operator?
Instead of using Print "Processing Doc " + Str$(i)
you can use
Print "Processing Doc " & i
(The & operator auto-converts non-string data to string data)
Cheers
Simon
Subject: RE: How to get an agent to move onto next doc in view when error encountered.
Kewl, thanks!
Okay, here’s the code as it currently stands.
Since I have a somewhat clearer head today, I’ve added the user prompts. Developers will just have to change the target field, currently hardcoded to body, to the appropriate rich text field.
Declarations:
Dim StringFind As Variant
Dim StringReplace As Variant
Function ProcessDoc(doc As notesdocument)
On Error Goto errorHandler
Set Body = Doc.GetFirstItem("Body")
Print "Processing Doc " & i
Set RTNav = Body.CreateNavigator
If RTNav.FindFirstElement(RTELEM_TYPE_TEXTPARAGRAPH) Then
RTItemUpdated = False
Set RTRange = Body.CreateRange
SearchValue = StringFind
ReplaceValue = StringReplace
While RTRange.FindAndReplace(SearchValue, ReplaceValue, RT_FIND_CASEINSENSITIVE Or RT_REPL_ALL) > 0
RTItemUpdated = True
Call Body.Update ' Must update before looping
Wend
End If
If RTItemUpdated Then
Call Body.Compact
End If
Call Doc.Save (True, False)
Exit Function
errorHandler:
Exit Function
End Function
Sub Initialize
Dim Body As NotesRichTextItem
Dim DB As NotesDatabase
Dim Doc As NotesDocument
Dim i As Integer
Dim SearchValue As String
Dim ReplaceValue As String
Dim NoteCollection As NotesDocumentCollection
Dim NoteDoc As NotesDocument
Dim RTNav As NotesRichTextNavigator
Dim RTRange As NotesRichTextRange
Dim RTItemUpdated As Boolean
Dim Session As New NotesSession
Dim ws As New NotesUIWorkspace
StringFind = ws.Prompt (PROMPT_OKCANCELEDIT, _
"What is the text you want to search for?","")
If Isempty (StringFind) Then
Messagebox "Sorry, need something to search for"
Exit Sub
End If
StringReplace= ws.Prompt (PROMPT_OKCANCELEDIT, _
"What is the text you want to replace it with?","Enter the word BLANK if you want to replace it with nothing.")
If Isempty (StringReplace) Then
Messagebox "Sorry, need something to search for"
Exit Sub
Elseif StringReplace = "BLANK" Then
StringReplace = ""
End If
Set DB = Session.CurrentDatabase
Set NoteCollection = db.UnprocessedDocuments
Set Doc = NoteCollection.GetFirstDocument()
i = 0
Do While Not Doc Is Nothing
i = i + 1
If Doc.hasItem("Body") Then
Call ProcessDoc(Doc)
End If
nextdoc:
Set Doc = NoteCollection.GetNextDocument(Doc)
Loop
Exit Sub
HandleErr:
Goto nextdoc
End Sub