
AGENT
Using @PickList with LotusScript agents
Richard Day 02.24.2003
Rating: -2.71- (out of 5)




|
You Can View User Feedback To This Tip
I recently had to write an agent that required assigning selected documents to a new parent within an application. The list of choices for the target document was far too large to fit into a text field that I could include in a LotusScript DialogBox() call and the agent was complex enough that the re-assignment had to be done with script. With some help from my friends, I came up with the following solution using a mix of simple actions, @Formula agents and a scripted agent to do the job.
The solution involves 4 agents:
- The first simply calls the other 3 in order
- The second collects the UNIDs for the selected docs and writes them to a user's profile document
- The third prompts the user to pick a target document
- The fourth pulls the information from the profile doc and does all the work. It also deletes the profile document so that you are starting from a clean copy every time you run the agent.
Code
Agent1: (Simple Action)
==========================
Run Agent "Agent2"
Run Agent "Agent3"
Run Agent "Agent4"
Agent2: (Formula - run on selected
docs from agent list)
This agent builds a list of UNID values
for all of the selected documents.
==================================
init := @GetProfileField( "Reassign";
"SourceDocs"; @UserName);
@SetProfileField( "Reassign";
"SourceDocs"; @Trim( @Explode(init; ";") :
@Text(@DocumentUniqueID));
@UserName);SELECT @All
Agent3: (Formula - run once from
agent list)
This agent uses @PickList call to
allow you to select a target document.
==================================
init := @GetProfileField( "Reassign";
"SourceDocs"; @UserName);
@If( @IsError(init); @Return( @Prompt([OK];
"Error"; "No source documents were
selected."));
init = ""; @Return( @Prompt([OK];
"Error"; "No source documents were
selected."));
""
);
REM "2nd column is UNID";
trgDoc := @PickList( [Custom] : [Single];
""; "Co"; "Select Target"; "Select the
target document that you want to
assign the select documents to: "; 2);
@If( @IsError(trgDoc);
@Do(
@SetProfileField( "Reassign";
"SourceDocs"; ""; @UserName);
@Return( @Prompt([OK]; "Error";
"No target document was selected."))
);
trgDoc = "";
@Do(
@SetProfileField( "Reassign";
"SourceDocs"; ""; @UserName);
@Return( @Prompt([OK]; "Error";
"No target document was selected."))
);
""
);
@SetProfileField( "Reassign";
"TargetDoc"; trgDoc; @UserName)
Agent4: (LotusScript - run once from
agent list)
This agent gets the source and target
UNIDs from the user's profile document
and performs the reassignment.
==================================
(Declarations)
%INCLUDE "lsconst.lss"
Dim session As NotesSession
Dim currentDb As NotesDatabase
Dim activityMessage As String
Sub Initialize
On Error Goto ErrorHandler
Dim workspace As New NotesUIWorkspace
Dim pDoc As NotesDocument
Dim tDoc As NotesDocument
Dim sDoc As NotesDocument
Dim tDocID As String
Dim msg As String
Dim docCount As Long
Dim goodCount As Long
activityMessage = "Initializing"
docCount = 0
goodCount = 0
Set session = New NotesSession
Set currentDb = session.CurrentDatabase
Set pDoc = currentDb.GetProfileDocument
( "Reassign", session.UserName)
If( pDoc Is Nothing) Then Error 6000,
"Unable to locate Profile Document for
" + session.UserName
' get handle to target document
activityMessage = "Getting target client
profile"
tDocID = pDoc.TargetDoc(0)
' user cancelled out of @PickList
If( tDocID = "") Then Error 5000,
"Operation cancelled at your request."
Set tDoc = currentDb.GetDocumentByUNID
( tDocID)
If( tDoc Is Nothing) Then Error 6001,
"Unable to locate target doc by ID (" + tDocID + ")"
' process all selected docs from the
profile document
Forall docID In pDoc.SourceDocs
activityMessage = "Reassigning
document (" + Cstr( docID) + ")"
docCount = docCount + 1
Set sDoc = currentDb.GetDocumentByUNID
( docID )
' perform check of applicable
business rules - not included here
If( Not( isOK( sDoc, tDoc, msg))) Then
Msgbox msg, MB_ICONEXCLAMATION,
"Document not reassigned!"
Else
activityMessage = "Reassigning document
(" + Cstr( docID) + ") - OK - starting transfer"
' do the transfer (code not included)
Call ReassignDoc( sDoc, tDoc)
activityMessage = "Reassigning document
(" + Cstr( docID) + ") - transfer complete"
goodCount = goodCount + 1
End If
End Forall
' clean up
If( Not( pDoc Is Nothing)) Then Call
pDoc.Remove( True)
Print "Removed profile document."
Msgbox "Reassigned " + Cstr( goodCount)
+ " of " + Cstr( docCount) + " documents."
, MB_ICONINFORMATION, "Complete!"
Exit Sub
ErrorHandler:
On Error Resume Next
' cleanup
If( Not( pDoc Is Nothing)) Then Call
pDoc.Remove( True)
' report error
If( Err > 5555) Then
Msgbox "Error (" + Cstr( Err) + ") while " +
activityMessage + ": " + Error$, MB_ICONSTOP,
"Error!"
Else
Msgbox Error$, MB_ICONINFORMATION,
"Reassign Documents"
End If
Exit Sub
End Sub
USER FEEDBACK TO THIS TIP
This is in response to Richard Day's February 24 Post "Using @Picklist with LotusScript" is a vastly simpler way do do the same thing--one that requires only a single agent. Just use the PicklistCollection method, which Lotus kindly gave us in R5. The practice of chaining agents together like this is common in the Lotus Notes world, but in fact it is very rarely needed and greatly complicates support. The desired functionality can nearly always be done in a single LS agent, and it's much easier to read. This agent gets the source and target documents DIRECTLY, and performs the reassignment or whatever all within it's body. This is just an example of how the 4 agents recently highlighted on SearchDomino can in fact be combined into one.
This agent replaces agent 1 through 4 and should be set to run on selected documents. ==================================
(Declarations) %INCLUDE "lsconst.lss" Dim session As NotesSession Dim currentDb As NotesDatabase Dim activityMessage As String Sub Initialize On Error Goto ErrorHandler %Rem
Cregg's Comment: This practice of creating a catch all error trap is generally unproductive -- I think people add them out of a sense that they ought to handle all errors. This is wrong. The system already handles all errors. All you need worry about is errors from which you can recover. Having an error message pop up is a perfectly reasonable response to an unforeseen and therefore unrecoverable error. And since the error trap gets in the way of finding the offending line during debug, it doesn't buy you anything. It does let you present the user with a more friendly message, perhaps including the developer's phone number, but then such information can come to have it's own support costs over time. This particular error trap uses a running text variable to record the "Current status" for display in the error message. That's a nice idea and I have seen it before. But realistically, are you going to keep that status message updated as you update the code? Are you going to trust another developer to have done so? Heck No! So the first thing you will have to do in support it verify the "activity status" by turning of the error trap -- My advice is skip it altogether.
Write specific traps to handle specific, recoverable errors, and the rest of the time leave is set to ON Error Goto 0. %End Rem Dim workspace As New NotesUIWorkspace Dim tDoc As NotesDocument Dim sDoc As NotesDocument Dim msg As String Dim docCount As Long Dim goodCount As Long activityMessage = "Initializing" docCount = 0 goodCount = 0 Set session = New NotesSession Set currentDb = session.CurrentDatabase dim selected as notesdocumentcollection dim targetcollection as notesdocumentcollection set selected=currentDb.unprocesseddocuments if selected.count=0 then Messagebox "You have not selected any documents to reassign.",MB_ICONSTOP,db.title exit sub end if set targetcollection =workspace.picklistcollection(PICKLIST_CUSTOM,false,db.server,db.filepath, "Select Target"; "Select the target document that you want to assign the select documents to: ") if targetcollection.count<>1 then MessageBox "No target document was selected.",MB_ICONSTOP,db.title Exit Sub end if activityMessage = "Getting target doc" Set tDoc = GetFirstDocument ' process all selected docs from the profile document dim index as integer activityMessage = "Reassigning selected documents...." For index =1 to Selected.count Set sDoc = Selected.GetNthDocument(Index ) activityMessage = "Reassigning document (" + Cstr( sdoc.universalid) + ")" ' perform check of applicable business rules - not included here If( Not( isOK( sDoc, tDoc, msg))) Then Msgbox msg, MB_ICONEXCLAMATION, "Document not reassigned!" Else activityMessage = "Reassigning document (" + Cstr( sdoc.universalid) + ") - OK - starting transfer" ' do the transfer (code not included) Call ReassignDoc( sDoc, tDoc) activityMessage = "Reassigning document (" + Cstr( sdoc.universalid) + ") - transfer complete" goodCount = goodCount + 1 End If End Forall Msgbox "Reassigned " + Cstr( goodCount) + " of " + Cstr( index) + " documents.", MB_ICONINFORMATION, "Complete!" Exit Sub ErrorHandler: On Error Resume Next ' report error If( Err > 5555) Then Msgbox "Error (" + Cstr( Err) + ") while " + activityMessage + ": " + Error$, MB_ICONSTOP, "Error!" Else Msgbox Error$, MB_ICONINFORMATION, "Reassign Documents" End If Exit Sub Cregg Hardwick
 |

|
Rate this Tip
|
To rate tips, you must be a member of SearchDomino.com. Register now
to start rating these tips. Log in if you are already a member.
|


');
// -->
DISCLAIMER: Our Tips Exchange is a forum for you to share technical advice and expertise with your peers and to learn from other enterprise IT professionals. TechTarget provides the infrastructure to facilitate this sharing of information. However, we cannot guarantee the accuracy or validity of the material submitted. You agree that your use of the Ask The Expert services and your reliance on any questions, answers, information or other materials received through this Web site is at your own risk.
|
 |
|
|
 |
|
 |