Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
stefan_schnell
Active Contributor
The programming language Python offers many possibilities. Also it supports with py32win ActiveX automation, and therefore SAP GUI Scripting. The following example shows, how easy it is to take the recorded VBScript code and to use it inside Python.

In the comment lines you see the recorded VBScript code as a direct comparison. Here an example which opens TAC SE16, enters table TADIR and execute the TAC:
#-Begin-----------------------------------------------------------------

#-Includes--------------------------------------------------------------
import sys, win32com.client

#-Sub Main--------------------------------------------------------------
def Main():

try:

SapGuiAuto = win32com.client.GetObject("SAPGUI")
if not type(SapGuiAuto) == win32com.client.CDispatch:
return

application = SapGuiAuto.GetScriptingEngine
if not type(application) == win32com.client.CDispatch:
SapGuiAuto = None
return

connection = application.Children(0)
if not type(connection) == win32com.client.CDispatch:
application = None
SapGuiAuto = None
return

session = connection.Children(1)
if not type(session) == win32com.client.CDispatch:
connection = None
application = None
SapGuiAuto = None
return

#session.findById("wnd[0]").resizeWorkingPane 173, 36, 0
session.findById("wnd[0]").resizeWorkingPane(173, 36, 0)
#session.findById("wnd[0]/tbar[0]/okcd").text = "/nse16"
session.findById("wnd[0]/tbar[0]/okcd").text = "/nse16"
#session.findById("wnd[0]").sendVKey 0
session.findById("wnd[0]").sendVKey(0)
#session.findById("wnd[0]/usr/ctxtDATABROWSE-TABLENAME").text = "TADIR"
session.findById("wnd[0]/usr/ctxtDATABROWSE-TABLENAME").text = "TADIR"
#session.findById("wnd[0]").sendVKey 0
session.findById("wnd[0]").sendVKey(0)
#session.findById("wnd[0]/tbar[1]/btn[8]").press
session.findById("wnd[0]/tbar[1]/btn[8]").press()

except:
print(sys.exc_info()[0])

finally:
session = None
connection = None
application = None
SapGuiAuto = None

#-Main------------------------------------------------------------------
if __name__ == "__main__":
Main()

#-End-------------------------------------------------------------------

 

And after all we see that it is very easy to use SAP GUI Scripting inside Python. The recorded VBScript code can use almost always unchanged, sometimes it is necessary to set some brackets.

As IDE I use VS Code with Python extension, here a look at it:

43 Comments
former_member492038
Participant
Hi Stefan,

Awesome to see some Python pop up here on the SAP community! Just some suggestions - if you wanted to follow the PEP 8 convention you should keep function names lowercased. You could also simplify your code a bit if you just used "Duck Typing" on the variables you declare, rather than checking of types.

Great stuff though - keep it coming!
stefan_schnell
Active Contributor
0 Kudos
Hello William,

thank you very much for your reply and for your interesting suggestions. As you can see I am newbie at Python. I build this bridge in the context of test automation, here in combination with the Robot Framework.

Best regards
Stefan
former_member492038
Participant

I’m not familiar with the Robot Framework, but you may find some value in looking at Python’s built-in unittest module which can help consolidate a lot of setup and teardown actions across your test cases. To get you started, I’ve refactored your code above to fit that framework.

Note that this is just taking your code as is. I’m not too familiar with the COM SDK but I think you might need to find an explicit close method to call for your session object rather than just setting it to None as you do above. Also, there could be some opportunity to simplify a lot of your “findById” calls if you create the window object as a variable, and have your calls work relative to that rather than always starting back with the session object as its root.

I’m on a Mac and can’t test any of this, but feel free to ping me back if you have any issues or questions ?

import unittest
import win32com.client

class SapGuiTests(unittest.TestCase):

@classmethod
def setUpClass(cls):
'''This runs once when the class is instantiated'''
cls.gui = win32com.client.CDispatch
cls.app = gui.GetScriptingEngine
cls.conn = app.Children(0)
cls.sess = app.Children(1)
cls.findById("wnd[0]").resizeWorkingPane(173, 36, 0)

@classmethod
def tearDownClass(cls):
'''This runs once when the class is being destroyed'''
# Close out any sessions or applications here
...

def setUp(self):
'''This runs before each test case'''
# Start back at the home screen
self.sess.findById("wnd[0]/tbar[0]/okcd").text = "/n"
self.sess.findById("wnd[0]").sendVKey(0)

def tearDown(self):
'''This runs after each test case'''
...

def test_tadir(self):
'''Test that we can access the TADIR table in SE16'''
self.sess.findById("wnd[0]/tbar[0]/okcd").text = "/nse16"
self.sess.findById("wnd[0]").sendVKey(0)
self.sess.findById("wnd[0]/usr/ctxtDATABROWSE-TABLENAME").text = "TADIR"
self.sess.findById("wnd[0]").sendVKey(0)
self.sess.findById("wnd[0]/tbar[1]/btn[8]").press()


if __name__=='__main__':
unittest.main()
Former Member
0 Kudos
I have the below python script working to open SAP and then it also runs a t-code after opening.

For some reason I am able to execute a t-code but I'm not able to access the elements by Id using the FindById(). Any solutions? I think the problem is with the window ID or the session ID.

import win32com.client
from win32com import *
from win32api import *
from win32com.client import *

SAPguiAPP = win32com.client.Dispatch("Sapgui.ScriptingCtrl.1")
Connection = SAPguiAPP.OpenConnection("System_Name_QA",1)
Session = SAPguiAPP.ActiveSession
Session.SendCommand(Command="/nSE16")
Former Member
0 Kudos
Interestingly, this format does not cause any error but it does not act upon the Id and transfer a value to the screen either.

Session.SendCommand("Session.FindById('wnd[0]/usr/ctxtRP50G-PERNR').text='9999999'")
stefan_schnell
Active Contributor
0 Kudos
Hello Mason,

Session.SendCommand("/nse16") sets in the command field combo box the TAC SE16 and execute it. Your examples should not work in my opinion.

If I try this:
session.sendcommand(Command = "/nse16")

I get the result that the transaction 0 doesn't exists.

And if I try this:
Session.SendCommand(“Session.FindById(‘wnd[0]/usr/ctxtRP50G-PERNR’).text=’9999999′”)

I get an error message.

Best regards
Stefan

 
Former Member
0 Kudos
Hi Stefan,

I have included a more complete code example and indicated the line where it is failing.

I would like to create the python equivalent of the VBA code below. The problem seems to be the reference to translate the vba Dim SAPguiAPP As SAPFEWSELib.GuiApplication.

How can I call SAPFEWSELib.GuiApplication from the ocx file in python? There are python ctype method to call dlls.

#Start of python code

import win32com.client
from win32com import *
from win32api import *
from win32com.client import *

SAPguiAPP = win32com.client.Dispatch("Sapgui.ScriptingCtrl.1")
Connection = SAPguiAPP.OpenConnection("75 - NSP - Production Simple SAP Access",1)
session1 = SAPguiAPP.ActiveSession
print(help(session1)) # proves the FindByID method is now available in the print out
session1.StartTransaction("PA20") # This line works perfectly
session1.FindById("wnd[0]/usr/ctxtRP50G-PERNR").text = '999999' # This line fails without error

#End of python code

 

"""

''Start of vba example"

Sub Log_Sap_VBA()
'''references C:\Program Files (x86)\SAP\FrontEnd\SAPgui\sapfewse.ocx

Dim SAPguiAPP As SAPFEWSELib.GuiApplication
Dim Connection As SAPFEWSELib.GuiConnection
Dim Session As SAPFEWSELib.GuiSession
Dim info As SAPFEWSELib.GuiSessionInfo

If SAPguiAPP Is Nothing Then
Set SAPguiAPP = CreateObject("Sapgui.ScriptingCtrl.1")
End If
If Connection Is Nothing Then
Set Connection = SAPguiAPP.OpenConnection("75 - NSP - Production Simple SAP Access",1)
End If
If Session Is Nothing Then
Set Session = Connection.Children(0)
MsgBox x
End If

End Sub

''End of VBA example

"""

 
stefan_schnell
Active Contributor
0 Kudos
Hello Mason,

in my case is in TAC PA20 the GuiCTextField RP50G-PERNR wrapped by a GuiSimpleContainer. If you don't use the complete path to your object the access fails, as in your case.
session.findById("wnd[0]/usr/subSUBSCR_PERNR:SAPMP50A:0110/ctxtRP50G-PERNR").text = "999999"

Please check your path and let us know your result.



Cheers
Stefan

 

 
Former Member
0 Kudos
Hi Stefan,

On my SAP, it does not appear to be a wrapped element. I have still not been able to get it to transfer a value to the screen. I included my tracking image below.

import win32com.client
from win32com import *
from win32api import *
from win32com.client import *

SAPguiAPP = win32com.client.Dispatch("Sapgui.ScriptingCtrl.1")
Connection = SAPguiAPP.OpenConnection(“75 – NSP – Production Simple SAP Access”,1)
Session1 = SAPguiAPP.ActiveSession
Session1.StartTransaction("PA20") # This works
Session1 = SAPguiAPP.ActiveSession
Session1.FindById("wnd[0]/usr/lblRP50G-PERNR").text = '999999' # This does not work

 



 
stefan_schnell
Active Contributor
0 Kudos
Hello Mason,

you open a new connection so you can use this to solve your problem:
import win32com.client
from win32com import *
from win32api import *
from win32com.client import *

SAPguiAPP = win32com.client.Dispatch(“Sapgui.ScriptingCtrl.1”)
Connection = SAPguiAPP.OpenConnection(“75 – NSP – Production Simple SAP Access”,1)
Session1 = Connection.Children(0)
Session1.StartTransaction(“PA20”)
Session1.FindById(“wnd[0]/usr/lblRP50G-PERNR”).text = ‘999999’

Cheers
Stefan
Former Member
Hi Stefan,

 

The last script that you posted works perfectly now! I discovered the issue is that it will not work in python 3.6 but it does work in 32-bit python 2.7 with the 32-bit pywin32 package!

The following are the collection of errors that I found in python 3.6 with pywin32 for 3.6.

#Session1 = SAPguiAPP.ActiveSession # Works for the Start Transaction but does not work for FindById
Session1 = Connection.Children(0) # TypeError: 'GuiComponentCollection' object is not callable
#Session1 = Connection.Children(Index=0) # TypeError: 'GuiComponentCollection' object is not callable
#Session1 = Connection.Children # object has no attribute 'StartTransaction'
#Session1 = Connection.Children.Item(0) #object has no attribute 'StartTransaction'
#Session1 = Connection.Children[0] # TypeError: 'GuiComponentCollection' object does not support indexing
#Session1 = Connection.Children['ses[0]'] # 'GuiComponentCollection' object is not subscriptable
#Session1 = SAPguiAPP.ActiveSession.Children(0) #TypeError: 'GuiComponentCollection' object is not callable
#Session1 = Connection.Children() # TypeError: 'GuiComponentCollection' object is not callable
#Session1 = Connection.Children "0" # Invalid Syntax
#Session1 = Connection.Children 0 # Invalid Syntax
#Session1 = Connection.Children # Sets Session1 = to <win32com.gen_py.None.GuiComponentCollection> does not work
#print(len(Dispatch(SAPguiAPP.Children)))
#Session1 = len(Dispatch(SAPguiAPP.Children))
#TypeError: 'GuiComponentCollection' object is not iterable
#TypeError: 'GuiComponentCollection' object cannot be interpreted as an integer

If you find a 3.6 solution please let me know. Otherwise, I'm happy it works in 2.7!

Regards,

Mason
Former Member
I created a cool and re-usable gui connection class example using a Tkinter window to run the script.

Many buttons could be added to the window re-using the same connection class for each sap gui scripting function.

# import libraries
import win32com.client
from win32com import *
from win32api import *
from win32com.client import *
import win32com.client as win32
import win32gui, win32con
import pyautogui, time, webbrowser, datetime
from Tkinter import *

# create a reuseable connection class
class cls_SAP_Gui_Scripting:
def __init__(self, api, conn):
self.SAPguiAPP = win32com.client.Dispatch(api)
self.Connection = self.SAPguiAPP.OpenConnection(conn,1)
self.Session = self.Connection.Children(0)

# Create Different SAP Script Functions
def run_my_sap_script():
# instantiate the class inside the function
MySapGui = cls_SAP_Gui_Scripting("Sapgui.ScriptingCtrl.1", "75 – NSP – Production Simple SAP Access")
MySapGui.Session.StartTransaction("PA20")
MySapGui.Session.FindById("wnd[0]/usr/ctxtRP50G-PERNR").Text = '9999999'
# Loop through excel workbook here with excel.application

# Create a main window with Tkinter and add button to run SAP Script Function
def main():
window = Tk()
window.title("SAP Script Automation")
window.wm_state('zoomed')
window.configure(bg='red')
b1 = Button(window,text="Run SAP GUI Script",font=("Helvetica", 16),command=run_my_sap_script)
b1.grid(row=0, column=0)
window.mainloop()

# Call Main
main()
stefan_schnell
Active Contributor
Hello Mason,

that sounds great.

Cheers
Stefan
Former Member
That was a very good snippet Stefan. Were you able to send any other keys other than Enter?

Like sendVkey(2) which is vkey for F2
stefan_schnell
Active Contributor
0 Kudos
Hello Vijay,

thanks for your reply.

Sure is that possible, take a look at the SAP GUI Scripting help:



In the table GUI_FKEY you can find all supported virtual key codes.



Best regards
Stefan
Former Member
0 Kudos
Hi Stefan,

I used VBA to write a tool to operate SAP several month ago. This time I want to change it to C++, but I am a bit confused. Do you have any good suggests about this situation? Thank you!

Best regards

Tiny
stefan_schnell
Active Contributor
0 Kudos
Hello Tiny,

I assume that you use SAP GUI Scripting too. In my opinion it should be not a problem to use SAP GUI Scripting with C++, you can find an explanation to use COM with C++ here
https://msdn.microsoft.com/en-us/library/windows/desktop/ff485848(v=vs.85).aspx

Best regards
Stefan
raghavan7
Explorer
0 Kudos
Hi Stefan,

 

I have a question related to SAP GUI screens which have dynamic screen names and changes often for which FindByID is not working.

 

Currently I'm trying to use FindByName to handle this, but unable to fetch the text from the field, can you please help ?

 
PONbr = cls.session.FindById(
"wnd[0]/usr").FindByName("txtMEPO_TOPLINE-EBELN","GuiCTextField").text


Error I'm getting as below -

Traceback (most recent call last):
File "C:\Users\rrama3\PycharmProjects\pysaf_core\pysaf\tests\testBusinessFlows\crossAppTesting\coupaPOValidateInSAP.py", line 47, in get_display_validate_PO
"wnd[0]/usr").FindByName("txtMEPO_TOPLINE-EBELN","GuiCTextField").text
AttributeError: 'NoneType' object has no attribute 'Text'


How can i interact with FindByName fields to get text, I'm writing my scripts in Python


stefan_schnell
Active Contributor

Hello Raghavendran,

I don’t know what your problem is, I tried it and it works in my case without any problems.

Cheers
Stefan

#-Begin-----------------------------------------------------------------

#-Includes--------------------------------------------------------------
import sys, win32com.client

#-SUB Main--------------------------------------------------------------
def Main():

try:

SapGuiAuto = win32com.client.GetObject("SAPGUI")
if not type(SapGuiAuto) == win32com.client.CDispatch:
return

application = SapGuiAuto.GetScriptingEngine
if not type(application) == win32com.client.CDispatch:
SapGuiAuto = None
return

connection = application.Children(0)
if not type(connection) == win32com.client.CDispatch:
application = None
SapGuiAuto = None
return

session = connection.Children(0)
if not type(session) == win32com.client.CDispatch:
connection = None
application = None
SapGuiAuto = None
return

UserArea = session.findById("wnd[0]/usr")
Control = UserArea.findByName("shellcont", "GuiContainerShell")
print(Control.Text)

print(session.findById("wnd[0]/usr").findByName("shellcont", "GuiContainerShell").Text)

except:
print(sys.exc_info()[0])

finally:
session = None
connection = None
application = None
SapGuiAuto = None

#-Main------------------------------------------------------------------
Main()

#-End-------------------------------------------------------------------
Former Member
0 Kudos

how can we achieve a similar result in MAC? is this possible at all?

stefan_schnell
Active Contributor
0 Kudos
Hello David,

I am afraid that is not possible, but I don't know it exactly. SAP GUI Scripting bases on COM and as far as I know it works only on Windows environments.

Cheers
Stefan
raghavan7
Explorer
0 Kudos
Hi Stefan,

 

Thanks for your quick response , i was able to figure out the problem in my code using your example and few others from my search.

 

My incorrect - Code below -
PONbr = cls.session.FindById(
"wnd[0]/usr").FindByName("txtMEPO_TOPLINE-EBELN","GuiCTextField").text


Small change makes it work - (which was caused due incorrect Name)

Working Code - (after removing 'txt' from name)
PONbr = cls.session.FindById( "wnd[0]/usr").FindByName("MEPO_TOPLINE-EBELN","GuiCTextField").text


Thanks,

Raghav
raghavan7
Explorer
0 Kudos
Hi Stefan,

 

Im trying to get the SAP GUI session and print it so that i can know whats the connection currently running, this is currently supported with SAP Scripting Tracker tool provided by you and i able to see the current SAP GUI active.

E.g.



 

I would like to get the con[4] and print this using python ? Is there a way to achieve this.

Expectation is to get the con[4] value and route my SAP python scripts to specific connection of SAP GUI
stefan_schnell
Active Contributor
0 Kudos
Hello Raghavendran,

you can find many examples how to loop over your sessions here:

The same way you can use to detect your correct connection and session to use it with your Python script.

Cheers
Stefan
Former Member
Stefan, thanks a lot for sharing this knowledge!

We're building in my company a Python app to interact with SAP GUI.

The script you shared at the beginning works fine, but it requires SAP GUI to be already opened. We would like to automate everything from the beginning, including opening SAP GUI, selecting the desired connection, login and so on. However, everytime we try to do that, the SAP GUI interface we get is very different than when we open it manually. Furthermore, it seems the list of connections is not even the same.

The python constructor is this
class SapGuiScripting:

def __init__(self, api):
# self.sap_app = win32com.client.Dispatch(api)
# self.sap_connection = self.sap_app.OpenConnection(conn,1)
# self.sap_session = self.sap_connection.Children(0)

sap_gui= SapGuiScripting("Sapgui.ScriptingCtrl.1","the name of our connection")

The script works, and this is shown:



but the GUI is different, this is how it looks if we opened it manually:



And this is the UI when called with Python



Any thoughts on this? Thanks!
stefan_schnell
Active Contributor
0 Kudos

Hello David,

your observations are very interesting.

To the different appearance of the UI: sanchezd asked the same question here and I assume that Sapgui.ScriptingCtrl works independently from and without the SAP Logon.

But the requester speaks another language. Disable the notifications and you should not see it again. But it seems that Sapgui.ScriptingCtrl considered this settings but it doesn’t considered the selected theme. Also look at RZ11 with the parameter sapgui/user_scripting_force_notification, it should set to FALSE.

Best regards
Stefan

former_member612747
Discoverer
0 Kudos
How can I connect the SAP GUI with SapGuiLibrary in the Robot Framework?
stefan_schnell
Active Contributor
0 Kudos
Hello Francisco,

you can very easy use Python code in the Robot Framework via test libraries. On this way you can use this approach also, I assume.

Best regards
Stefan
faranak88
Discoverer
Hi Stefan,

I have installed py32win on my system but when I run your code example on top I am receiving this error :
<class 'pywintypes.com_error'>

I searched on google about this error I was wondering is this error because of unmatching between the python version and system version?
my python version is 3.7 (32bit) and my system is 64bit so I installed this package pywin32-224.win32-py3.7.exe.
I didn't get any error during installation.

Thank you.

Best regards,

Faranak
former_member633542
Discoverer
0 Kudos

Hi Faranak,

 

Have you solve the problem with python 3.7. I am also facing error when trying to

dispatch(”Sapgui.ScriptingCtrl.1")
former_member644462
Discoverer
0 Kudos
Hi Stefan,  It’s a little hard to tell if this is still an active blog, given the dates of the posts.

I posted this question below to your Scripting Tracker thread, but this seems to be a more up-to-date blog.

But I have successfully used scripting tracker to run and play back AutoIT scripts (from scripting Tracker only);  What I am having difficulty with is running these scripts from AutoIT, Powershell, or another tool, because the $session variable value is not included or set in the script.  I am particularly needing the Python scripts to work, as I want to integrate with Robot Framework.  If anyone has solved this, and can post script or links, I would appreciate it.

 

Many Thanks!





mynynachau
Community Advocate
Community Advocate
0 Kudos
Hi Steve,

please post your question here to receive help by community members: https://answers.sap.com/questions/ask.html

Thanks.

Mynyna (SAP Community moderator)
former_member729110
Discoverer
0 Kudos
Hi Stefan,

I am newbie to Python and Robot Framwork . I am currently in the process of automating some of the SAP business flows . By using only Robot Framework via SAPLibrary I was able to automate login to SAP and executing a custom program using SE38 and Validating the IDocs created in  Tcode WE02 . It was in this step I came across SAP GUIShell with tree & grid which I was unable to automate because the SAP GUI scripting tracker.exe does not capture much details like going thru each node of tree or finding the correct row in the grid.

Do I need to create the logic using python and how to I start ? I am using VS Code editor for coding.

Regards,

Sobin

 
former_member743280
Discoverer
0 Kudos
Hi,

I have the same issue as reported by


faranak88



 

<class 'pywintypes.com_error'>

What should I do?

Thanks
former_member795665
Discoverer
0 Kudos
Hi William/Stefan,

I tried to run your code but couldn't make it work. Would you be able to extend your support in fixing this? Please find the below error details(NameError: name 'gui' is not defined) for your reference.

Post that, I made some tweaks in the existing code to make it work but I'm still getting the control id error. I'm using Spyder IDE.

Best

Rohit

======================================================================
ERROR: setUpClass (__main__.SapGuiTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\O59380\lowHangingAutomation\dataTransformation.py", line 13, in setUpClass
cls.sess.findById("wnd[0]").resizeWorkingPane(173, 36, 0)
File "<COMObject <unknown>>", line 2, in findById
pywintypes.com_error: (-2147352567, 'Exception occurred.', (619, 'saplogon', 'The control could not be found by id.', 'C:\\Program Files (x86)\\SAP\\FrontEnd\\SAPgui\\saplogon.HLP', 393215, 0), None)

----------------------------------------------------------------------
Ran 0 tests in 0.017s

FAILED (errors=1)

 

======================================================================
ERROR: setUpClass (__main__.SapGuiTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\O59380\lowHangingAutomation\dataTransformation.py", line 10, in setUpClass
cls.app = gui.GetScriptingEngine
NameError: name 'gui' is not defined

----------------------------------------------------------------------
Ran 0 tests in 0.004s

FAILED (errors=1)

 

UPDATED CODE

import unittest
import win32com.client

class SapGuiTests(unittest.TestCase):

@classmethod
def setUpClass(cls):
'''This runs once when the class is instantiated'''
cls.gui = win32com.client.GetObject("SAPGUI")
cls.app = cls.gui.GetScriptingEngine
cls.conn = cls.app.Children(0)
cls.sess = cls.app.Children(0)
cls.sess.findById("wnd[0]").resizeWorkingPane(173, 36, 0)

@classmethod
def tearDownClass(cls):
'''This runs once when the class is being destroyed'''
# Close out any sessions or applications here
...

def setUp(self):
'''This runs before each test case'''
# Start back at the home screen
self.sess.findById("wnd[0]/tbar[0]/okcd").text = "/n"
self.sess.findById("wnd[0]").sendVKey(0)

def tearDown(self):
'''This runs after each test case'''
...

def test_tadir(self):
'''Test that we can access the TADIR table in SE16'''
self.sess.findById("wnd[0]/tbar[0]/okcd").text = "/nse16"
self.sess.findById("wnd[0]").sendVKey(0)
self.sess.findById("wnd[0]/usr/ctxtDATABROWSE-TABLENAME").text = "TADIR"
self.sess.findById("wnd[0]").sendVKey(0)
self.sess.findById("wnd[0]/tbar[1]/btn[8]").press()

if __name__=='__main__':
unittest.main()
former_member795665
Discoverer
0 Kudos
William/Stefen - Never mind, I've resolved the issue. Thanks!

Updated Code

import unittest
import win32com.client

class SapGuiTests(unittest.TestCase):

@classmethod
def setUpClass(cls):
'''This runs once when the class is instantiated'''
cls.SapGuiAuto = win32com.client.GetObject("SAPGUI")
cls.application = cls.SapGuiAuto.GetScriptingEngine
cls.connection = cls.application.Children(0)
cls.session = cls.connection.Children(0)
cls.session.findById("wnd[0]").resizeWorkingPane(173, 36, 0)

@classmethod
def tearDownClass(cls):
'''This runs once when the class is being destroyed'''
# Close out any sessions or applications here
...

def setUp(self):
'''This runs before each test case'''
# Start back at the home screen
self.session.findById("wnd[0]/tbar[0]/okcd").text = "/n"
self.session.findById("wnd[0]").sendVKey(0)

def tearDown(self):
'''This runs after each test case'''
...

def test_tadir(self):
'''Test that we can access the TADIR table in SE16'''
self.session.findById("wnd[0]/tbar[0]/okcd").text = "/nymem62"
self.session.findById("wnd[0]").sendVKey(0)

if __name__=='__main__':
unittest.main()
former_member813521
Discoverer
0 Kudos
Hi stefan.schnell

I need help to return session if exists, or log in and return session case not exists.

Can help me this?

 

Like this but in python:

If Not IsObject(application) Then
Set SapGuiAuto = GetObject("SAPGUI")
Set application = SapGuiAuto.GetScriptingEngine
End If
If Not IsObject(connection) Then
Set connection = application.Children(0)
End If
If Not IsObject(session) Then
Set session = connection.Children(0)
End If
If IsObject(WScript) Then
WScript.ConnectObject session, "on"
WScript.ConnectObject application, "on"
End If
0 Kudos
Hello all,

I'm not having any trouble, I'm just in doubt if I'm able to execute a Python code in background (like using Task Scheduler to run a code in a VM).

Is it possible?

This is my code:
# -Begin-----------------------------------------------------------------

# -Includes--------------------------------------------------------------
import sys, win32com.client
import subprocess, time, json, os

config_path = "path/to/your/username/and/password"

with open(config_path) as config_file:
config = json.load(config_file)
config = config["share_point"]

#set you username and passsword according with the file.
username = config["id"]
password = config["password"]

# -SUB Main--------------------------------------------------------------
def Main():
try:

subprocess.check_call(
['C:\Program Files (x86)\SAP\FrontEnd\SAPgui\\sapshcut.exe', '-system=SID', '-client=NUM', f'-user={username}',
f'-pw={password}'])
time.sleep(10)

SapGuiAuto = win32com.client.GetObject("SAPGUI")
if not type(SapGuiAuto) == win32com.client.CDispatch:
return

application = SapGuiAuto.GetScriptingEngine
if not type(application) == win32com.client.CDispatch:
SapGuiAuto = None
return

connection = application.Children(0)
if not type(connection) == win32com.client.CDispatch:
application = None
SapGuiAuto = None
return

session = connection.Children(0)
if not type(session) == win32com.client.CDispatch:
connection = None
application = None
SapGuiAuto = None
return

#UserArea = session.findById("wnd[0]/usr")
#Control = UserArea.findByName("shellcont", "GuiContainerShell")
#print(Control.Text)

# print(session.findById("wnd[0]/usr").findByName("shellcont", "GuiContainerShell").Text)
session.findById("wnd[0]").maximize()
# access ZSE16N
session.findById("wnd[0]/tbar[0]/okcd").Text = "/nZSE16N"
session.findById("wnd[0]").sendVKey(0)

# search table "ZM_J_1BNFDOC_LIN"
session.findById("wnd[0]/usr/ctxtGD-TAB").Text = "ZM_J_1BNFDOC_LIN"
session.findById("wnd[0]/usr/txtGD-MAX_LINES").Text = ""
session.findById("wnd[0]").sendVKey(0)

#insert data to fields in SAP
session.findById("wnd[0]/usr/tblSAPLSE16NSELFIELDS_TC/ctxtGS_SELFIELDS-LOW[2,2]").Text="ZE"

session.findById("wnd[0]/usr/tblSAPLSE16NSELFIELDS_TC/ctxtGS_SELFIELDS-LOW[2,6]").Text= "21.07.2022"
#current date
session.findById("wnd[0]/usr/tblSAPLSE16NSELFIELDS_TC/ctxtGS_SELFIELDS-HIGH[3,6]").Text= "21.08.2022"

#deselect all and select fields (Doc. Number - Doc. Date - Post. Date.)
session.findById("wnd[0]/tbar[1]/btn[18]").press()
session.findById("wnd[0]/usr/tblSAPLSE16NSELFIELDS_TC/chkGS_SELFIELDS-MARK[5,1]").Selected=True
session.findById("wnd[0]/usr/tblSAPLSE16NSELFIELDS_TC/chkGS_SELFIELDS-MARK[5,5]").Selected=True
session.findById("wnd[0]/usr/tblSAPLSE16NSELFIELDS_TC/chkGS_SELFIELDS-MARK[5,6]").Selected=True
session.findById("wnd[0]/tbar[1]/btn[8]").press()

#Download and substitute the excel file in downloads
session.findById("wnd[0]/usr/cntlRESULT_LIST/shellcont/shell").pressToolbarContextButton("&MB_EXPORT")
session.findById("wnd[0]/usr/cntlRESULT_LIST/shellcont/shell").selectContextMenuItem("&XXL")
session.findById("wnd[1]/tbar[0]/btn[0]").press()

#set path to save the file
session.findById("wnd[1]/usr/ctxtDY_PATH").Text='C:/Users/pm8dw8s/Downloads'
session.findById("wnd[1]/usr/ctxtDY_FILENAME").Text="Importados.XLSX"

#press to replace
session.findById("wnd[1]/tbar[0]/btn[11]").press()

#close SAP
session.findById("wnd[0]").close()
session.findById("wnd[1]/usr/btnSPOP-OPTION1").press()

#Kill background task
os.system("taskkill /IM saplogon.exe /F")
print("End")

except:
print("error")

finally:
session = None
connection = None
application = None
SapGuiAuto = None

print("End")
# -Main------------------------------------------------------------------
Main()

# -End-------------------------------------------------------------------
former_member769304
Discoverer
0 Kudos
Hello Stefan,

Have been following your suggestions to automate SAP Gui using python and have successfully automated many sap processes.  Currently we are trying to use Robot framework sapguilibrary for automation.  In cases where we have to press enter for recurring warning type status bar messages, we dont have support in Robot framework   Could you kindly suggest an alternative.

 

Thanks

Akhila
waddoum81
Explorer
0 Kudos
Hello, after enabling scripting for my SAP profile, I'm able to generate a script and run it from Python... my question is, would it be possible to deploy this solution as a package (an exe generated from Python for example) to another SAP user (a colleague) without enabling scripting on his SAP profile? Thanks a lot for any support.
Vinicius
Discoverer
0 Kudos

"Hi Stefan, thanks for your support. I'm facing significant issues dealing with session IDs in Python. While I'm not processing multiple tasks, sometimes when I run a Python code, I use an SAP shortcut to open a new session directly in a transaction. Consequently, this new GUI has a dynamic session ID. How can I approach identifying this new session?"

Marduk
Explorer
0 Kudos

@former_member769304 as an alternative to SapGuiLibrary you can use RoboSAPiens (https://pypi.org/project/robotframework-robosapiens/). It allows pressing all the key combinations supported by the SAP GUI Scripting API, which includes the Enter key.

 

Marduk
Explorer
0 Kudos

@former_member729110 You are right that Scripting Tracker doesn't show GuiTree nodes or GuiGridView cells. The good news is you don't have to implement the logic for traversing them. It is already built into RoboSAPiens (https://pypi.org/project/robotframework-robosapiens/). This library offers a uniform API for all tabular components in the SAP GUI. You can address any cell using as coordinates the column title and either the row number or some text in the row.

Labels in this area