SAP Script Recording and Playback - Cumulative data - vbscript

If I am using the Script Recording and Playback feature on same transaction for instance ME25, multiple times, I am getting cumulative data as part of multiple scripts rather than incremental data.
Explanation :
If I open ME25 details and enter "100-310" as Material and "Ball Bearing" as Short Text and stop the recording, I get the following script, which is expected behavior.
session.findById("wnd[0]/usr/tblSAPMM06BTC_0106/ctxtEBAN-MATNR[3,0]").text = "100-310"
session.findById("wnd[0]/usr/tblSAPMM06BTC_0106/txtEBAN-TXZ01[4,0]").text = "Ball Bearing"
session.findById("wnd[0]/usr/tblSAPMM06BTC_0106/txtEBAN-TXZ01[4,0]").setFocus
session.findById("wnd[0]/usr/tblSAPMM06BTC_0106/txtEBAN-TXZ01[4,0]").caretPosition = 12
After this, I restart the recording and type Qty Requested as "100" and delivery date as "21.04.2021" and stop the recording. I get the following script:
session.findById("wnd[0]").maximize
session.findById("wnd[0]/usr/tblSAPMM06BTC_0106/ctxtEBAN-MATNR[3,0]").text = "100-310"
session.findById("wnd[0]/usr/tblSAPMM06BTC_0106/txtEBAN-TXZ01[4,0]").text = "Ball Bearing"
session.findById("wnd[0]/usr/tblSAPMM06BTC_0106/txtEBAN-MENGE[5,0]").text = "100"
session.findById("wnd[0]/usr/tblSAPMM06BTC_0106/ctxtRM06B-EEIND[8,0]").text = "21.04.2021"
session.findById("wnd[0]/usr/tblSAPMM06BTC_0106/ctxtEBAN-EKGRP[9,0]").setFocus
session.findById("wnd[0]/usr/tblSAPMM06BTC_0106/ctxtEBAN-EKGRP[9,0]").caretPosition = 0
Instead of getting the incremental part that I typed for the second recording instance, I am getting complete script. Is there a way to achieve incremental scripts?

I can reproduce in my SAP GUI 7.60 (whatever screen it is; whatever kind of field it is, I can reproduce even with very simple fields like in a Selection Screen).
It seems that it happens all the time, even if you write your own recorder (a VBS script which mainly uses session.record = True + event handlers). It's due to the fact that SAP GUI sends all the screen events (i.e. the user actions) since the screen was entered, when the user presses a button, a function key, closes a window, or stops the SAP GUI Recorder.
If you write your own recorder, I guess you can save the screen contents when you start the recorder, and when the "change" events occur you may ignore those ones where the new field value has not changed since the recorder started. But that's a lot of work.
I think that it's far more easy to append manually the last lines of the last script to the initial script.

Related

Googlesheet Appscript getSpreadsheetbyname() runs extremely slow [duplicate]

This question already has answers here:
Formulas make SpreadsheetApp work slower in Google Sheets Script
(3 answers)
Random slowness of Google Spreadsheet scripts
(1 answer)
Unreasonably slow apps script when accessing data from a google sheet cell
(2 answers)
Why my Google App Scripts slow down over time?
(2 answers)
Closed 2 months ago.
I have a simple appscript that fetches the first row from a data sheet and populate it into another sheet in the same worksheet. It is usually executed within 1-3 secs.
From last few days I am observing that the script take a long time at getSheetByName() for the first sheet. Once the first sheet is executed the next sheet does not take time. The below logs shows it took more than 90 secs just to execute getSheetByName()  for the first sheet (Calling Dashboard). The second sheet is executed almost instantaneously with the rest of the script. This is happening randomly after several executions and it is affecting our work.
I have tried SpreadsheetApp.flush(); but that does not help when this happens.
I am wondering if there a better way of handling this or I have missed anything? I have gone through several online resources but could not find any guidance on this kind of issue.
I am attaching my script and any help will be very much appreciated!!
enter image description here (Logs snapshot attached)
function fetchNextCallBack() {
Logger.log("Start Function")
const myGooglSheet = SpreadsheetApp.getActiveSpreadsheet();
Logger.log("Active Spreadsheet initiated")
//SpreadsheetApp.flush();
const shUserForm = myGooglSheet.getSheetByName("Calling Dashboard");
Logger.log("Calling Dashboard Initiated")
const datasheet = myGooglSheet.getSheetByName("Call Backs");
Logger.log("Call Backs Initiated")
shUserForm.getRange("C8:C22").clearContent();
shUserForm.getRange("F10:F18").clearContent();
shUserForm.getRange("M4:M6").clearContent();
Logger.log("Dashboard cleared")
const values = datasheet.getRange("A3:N3").getValues();
Logger.log("Call back Data fetched")
shUserForm.getRange("C8").setValue(values[0][5]); // vehicle no
shUserForm.getRange("C10").setValue(values[0][3]); // mobile no
shUserForm.getRange("C12").setValue(values[0][2]); // customer name
shUserForm.getRange("F12").setValue(values[0][4]); // model
shUserForm.getRange("C14").setValue(values[0][1]); // call type
shUserForm.getRange("F14").setValue(values[0][6]); // service type
shUserForm.getRange("F20").setValue(values[0][13]); // cre
shUserForm.getRange("C18").setValue(values[0][11]); // appt date
shUserForm.getRange("F18").setValue(values[0][12]); // appt slot
shUserForm.getRange("F10").setValue("REMINDER CALL");
Logger.log("Call back Data populated in dashboard")
}
the script is expected to be completed within 1-3 secs. However it takes sometime more than 90 secs abruptly. It always get stuck in the following line:
getSheetByName()
The code you show seems fine. Chances are that the spreadsheet is on the heavy side, and that makes accessing the data slow. You can confirm whether that is the case by making a copy of the spreadsheet and deleting everything on every tab, leaving say 25 blank rows on each tab. Then test the code in the blank spreadsheet and see if the same thing happens.
To improve spreadsheet performance, see these optimization tips.

Shiny, RStudio - how to remove objects created by eventReactive functions

I'm in Shiny, RStudio. I'm making an app that processes a user input in several steps, each step taking input from the previous step. At each step the user can set several parameters to process the input.
The workflow looks like this:
Step1: upload input from user
obj_step1 <- eventReactive(input$actionButton1, {#function to upload input from user})
output$step1 <- renderPlot({#function to display obj_step1})
Step2:
obj_step2 <- eventReactive(input$actionbutton2, {#function to process obj_step1, taking several user given parameters from the ui with input$})
output$step2 <- renderPlot({#function to display obj_step3})
Step3:
obj_step3 <- eventReactive(input$actionbutton3, {#function to process obj_step2, taking several user given parameters from the ui with input$})
output$step3 <- renderPlot({#function to display obj_step3})
Step4:
obj_step4 <- eventReactive(input$actionbutton4, {#function to process obj_step3, taking several user given parameters from the ui with input$})
output$step4 <- renderPlot({#function to display obj_step4})
My problem: the user has gone through all the steps and concludes that, to get the best results, he needs to restart the process from step 2, with new parameters. How do I remove all the objects and outputs from the step3-4, to ensure that no mix up takes place?
I've tried remove(obj_step4()), but it does not support this type of objects.
After some days running around in circles, I found the reactiveValues() function from shiny (http://shiny.rstudio.com/articles/). It helps to empty the objects from eventReactive functions when an actionButton of a previous step is pressed. For more details follow the link to the manual pages.

While Recording in Squish using python, how to set the application to sleep for sometime between 2 consecutive activities?

I am working on an application where there are read only screens.
To test whether the data is being fetched on screen load, i want to set some wait time till the screen is ready.
I am using python to record the actions. Is there a way to check the static text on the screen and set the time ?
You can simply use
snooze(time in s).
Example:
snooze(5)
If you want to wait for a certain object, use
waitForObject(":symbolic_name")
Example:
type(waitForObject(":Welcome.Button"), )
The problem is more complicated if your objects are created dynamically. As my app does. In this case, you should create a while function that waits until the object exists. Here, maybe this code helps you:
def whileObjectIsFalse(objectID):
# objectID = be the symbolic name of your object.
counter = 300
objectState = object.exists(objectID)
while objectState == False:
objectState = object.exists(objectID)
snooze(0.1)
counter -= 1
if counter == 0:
return False
snooze(0.2)
In my case, even if I use snooze(), doesn't work all the time, because in some cases i need to wait 5 seconds, in other 8 or just 2. So, presume that your object is not created and tests this for 30 seconds.
If your object is not created until then, then the code exits with False, and you can tests this to stop script execution.
If you're using python, you can use time.sleep() as well

Visual Basic: How to use timer properly

I'm trying to write a simple program that could perform some tasks at specified time.
Here's what I have:
If (TimeOfDay = "06:12:50") Then
MsgBox(TimeOfDay)
End If
If (TimeOfDay = "06:13:58") Then
MsgBox(TimeOfDay)
End If
This code is placed inside Timer1_Tick, I set time interval - 1000 and it works OK, I get TimeOfDay value in MsgBox when current time is equal to my specified time.
But what should I do to make it work dynamically? For example: I want to type TIME value via TextBox and pass it to Timer1_Tick I need to do it as many times as I want so everytime current time matches with my specified hour,minute,second it would work, but I don't know where I have to put my code, because if I place code in while loop and in Time_Ticker1 it runs while loop every second and UI crashes immediately.
Thank you in advance for your help!
Have you considered setting a Windows Scheduled event of MSG to yourself using the AT command line? The operating system timer/scheduler, dialog, storage and queue are already there and the MSG can optionally be dismissed if there is no one to receive it within a set amount of time. Example to send the time at 06:12:15 run the following into a command shell.
AT 06:12:15 msg %USERNAME% It is 06:12:15 am

Ruby/Selenium WebDriver - Pausing test and waiting for user input, i.e. user inputs captcha

I'm using the Selenium WebDriver and Ruby to perform some automation and I ran into a problem of a captcha around step 3 of a 5 step process.
I'm throwing all the automation in a rake script so I'm wondering is there a command to pause or break the script running temporarily until I enter data into the captcha and then continue running on the next page.
To build on seleniumnewbie's answer and assuming that you have access to the console the script is running on:
print "Enter Captcha"
captchaTxt = gets.chomp
yourCaptchaInputWebdriverElement.send_keys captchaTxt
If you just want to pause and enter the captcha in your browser, you can just have it prompt at the console to do that very thing and it'll just sit there.
print "Enter the captcha in your browser"
gets
You could also set the implicit wait to decently long period of time so that Selenium would automatically see the next page and move out. However, this would leave the important Captcha step (for documenting / processes sake) out of your test unless you're pretty anal with your commenting.
Since this is an actively participating test requiring user input I would say that making the tester press "enter" on the console is the way to go.
Since you are writing the test in a script, all you need to do is add a sleep in your test i.e. 'sleep 100' for example.
However, it is bad to add arbitrary sleeps in tests. You can also do something like "Wait for title 'foo'" where 'foo' is the title of the page in Step 4. It need not be title, it can be anything, but you get the idea. Wait for something semantic which indicates that step 3 is done and step 4 is ready to start.
This way, its more targeted wait.
This has been implemented in JAVA, but similar technique.Your solution could be found here

Resources