How to get an agent to move onto next doc in view when error encountered

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