使用Python在SAP GUI中进行多处理
我的汁液很老,我无法用它拨打API。因此,我必须操纵SAP的GUI才能做我的事情。
我正在尝试使用Python在两个不同的窗口中同时访问两项SAP交易。
为此,我正在使用库:pywin32,子进程和多处理。
但是我会收到以下错误:
TypeError:无法泡菜'Pyidispatch'对象
和
常规:[WinError 5] Acess拒绝
我到目前为止所获得的是打开两个窗口(创建两个SAP GUI会话),并在不同的窗口中访问交易,但一个接一个地,换句话说,而不是同时。
该测试程序构成3个分开的脚本:
- 一个类可以创建连接,创建第一个会话并登录到帐户中。
- 第二类是“操纵” SAP GUI
- 最后一个是主要脚本。
脚本:
createConnection.py
subcrocess Import popen 进口时间 来自win32com.client import getObject SAP类: def __init __(self,sap_env,user_id,user_password,语言=“ en”, 新闻= false,connectby = 2): self.sap_file =“ c:\\ program文件(x86)\\ sap \\ frontend \\ sapgui” +\ \ \ \ \ \ \ \ \ “ \\ saplogon.exe” self.sap_env = sap_env self.user_id = user_id self.user_password = user_password self.language =语言 self.connectby =连接 self.newsession =新闻 def __get_sap_gui __(self): 尝试: 返回getObject('sapgui')。getCriptingEngine 除了: 时间。 返回self .__ get_sap_gui __() def get_sap_connection(self): 如果self.connectby == 3: popen(self.sap_file +'' + self.sap_env) sapgui = self .__ get_sap_gui __() conn = sapgui.connections(0) 超时= 10 而conn.sessions.count == 0和超时: 时间。 超时 - = 1 如果超时== 0:提高异常(“无法连接”) 别的: popen(self.sap_file) sapgui = self .__ get_sap_gui __() conn =无 如果self.connectby == 1: 如果sapgui.connections.count> 0:#不好,我稍后再解决 对于sapgui.connections中的conn: 如果conn.description == self.sap_env: 休息 如果不是conn: conn = sapgui.openconnection(self.sap_env) 别的: 如果sapgui.connections.count> 0: 对于sapgui.connections中的conn: 如果在conn.connectionstring中self.sap_env: 休息 如果不是conn: conn = sapgui.openconnectionbyconnectionstring(self.sap_env) 返回连接 def get_sap_session(self,conn): 如果self.newsession: numsessions = conn.sessions.count + 1 conn.sessions(0).createsession() 而Conn.Sessions.Count≪数字:通过 session = conn.sessions(numsessions-1) 别的: 会话= conn.sessions(0) 如果session.findbyid('wnd [0]/sbar')。text.startswith('snc登录'): session.findbyid('wnd [0]/usr/txtrsyst-langu')。text = self.language session.findbyid('wnd [0]')。sendvkey(0) session.findbyid('wnd [0]')。sendvkey(0) elif session.info.user =='': session.findbyid('wnd [0]/usr/txtrsyst-bname')。text = self.user_id session.findbyid('wnd [0]/usr/pwdrsyst-bcode')。文本= \ self.user_password session.findbyid('wnd [0]/usr/txtrsyst-langu')。text = self.language session.findbyid('wnd [0]')。sendvkey(0) session.findbyid('wnd [0]')。最大化() 返回会话
manipulatesap.py
从createConnection导入SAP 类Querysap(SAP): def __init __(self,sap_env,user_id,user_password,语言): super()。 self.connection = self.get_sap_connection() self.session = self.get_sap_session(self.connection) self.new_session =无 def open_new_windows(self): self.connection。课程(0).createsession() self.connection。课程(0).createsession() self.new_session = self.connection.sessions(1) @财产 def sess1(self): 返回自我 @财产 def sess2(self): 返回self.new_session
main.py
来自ManiPulateSap Import QuerySap 从多处理进口池,过程 从时间进口睡眠 def goto_trasaction(会话,transacion): session.findbyid(“ wnd [0]/tbar [0]/okcd”)。text = transacion session.findbyid(“ wnd [0]”)。sendvkey(0) 睡眠(5) def sap_interface_multi_process(USR,PW,Env): sap_nav = querysap(sap_env = env,user_id = usr,user_password = pw, 语言=“ pt”) sap_nav.open_new_windows() session1 = sap_nav.sess1 session2 = sap_nav.sess2 p1 = process(target = goto_trasaction,args =(session1,“ transacion a”)) p2 = process(target = goto_trasaction,args =(session2,“ transaction b”)) p1.start() p2.start() p1.join() p1.join() def main(): 打印(“>>> start”) sap_env =“ string_for_connection” sap_interface_multi_process(“ usr_id”,“ usr_pw”,sap_env) 打印(“>>> terinial”) 如果__name__ ==“ __ -main __”: 主要的()
你们能帮我找到我想念的东西以及我应该做什么吗?
非常感谢。
My SAP is very old and I can't make API calls with it. So, I have to manipulate the GUI of SAP to do my stuff.
I'm trying to access two SAP transactions at the same time in two different windows using Python.
To do this I'm using the libraries: pywin32, subprocess and multiprocessing.
But I'm getting the following error:
TypeError: cannot pickle 'PyIDispatch' object
and
PermissionError: [WinError 5] Acess denied
What I got until now is to open two windows (create two SAP GUI sessions) and access the transaction in different windows but one after the other, in other words, not at the same time.
This test program constitutes in 3 separated scripts:
- One have the class to create a connection, create the first session and login into the account.
- The second class is to "manipulate" the SAP GUI
- The last one is the main script.
The Scripts:
createconnection.py
from subprocess import Popen import time from win32com.client import GetObject class Sap: def __init__(self, sap_env, user_id, user_password, language="EN", newSession=False, connectBy=2): self.sap_file = "C:\\Program Files (x86)\\SAP\\FrontEnd\\SapGui" +\ "\\saplogon.exe" self.sap_env = sap_env self.user_id = user_id self.user_password = user_password self.language = language self.connectBy = connectBy self.newSession = newSession def __get_sap_gui__(self): try: return GetObject('SAPGUI').GetScriptingEngine except: time.sleep(0.5) return self.__get_sap_gui__() def get_sap_connection(self): if self.connectBy == 3: Popen(self.sap_file + ' ' + self.sap_env) sapGui = self.__get_sap_gui__() conn = sapGui.Connections(0) timeout = 10 while conn.Sessions.Count == 0 and timeout: time.sleep(1) timeout -= 1 if timeout == 0: raise Exception("Fail to connect") else: Popen(self.sap_file) sapGui = self.__get_sap_gui__() conn = None if self.connectBy == 1: if sapGui.Connections.Count > 0: # it's not good, I'll fix this later for conn in sapGui.Connections: if conn.Description == self.sap_env: break if not conn: conn = sapGui.OpenConnection(self.sap_env) else: if sapGui.Connections.Count > 0: for conn in sapGui.Connections: if self.sap_env in conn.ConnectionString: break if not conn: conn = sapGui.OpenConnectionByConnectionString(self.sap_env) return conn def get_sap_session(self, conn): if self.newSession: numSessions = conn.Sessions.Count + 1 conn.Sessions(0).createsession() while conn.Sessions.Count < numSessions: pass session = conn.Sessions(numSessions-1) else: session = conn.Sessions(0) if session.findById('wnd[0]/sbar').text.startswith('SNC logon'): session.findById('wnd[0]/usr/txtRSYST-LANGU').text = self.language session.findById('wnd[0]').sendVKey(0) session.findById('wnd[0]').sendVKey(0) elif session.Info.User == '': session.findById('wnd[0]/usr/txtRSYST-BNAME').text = self.user_id session.findById('wnd[0]/usr/pwdRSYST-BCODE').text =\ self.user_password session.findById('wnd[0]/usr/txtRSYST-LANGU').text = self.language session.findById('wnd[0]').sendVKey(0) session.findById('wnd[0]').maximize() return session
manipulatesap.py
from createconnection import Sap class QuerySap(Sap): def __init__(self, sap_env, user_id, user_password, language): super().__init__(sap_env, user_id, user_password, language=language) self.connection = self.get_sap_connection() self.session = self.get_sap_session(self.connection) self.new_session = None def open_new_windows(self): self.connection.Sessions(0).createsession() self.connection.Sessions(0).createsession() self.new_session = self.connection.Sessions(1) @property def sess1(self): return self.session @property def sess2(self): return self.new_session
main.py
from manipulatesap import QuerySap from multiprocessing import Pool, Process from time import sleep def goto_trasaction(session, transacion): session.findById("wnd[0]/tbar[0]/okcd").text = transacion session.findById("wnd[0]").sendVKey(0) sleep(5) def sap_interface_multi_process(usr, pw, env): sap_nav = QuerySap(sap_env=env, user_id=usr,user_password=pw, language="PT") sap_nav.open_new_windows() session1 = sap_nav.sess1 session2 = sap_nav.sess2 p1 = Process(target=goto_trasaction, args=(session1, "TRANSACION A")) p2 = Process(target=goto_trasaction, args=(session2, "TRANSACTION B")) p1.start() p2.start() p1.join() p1.join() def main(): print(">>> Start") sap_env = "string_for_connection" sap_interface_multi_process("usr_id", "usr_pw", sap_env) print(">>> Finish") if __name__ == "__main__": main()
Could you guys help me to find what I missing and what I should do?
Thank you very much.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
终于,在VACTION的一段时间后,我得到了解决方案。
但是我不得不重复大量的代码。
我所做的是将SAP类实例化到一个对象,然后将此对象传递给将在并行执行的函数。在此功能内部,我使用SAP类方法来创建连接并创建会话。
这是我的解决方案。不漂亮,但是有效:
Finally I got the solution after sometime of vaction.
But I had to refactory a lot of my code.
What I did was to instantiate the sap class to an object and pass this object to a function that will be executed in parallel. Inside of this function I use the sap class method to create a connection and create a session.
Here is my solution. Not pretty but worked: