RunOnServer Agent - help please!

Hi all,

I had a great Action Button, but then realised that normal users would not have access to open other databases to create a document.

So I read about invoking an Agent to RunOnServer. This should then use the Agent Signers authority.

However, I cannot debug the agent. Probably as it runs on the server rather than in the client.

Please could somebody tell me why the agent is not doing anything, or how to debug it in some way.

Basically, the Appointment is created & on Saving the agent needs to loop through names in a field, find a database, open it, then create a document in the database, based on info from the appointment document.

This all worked as an Action, so it must be the way the document info is being passed to the agent.


Action Button


Sub Click(Source As Button)

'Set Dimensions

Dim session As New NotesSession

Dim workspace As New NotesUIWorkspace

Dim db As NotesDatabase

Dim uidoc As NotesUIDocument

Dim doc As NotesDocument

Dim agent As NotesAgent

'Get Current Document to work on

Set uidoc = workspace.CurrentDocument

Set doc = uidoc.Document

'Save current document

Call doc.Save(True, False)

'Start agent and pass note ID of doc

Set db = session.CurrentDatabase

Set agent = db.GetAgent("Agent Code")

Call agent.RunOnServer(doc.NoteID)



'Save current document	

Call uidoc.Save

Call uidoc.Close

End Sub


Agent Code


Sub Initialize

Dim session As New NotesSession

Dim db As NotesDatabase		

Dim doc As NotesDocument

Dim doc1 As NotesDocument

Dim doc2 As NotesDocument

Dim item As NotesItem



Dim agent As NotesAgent

Set agent = session.CurrentAgent

Set db = session.CurrentDatabase

'Get document used for passing data

Set doc = db.GetDocumentByID(agent.ParameterDocID)

'Run Loop through any names in AlarmDialog Field

Forall n In doc.AlarmDialog

'Get current NAB

	Dim nab As NotesDatabase

	Set nab = session.GetDatabase("Spinoza" , "names.nsf")

'Get view in NAB

	Dim view As NotesView

	Set view = nab.GetView("($Users)")

'Find person in view

	Set doc1 = view.GetDocumentByKey( n, True)

'Find mailfile field value from document

	homeserver = doc1.GetItemValue("mailserver")	

	mailfile = doc1.GetItemValue("mailfile")

'Get database to create document in

	Set db = session.GetDatabase( homeserver(0) , mailfile(0))

'Create mini-doc

	Set doc2 = New NotesDocument(db)

	Set item = doc.GetFirstItem("$Alarm")

	Call item.CopyItemToDocument(doc2, "$Alarm")

	Set item = doc.GetFirstItem("$AlarmOffset")

	Call item.CopyItemToDocument(doc2, "$AlarmOffset")

	If doc.HasItem("RepeatDates") Then

		Set item = doc.GetFirstItem("RepeatDates")

	Else

		Set item = doc.GetFirstItem("CalendarDateTime")	

	End If

	Call item.CopyItemToDocument(doc2, "CalendarDateTime")

	Call item.CopyItemToDocument(doc2, "PostedDate")

	Set item = doc.GetFirstItem("Subject")

	Call item.CopyItemToDocument(doc2, "Subject")		

'Save and move mini-doc to folder

	Call doc2.Save(True , False , True)

	Call doc2.PutInFolder ("($Alarms)")

	

	

End Forall

'Delete document used for passing data

Set db = session.CurrentDatabase

Call doc.Remove(True)

End Sub

Subject: RunOnServer Agent - help please!!

Well, To start I’d suggest you put an error handler in and print or log any errors with an agent log (noteslog class). Be sure to include the error line.

Second, your main loop could use some work - try:

dim destdb as notesdatabase

Dim nab As NotesDatabase

Dim view As NotesView

'Get current NAB

Set nab = session.GetDatabase(“Spinoza” , “names.nsf”)

'Get view in NAB

Set view = nab.GetView(“($Users)”)

Forall n In doc.AlarmDialog

'Find person in view

Set doc1 = view.GetDocumentByKey( n, True)

'Find mailfile field value from document

homeserver = doc1.GetItemValue(“mailserver”)

mailfile = doc1.GetItemValue(“mailfile”)

'Get database to create document in

Set destdb = session.GetDatabase( homeserver(0) , mailfile(0))

'Create mini-doc

Set doc2 = New NotesDocument(destdb)

Set item = doc.GetFirstItem(“$Alarm”)

Call item.CopyItemToDocument(doc2, “$Alarm”)

Set item = doc.GetFirstItem(“$AlarmOffset”)

Call item.CopyItemToDocument(doc2, “$AlarmOffset”)

If doc.HasItem(“RepeatDates”) Then

Set item = doc.GetFirstItem(“RepeatDates”)

Else

Set item = doc.GetFirstItem(“CalendarDateTime”)

End If

Call item.CopyItemToDocument(doc2, “CalendarDateTime”)

Call item.CopyItemToDocument(doc2, “PostedDate”)

Set item = doc.GetFirstItem(“Subject”)

Call item.CopyItemToDocument(doc2, “Subject”)

'Save and move mini-doc to folder

Call doc2.Save(True , False , True)

Call doc2.PutInFolder (“($Alarms)”)

End Forall

Subject: Agent Signer cannot open NAB ??

Ok,

I have generated an error message

It appears that the Agent Signer cannot open the NAB on the server specified in the code.

This is the relevant code where it would need to access the NAB

Dim view As NotesView

Dim nab As NotesDatabase

Set nab = session.GetDatabase(“Spinoza” , “names.nsf”)

Set view = nab.GetView(“($Users)”)

The Signer has Manager access to all databases on the server. Although it is within a group.

Any Ideas?

Subject: RE: Agent Signer cannot open NAB ??

If the specified server is not the same as the server on which the agent runs, then it MUST be R6 or newer and I believe it also needs to have the calling server in the trusted servers field of the config document.

Subject: Better - Can open databases!

Now…I have managed to get the Agent to Open the NAB.

I have also managed to get the agent to open the relevant users databases.

The problem was that in the Agent, the GetItemValue, to retrieve the servername from the $users view in the NAB, returned the full server name (CN=…/…/…)

Wether this was the case before I don’t know, but it did work before. But for the agent I have extracted the common name of the server.

homeserver = doc1.GetItemValue(“mailserver”)

databasename = mailserver.Common

mailfile = doc1.GetItemValue(“mailfile”)

Set destdb = session.GetDatabase( databasename(0) , mailfile(0))

Subject: Now - Error: Variant does not contain a container

Now the agent can open the relevant database, this error must be when the agent is trying to ‘GetItem’ from the doc.


I have passed a document from the action that initiated the Agent.


Set uidoc = workspace.CurrentDocument

Set doc = uidoc.Document

Call doc.Save(True, False)

Set db = session.CurrentDatabase

Set agent = db.GetAgent(“Agent to be run LotusScript”)

Call agent.RunOnServer(doc.NoteID)


Then called the document in the Agent


Set agent = session.CurrentAgent

Set db = session.CurrentDatabase

Set doc = db.GetDocumentByID(agent.ParameterDocID)

Dim destdb As notesdatabase

Set destdb = session.GetDatabase( databasename(0) , mailfile(0))

Set doc2 = New NotesDocument(destdb)

Set item = doc.GetFirstItem(“$Alarm”)

Call item.CopyItemToDocument(doc2, “$Alarm”)

Is there a problem in the way I have called the document across?

Subject: RE: Now - Error: Variant does not contain a container

which line is causing the error? erl will give you the error line.

Subject: RE: Now - Error: Variant does not contain a container

This is the code I currently have. I have placed the Error Log at the bottom.

It appears to start having problems with the Object Variable, when the code is trying to extract the item ‘mailserver’ from the server document found in the NAB.

Sub Initialize

On Error Goto errhandler



    Dim session As New NotesSession

    Dim db As NotesDatabase		

Dim doc As NotesDocument

Dim doc1 As NotesDocument

Dim doc2 As NotesDocument

Dim agent As NotesAgent

Dim item As NotesItem

Dim nab As NotesDatabase

Dim view As NotesView		

Dim homeserver As NotesName

Dim databasename As Variant

Dim mailfile As Variant

Dim destdb As notesdatabase





Set agent = session.CurrentAgent

Set db = session.CurrentDatabase	

'Get document used for passing data

Set doc = db.GetDocumentByID(agent.ParameterDocID)	

Call doc.Save(True , False , True)

'Run Loop through any names in AlarmDialog Field

Forall n In doc.AlarmDialog

'Get current NAB

	Set nab = session.GetDatabase("" , "names.nsf")

'Get view in NAB

	Set view = nab.GetView("($Users)")

'Find person in view

	Set doc1 = view.GetDocumentByKey( n, True)

'Find mailfile field value from document

	Set homeserver = doc1.GetItemValue("mailserver")

	databasename = homeserver.Abbreviated

	mailfile = doc1.GetItemValue("mailfile")

'Get database to create document in

	Set destdb = session.GetDatabase( databasename(0) , mailfile(0))

	Set doc = db.GetDocumentByID(agent.ParameterDocID)	

'Create mini-doc

	Set doc2 = New NotesDocument(destdb)

	Set item = doc.GetFirstItem("$Alarm")

	Call item.CopyItemToDocument(doc2, "$Alarm")

	Set item = doc.GetFirstItem("$AlarmOffset")

	Call item.CopyItemToDocument(doc2, "$AlarmOffset")

	If doc.HasItem("RepeatDates") Then

		Set item = doc.GetFirstItem("RepeatDates")

	Else

		Set item = doc.GetFirstItem("CalendarDateTime")	

	End If

	Call item.CopyItemToDocument(doc2, "CalendarDateTime")

	Call item.CopyItemToDocument(doc2, "PostedDate")

	Set item = doc.GetFirstItem("Subject")

	Call item.CopyItemToDocument(doc2, "Subject")		

'Save and move mini-doc to folder

	Call doc2.Save(True , False , True)

	Call doc2.PutInFolder ("($Alarms)")

	

End Forall

'Delete document used for passing data

Set db = session.CurrentDatabase

ErrHandler:

Print "Got Error " & Cstr( Err() ) & " " & Error() & " in line: " & Cstr( Erl() )

Resume Next

End Sub


Error Log


24/02/2005 14:11:06 Agent printing: Got Error 91 Object variable not set in line: 36

24/02/2005 14:11:06 Agent printing: Got Error 91 Object variable not set in line: 37

24/02/2005 14:11:06 Agent printing: Got Error 91 Object variable not set in line: 38

24/02/2005 14:11:06 Agent printing: Got Error 184 Variant does not contain a container in line: 41

24/02/2005 14:11:06 Agent printing: Got Error 4250 You must specify a parent database in line: 45

24/02/2005 14:11:06 Agent printing: Got Error 4207 Function requires a valid ADT argument in line: 47

24/02/2005 14:11:06 Agent printing: Got Error 91 Object variable not set in line: 49

24/02/2005 14:11:06 Agent printing: Got Error 91 Object variable not set in line: 55

24/02/2005 14:11:06 Agent printing: Got Error 91 Object variable not set in line: 56

24/02/2005 14:11:06 Agent printing: Got Error 4207 Function requires a valid ADT argument in line: 58

24/02/2005 14:11:06 Agent printing: Got Error 91 Object variable not set in line: 61

24/02/2005 14:11:06 Agent printing: Got Error 91 Object variable not set in line: 62

24/02/2005 14:11:06 Agent printing: Got Error 0 in line: 0

24/02/2005 14:11:06 Agent printing: Got Error 20 RESUME without error in line: 71

Subject: RE: Now - Error: Variant does not contain a container

You should add Option Explicit to your agent if you have not already. It looks like databasename is a string, so referencing databasename(0) will produce something like Variant does not contain a container. Basically you’re referring to a variable that doesn’t exist. Take off the (0).

databasename = mailserver.Common

mailfile = doc1.GetItemValue(“mailfile”)

Set destdb = session.GetDatabase( databasename(0) , mailfile(0))

And don’t use the extended syntax value = document.fieldname. It’s too easy to make hard-to-spot mistakes. Say instead

dim db as notesdatabase

dim server as notesitem

set databasename = doc1.getFirstitem(“ServerName”)

set db = new notesdatabase(databasename.values(0),“somepath\foo.nsf”)

etc

Subject: RunOnServer Agent - help please!!

You can’t run an agent on the server that uses UI classes… the AMGR will abort execution with an error. You have to work around the UI, as there’s not workspace or user interface available locally on the server… good luck :wink: