I have written lotusscript code in Agent, i need to run the agent by on clicking the button in Xpage.
How could i achieve?
Thanks in advance
A problem with this solution could be that when you want to use data which is manipulated in the agent you have to reload the notes document in your xpage. This can be done with the following lines of code:
var ag = database.getAgent("agentname");
if(ag != null){
var id = doc.noteid;
ag.runonserver(id);
doc.recycle();
doc = database.getdocumentbyid(id);
// check if the agent did its job.
// if so do stuff otherwhise report this to the user?
}
Since version 8.5.2 there is a new method added to the agent class
agent.runWithDocumentContext(NotesDocument doc);
This method uses the in memory document of the xPage. Therefore you don't need to save your document in the agent itself but you can make your changes and exit the agent code. The xpage can directly make use of the changes made. This saves you a lot of hassle with checking if the agent did his job, reloading the document etc etc.
For this to work you have to set the options of your agent to
Run as web user
Allow restricted operations
the type of agent is "Agent list selection" with target "none"
simply call this on click event (there is no difference what language is used for agent)
database.getAgent("agentName").run() or database.getAgent("agentName").runOnServer()
notice that Runtime for agent has to be like that
Related
I have created an Xpage to allow the administrator to input a single Notes Document (They are Contracts) ID into an edit box and press a button to delete the Contract. The delete calls an Agent passing the Contract ID. Below is the button script and then the relevant part of the Agent. What is happening is only the first character is being passed to the Agent, i.e if the Contract ID is 9MXCB4 only "9" is being passed as the Agent message box prints this to the log. What am I doing wrong here? If I hard code a Contract ID after the message box the Contract is processed correctly.
Button code
ag = database.getAgent("DeleteOneContract");
noteid = getComponent("ContractIDDelete").getValue()
ag.run(noteid)
Part of Agent code
Dim runAgent As NotesAgent
Dim deleteID As Variant
deleteID = runAgent.Parameterdocid
MsgBox "Input is " & deleteID
'If line below is uncommented it processes the Contract correctly
'deleteID = "9MXCB4"
' Rest of agent process
....
Note that I have also tried runAgent.Target and runAgent.Query
Just tested that and when I pass it a valid NoteID, the agent reads it just fine. I don't think you can pass any other value than a NoteID to the agent this way.
An alternative might be to use the agent.runWithDocumentContext(doc) method and retrieve the document before sending it to the agent.
I believe that the note ID parameter has to actually be a hexidecimal number in string form. It doesn't have to line up with an actual note ID in the database, but it can only contain 0-9 and A-F (with presumably a cap on size).
To add an extra thought on Jesse's and Mark's correct answers: from AJF's question we cannot tell whether the Xpage is bound to an actual NotesDocument object, or whether it is a (temporary) stand-alone page. In that case, of course, agent.runWithDocumentContext won't work.
But unless you have a good reason to perform the rest of your task using a LotusScript coding: why use an agent in the first place? Why not perform the deletion directly using SSJS code? On the Xpages side of the process you most probably will have to start with SSJS code very similar to Mark's example, but then why not go ahead and finish it off with two or three more lines?
In fact I try to avoid calling agents directly from my Xpages driven applications, due to performance issues, and because I don't like my code to be scattered all over the place.
In several mail-in and regular databases we have documents that appear to be "uneditable" - i.e. edit them and the edits appear not to save. In fact what is happening is that both the original and the edited doc are being saved because something has switched on "versioning". Needless to say this confuses users quite a lot.
It appears you can only tell versioning is enabled by looking inside the document properties for a field called $VersionOpt.
The form designs have versioning set to None, so something must be setting $VersionOpt.. but what might do that? Is there anything in a regular 8.5.3 mail client that sets document versioning? Any other ideas how this can happen?
(This link explains the background to Notes versioning - http://gg-lnotes.blogspot.co.uk/2010/04/ways-to-do-version-controllingtracking.html)
Based on the comments, my best guess is that you have one or more users drafting their messages in a Notes application built with a template that supports versioning (possibly the Document Library, but it could be something custom) and using a programmed action that calls #MailSend to submit them to the mail-in database. That's going to take the note intact, add the required fields (e.g., SendTo, etc.) for mailing, and drop it into mail.box, complete with all items that the application template's code had created.
(The only other possibility I can conceive of is that you have some add-on software on one of your servers that is hooking the router and adding the $VersionOpt item based on something it sees in certain messages, but that seems very far-fetched. I've never heard of a mail add-in that would do that.)
In any case, the solution to the problem would be to add an agent to the mail-in databases, triggered by the "Before new mail arrives" event, to remove the item. I.e., FIELD $VersionOpt = #DeleteField;
If a user creates a Notes 'memo' message using 'stationery', the new note can be created with a version control field. If this Notes 'memo' is then mailed in to the mail-in db, it will recieve the message with the version control field '$VersionOpt'. See this answer in an old forum post:
http://www-10.lotus.com/ldd/nd6forum.nsf/ShowMyTopicsAllFlatweb/92a576fbe203b781852573af00630b78?OpenDocument
There are also old technotes referring to this issue.
The solution is to delete the field using a background agent or otherwsie arrange to delete the field.
Is there an event that a plugin can be registered on when a FetchXML (or even SQL) report is run?
RetrieveMultiple and Retrieve do not get fired!
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
// The FetchXML report does not fire the plugin on RetrieveMultiple
if (context.InputParameters["Query"] is FetchExpression)
{
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = factory.CreateOrganizationService(context.UserId);
using (Context linq = new Context(service))
{
// Do the work.
}
}
}
I had the same issue and the solution is the following:
Reports do not trigger plugins. SQL reports bypass CRM completely, and
Fetch reports also bypass the plugin pipeline
More about this here: https://crmbusiness.wordpress.com/2014/11/25/fetchxml-reports-do-not-trigger-retrievemultiple-plugins-in-crm-2011/
I have had similar needs to perform an action when a report is run and the best [supported] way I could find to accomplish this by triggering the report to run via Javascript.
The rough process is this:
In the applicable entity, create ribbon button to launch the report via Javascript. (This post gives a how-to: Trigger a report from a ribbon button)
As part of Javascript function which runs the report, update a field (e.g. "new_ReportRunOn") in the respective record (A standard REST update operation would work here) prior to report run code. The idea here is simply running the report will always cause the "new_ReportRunOn" field to update first.
Have your plugin listen for changes on this field by applying a filter only the "new_ReportRunOn" field. (Alternately, you could just have your logic run in Javascript [as part step 2] instead of updating a field just to trigger a plugin.)
This isn't without drawbacks though:
You would need to "hide" the report in CRM Reports section so it is essentially only accessible via the entity form. It would still be visible in the Reports section if users chose to browse "All Reports" in the reports section. If a "savy" user launched the report this way then it would bypass your Javascript code which fires the plugin.
If the report can be run across multiple records (e.g. the user selects applicable records from the entity grid view) then additional considerations/coding would need to be done. It is possible to handle this case, but based on your question it doesn't appear this would be use case.
I've had process similar to this in place for a while on our 2013 install and it actually works quite well. It isn't ideal but gets the job done.
I have an embedded View within my form which has a bunch of agents in the embedded view.
However when i select rows(documents) in the embedded view and run the agent (eg "Do a multi profile update") it does work but it does not make any changes to the documents selected. Like the prompt in the lotus script agents does work and pop up but no updates are made.
When ran externally from the view it works fine so for some reason it does not work from an embedded view is what i feel.
The agent within the view is an Action which uses a formula language code #Command([RunAgent];"updatePeople")
were the updatePeople is a lotus script agent.
any ideas or suggestions guys?
I think you have to access the selected documents using an action in the embedded view with the LotusScript logic inside the acrtion instead of calling agents. You can find a complete answer here (with full explanation and code sample):
Domino Designer: Access selected rows from embedded view
I am not sure if this IBM TechNote explains exactly the same issue, but it seems very similar:
How to get a handle on selected documents in an embedded view when using LotusScript
Does the ID have the correct ACL settings for the agent to run?
Does the ID have the ability to edit documents?
Does the Agent have the proper save statements in the code?
The example code in the above link is doing a full db search of unprocessed documents. I would suggest using the ViewEntry document collection. This will allow the agent to run faster since the view could be customized.
Another way to go if you are having issues with processing is to set up a flag field that is updated with the save of your document. The flag field could be used in your view selection field to have the documents fall out of the view if that is desired.
Is it possible to call script libraries from another database?
Not directly. About the only thing you can do is have one database inherit from the other, and set only the lotusscript libraries to be inherited. Then you could make changes on the parent, and have them carry over to the child (or children) databases.
You can, however, run agents on another database. Agents in turn can make calls to script libraries in their own databases. Depending on your goals, you may be able to get what you need from that.
From your comments, it seems that you are calling an agent within an agent. Not really the best way to go about it.
You may get the result you want if you merely call the "TextExternalUse" agent directly from the button. This means creating a regular action button rather than a shared action and calling the agent directly.
UPDATE:
I think I know what your problem is. If you're using formula to call the agent in the other database, it won't work, because formula can only call agents in the current database. So if you're using "ToolsRunMacro" it has no parameter for specifying a different database.
Try calling the agent with LotusScript. Here is an example.
I created 2 databases one with an agent called "clickme", which simply displays a "notesUIWorkspace.prompt", and another database with a view that has an action button with the following code that calls the agent from db1
Sub Click(Source As Button)
Dim agnt As notesAgent
Dim db2 As notesDatabase
Set db2 = New notesDatabase("","test2.nsf")
Set agnt = db2.GetAgent("clickme")
Call agnt.Run
End Sub
Can you test something like the above ?