Using @PickList with LotusScript agents

This tip describes using @PickList with LotusScript agents.

This Content Component encountered an error

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.

 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

This was first published in February 2003

Dig deeper on Lotus Notes Domino Formula Language

0 comments

Oldest 

Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to:

-ADS BY GOOGLE

SearchWindowsServer

Search400

  • iSeries tutorials

    Search400.com's tutorials provide in-depth information on the iSeries. Our iSeries tutorials address areas you need to know about...

  • V6R1 upgrade planning checklist

    When upgrading to V6R1, make sure your software will be supported, your programs will function and the correct PTFs have been ...

  • Connecting multiple iSeries systems through DDM

    Working with databases over multiple iSeries systems can be simple when remotely connecting logical partitions with distributed ...

SearchEnterpriseLinux

SearchDataCenter

SearchExchange

SearchContentManagement

Close