selectContextMenuItem method returning "The method got an invalid argument" - blueprism

I'm trying to sort a table in SAP in Blue Prism. The code previously worked fine but now I'm getting the following error message when I try to sort the table by context menu item.
The method got an invalid argument
I've tried passing a variety of values to the selectContextMenuItem method: "&SORT_DSC", "&SORT_ASC", "&COL_INV"...all yield the same error.
Dim SAPGuiAuto as Object
Dim SAPApp as Object
Dim SAPCon as Object
Dim session as Object
Dim Table as Object
SAPGuiAuto = Microsoft.VisualBasic.Interaction.GetObject("SAPGUI")
SAPApp = SAPGuiAuto.GetScriptingEngine
SAPCon = SAPApp.Children(0)
session = SAPCon.Children(0)
Table = session.findById("/app/con[0]/ses[0]/wnd[0]/usr/cntlGRID1/shellcont/shell")
Table.setCurrentCell("-1", "LMENGEIST")
Table.selectColumn("LMENGEIST")
Table.contextMenu
Table.selectContextMenuItem("&SORT_DSC")
I expect the column I've selected to be sorted in descending order.
Thanks in advance for any help you can provide.

I know this is an old question but I just started receiving this same error in my C# Console Application (.NET Framework v4.6) after months of the program running autonomously. The only difference is that I was attempting to select a Layout Variant using the filter. Additionally, the application only failed when I ran it as a scheduled task.
First, I did as Sandra suggested and executed the action manually. Whilst doing so, I used SAP's script recording feature to find out if the script used a different argument. I found that the script still used the same argument ("&FILTER"); but I also noticed that the table took a half second to initialize. So I added a few Thread.Sleep() - one after the button click (to give the Variant Select window time to initialize) and one after clicking the context menu (to give the menu time to initialize) - and now, my program now runs as smoothly as it did previously.
//Execute Report
((GuiMainWindow)SAPActive.SAPsession.FindById("wnd[0]")).SendVKey(8);
//Change Layout
((GuiButton)SAPActive.SAPsession.FindById("wnd[0]/tbar[1]/btn[33]")).Press();
Thread.Sleep(2000);
((GuiGridView)SAPActive.SAPsession.FindById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell")).CurrentCellRow = -1;
((GuiGridView)SAPActive.SAPsession.FindById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell")).SelectColumn("VARIANT");
((GuiGridView)SAPActive.SAPsession.FindById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell")).ContextMenu();
Thread.Sleep(2000);
((GuiGridView)SAPActive.SAPsession.FindById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell")).SelectContextMenuItem("&FILTER");

The error message The method got an invalid argument is very specific to SAP GUI Scripting methods, and can be recognized by the missing word has (before got).
It's a general purpose message which is sent when a method of SAP GUI Scripting has an argument which doesn't correspond to an expected value.
In your case, it would probably mean that the item &SORT_DSC does not exist in the context menu. Make sure that if you execute the action manually in the SAP GUI, you see this context menu and the option to sort in descending order.
NB: for information, this message may occur in a variety of other SAP GUI functions, for instance with fileID = application.utils.openfile("file-name.log"), just because the character "-" is not allowed in the file name.

Related

Where is scripted the Dalaran Well teleport (game object)?

When you try to reach the Dalaran Well in Dalaran, you are teleported to the sewers.
It is using this Game object: Doodad_Dalaran_Well_01 (id = 193904 )
Where is it scripted? How?
I've found nothing in the table smart_scripts, and found nothing in the core about this specific id so I'm curious because this type of teleport is really better than clicking on a game object
This gameobject is a unique case because it works like instance teleports do. If you check the gameobject_template table, you will see that it has several Data columns that have diferent values based on the type of the gameobject.
The gameobject you are refering too is the Well It self but the portal gameobject inside the well gives the player a dummy spell to tell the core that the player has been teleported (spell ID 61652).
For the specific case of the dalaran well, it's type is 30 which means, as the documentation says, GAMEOBJECT_TYPE_AURAGENERATOR. As soon as the player is in range, a dummy aura is cast on him to notify the core that this areatrigger has been activated (You could do stuff when player gets hit by the dummy spell).
The trick here is a bunny, but not the bunny itself since it is there mostly to determine an areatrigger. If you use command .go gobject 61148 you can check him out, he's inside the well.
Areatriggers are a DBC object that are actually present on our database on world.areatrigger. You can check the columns here. When the player enters the Radius box specified on the areatrigger, another thing happens in the core which is world.areatrigger_teleport.
If you run the following query you will be able to check the position where the trigger will teleport the player to.
SELECT * FROM areatrigger_teleport WHERE `Name` LIKE '%Dalaran Well teleporter%';

This row was already applied and cannot be modified

When i run my code in the test environment to test my new code about kudu insert,it reports to me:
This row was already applied and cannot be modified.
I have already tried to debug my code and to see what is the problem in my code , but it is useless
if((map.get(list.get(i))) instanceof Double){
row.addDouble(list.get(i), (Double) map.get(list.get(i)));
//System.out.println("Double type insert succeed : " + list.get(i) + " : " + map.get(list.get(i)));
continue;
}
I want to know what's wrong in my code because in my previous code i can run correct but know it cannot
In the source code ,The class was that PartialRow has a private propertiy:frozen, It's default value was false,but in my code,when i debug in it,i found that value was true,I think this is the reason that cause the program reports to my : This row was alredy applied and cannot be modified ! asking for help .please
Without full stacktrace and the rest of code I can only guess why this is happening.
My guess is because the Insert object on which this row object is created has already inserted to Kudu (using KuduSession.apply) and then you tried to update it using row.addDouble.
If you are unsure about why please see this example of how to insert into Kudu.
KuduSession.apply method is invoked on Insert object on which PartialRow object is created, this will insert the data from all the PartialRow objects created from the Insert object. This can be done only once on one Insert object. After that you create a new Insert object using KuduTable.newInsert()
In your case you should probably create new object of Insert using KuduTable.newInsert() and create a row object on this.

Maximo automatisation script to change statut of workorder

I have created a non-persistent attribute in my WoActivity table named VDS_COMPLETE. it is a bool that get changed by a checkbox in one of my application.
I am trying to make a automatisation script in Python to change the status of every task a work order that have been check when I save the WorkOrder.
I don't know why it isn't working but I'm pretty sure I'm close to the answer...
Do you have an idea why it isn't working? I know that I have code in comments, I have done a few experimentations...
from psdi.mbo import MboConstants
from psdi.server import MXServer
mxServer = MXServer.getMXServer()
userInfo = mxServer.getUserInfo(user)
mboSet = mxServer.getMboSet("WORKORDER")
#where1 = "wonum = :wonum"
#mboSet .setWhere(where1)
#mboSet.reset()
workorderSet = mboSet.getMbo(0).getMboSet("WOACTIVITY", "STATUS NOT IN ('FERME' , 'ANNULE' , 'COMPLETE' , 'ATTDOC')")
#where2 = "STATUS NOT IN ('FERME' , 'ANNULE' , 'COMPLETE' , 'ATTDOC')"
#workorderSet.setWhere(where2)
if workorderSet.count() > 0:
for x in range(0,workorderSet.count()):
if workorderSet.getString("VDS_COMPLETE") == 1:
workorder = workorderSet.getMbo(x)
workorder.changeStatus("COMPLETE",MXServer.getMXServer().getDate(), u"Script d'automatisation", MboConstants.NOACCESSCHECK)
workorderSet.save()
workorderSet.close()
It looks like your two biggest mistakes here are 1. trying to get your boolean field (VDS_COMPLETE) off the set (meaning off of the collection of records, like the whole table) instead of off of the MBO (meaning an actual record, one entry in the table) and 2. getting your set of data fresh from the database (via that MXServer call) which means using the previously saved data instead of getting your data set from the screen where the pending changes have actually been made (and remember that non-persistent fields do not get saved to the database).
There are some other problems with this script too, like your use of "count()" in your for loop (or even more than once at all) which is an expensive operation, and the way you are currently (though this may be a result of your debugging) not filtering the work order set before grabbing the first work order (meaning you get a random work order from the table) and then doing a dynamic relationship off of that record (instead of using a normal relationship or skipping the relationship altogether and using just a "where" clause), even though that relationship likely already exists.
Here is a Stack Overflow describing in more detail about relationships and "where" clauses in Maximo: Describe relationship in maximo 7.5
This question also has some more information about getting data from the screen versus new from the database: Adding a new row to another table using java in Maximo

bloomberg beqs response elements

I'm using excel vba to send beqsrequest and handle response. The bloomberg developer's guide says BeqsResponse message has responseError and securityData element. When handling the response, I used
Dim securities As blpapicomLib2.Element
Set securities = message.GetElement("securityData")
I got run-time error 5 - invalid procedure call or argument. However it worked when I put
Dim securi As blpapicomLib2.Element
Set securi = message.GetElement("responseError")
What's wrong with "securityData" ? And is there a way to get all the elements from message using blpapicomLib2 ?
Any advice would be appreciated.
The top level securityData is an array of securityData elements:
So you need to do something similar to a ReferenceDataResponse, for which you can find several examples in the doc, such as in "4.4 - Response Details".

Extending WSS3 task lists to support recurring reminders

WSS 3.0 will let me send an email to a group when a new task is added to a task list. What I would like to do is to run a weekly task that sends out reminders of tasks due within certain periods, i.e. 2 days, 7 days, 14 days etc. I thought the simplest way would be to build a little C# app that sits on the WS2K3 box and queries the WSS database. Any ideas on which tables I should be checking? More generally is there an overall schema for the WSS3 database system?
If anyone is aware of an existing solution with code please let me know.
Thx++
Jerry
My suggestions:
don't create a console app, create a class that inherits from SPJobDefinition.
set SPJobLockType.Job to this timer, this will grant that the job is executed only once in the whole farm, even if you are running multiple front-end servers
in the, timer job, open the SPSite, SPWeb objects you need, then find the SPList\
Using SPQuery filter out only the items you need - I believe, you will have to filter out the ones where Status!=Complete
Loop through the results collection (which will be of type SPListItemCollection, apply your rules, checking the DueDate and Datetime.Now, send the e-mails
Since a task is simply a SPListItem, it has a Properties property, which is actually a property bag - you can add whatever properties you need. So, add a property My_LastSentReminderDate. Use this property to check if you are not sending too much of "corporate spam" :-)
To install your SPJobDefinition in a SharePoint farm, you can use a PowerShell script. I can give you examples, if needed.
Don't forget to Threading.Thread.CurrentThread.CurrentCulture = Your_SPWeb_Instance.Locale, otherwise date comparisons may not work if the web has a different locale!
EDIT: This is how a typical reminder looks like in my applications:
Public Class TypicalTimer
Inherits SPJobDefinition
Public Sub New(ByVal spJobName As String, ByVal opApplication As SPWebApplication)
'this way we can explicitly specify we need to lock the JOB
MyBase.New(spJobName, opApplication, Nothing, SPJobLockType.Job)
End Sub
Public Overrides Sub Execute(ByVal opGuid As System.Guid)
'whatever functionality is there in the base class...
MyBase.Execute(Guid.Empty)
Try
Using oSite As SPSite = New SPSite("http://yourserver/sites/yoursite/subsite")
Using oWeb As SPWeb = oSite.OpenWeb()
Threading.Thread.CurrentThread.CurrentCulture = oWeb.Locale
'find the task list and read the "suspects"
Dim oTasks As SPList = oWeb.Lists("YourTaskListTitle")
Dim oQuery As New SPQuery()
oQuery.Query = "<Where><Neq><FieldRef Name='Status'/>" & _
"<Value Type='Choice'>Complete</Value></Neq></Where>"
Dim oUndoneTasks As SPListItemCollection = oTasks.GetItems(oQuery)
'extra filtering of the suspects.
'this can also be done in the query, but I don't know your rules
For Each oUndoneTask As SPListItem In oUndoneTasks
If oUndoneTask(SPBuiltInFieldId.TaskDueDate) IsNot Nothing AndAlso _
CDate(oUndoneTask(SPBuiltInFieldId.TaskDueDate)) < Now().Date Then
' this is where you send the mail
End If
Next
End Using
End Using
Catch ex As Exception
MyErrorHelper.LogMessage(ex)
End Try
End Sub
End Class
To register a timer job, I typically use this kind of a script:
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Administration")
[System.Reflection.Assembly]::LoadWithPartialName("Your.Assembly.Name.Here")
$spsite= [Microsoft.SharePoint.SPSite]("http://yourserver/sites/yoursite/subsite")
$params = [System.String]("This text shows up in your timer job list (in Central Admin)", $spsite.WebApplication
$newTaskLoggerJob = new-object -type Your.Namespace.TypicalTimer -argumentList $params
$schedule = new-object Microsoft.SharePoint.SPDailySchedule
$schedule.BeginHour = 8
$schedule.BeginMinute = 0
$schedule.BeginSecond = 0
$schedule.EndHour = 8
$schedule.EndMinute = 59
$schedule.EndSecond = 59
$newTaskLoggerJob.Schedule = $schedule
$newTaskLoggerJob.Update()
Any time you need something in sharepoint that is executed periodically, 99 times out of a 100 you'll need to build a TimerJob. These are scheduled tasks that run inside SharePoint and you can create your own, then using a feature + featurereceiver to actually "install" the timoerjob (definition) and assign it a schedule.
For more info: see Andrew Connell's article on TimerJobs.
P.S. Never query /update the databases related to SharePoint directly! This will make you "unsupported", i.e. if anything happens microsoft will charge (a lot of) money to come and fix it, instead of being able to ask for regular support. (if you are say an MSDN subscriber you get up to 4 free support calls a year).
Don't bother trying to go directly to the database. You will have a very hard time because it's undocumented, unsupported, and not recommended. SharePoint does in fact have a full featured object model though.
If you reference Microsoft.SharePoint.dll (located in the Global Assembly Cache of a machine with SharePoint installed on it) you can access the data that way. The objects you'll want to start with are SPSite, SPWeb, SPList, SPQuery, and SPListItem. All of which you can find very easily on http://msdn.microsoft.com in a search.
Another less-flexible but code-free possibility you could try is creating several different views that include upcoming tasks then via the GUI set up an alert for when items are added to that view.

Resources