写一个SAPGUI自助登陆的python脚本程序(3)——SAP操作

SAP脚本抓取

打开了对应的client以后,就涉及到了,输入登录账号的工作了。

在sap程序上操作是需要使用sap的脚本的,如在哪个位置输入账号和密码,对应的值是什么,映射到sap的程序执行上的脚本怎么跑的,这个我们是不知道的。
SAP本身提供了一些外部直接调用的gui的api,但是使用方法需要参考官方的说明去研究,挺麻烦的。

我呢,搜寻了多方资料,找到了一个大家推荐的工具,可以在GUI上操作时,自动的抓取映射出的操作脚本,这样就会方便很多。

SAP博客站的一个著名博主:Stefan Schnell(他写了很多sap script与其他语言结合的文章,非常受用)以及他开发的免费的sap脚本工具:
Scripting Tracker – Development Tool for SAP GUI Scripting
内含scripting Tracker的下载链接

总之呀,这个工具真的肥肠的霸道呀,我自己测试了后,简直有种顶礼膜拜的感觉。
你在sapgui上所有的操作,都可用它抓出来脚本,然后就可以自己写一些自动化的程序了。
真的是肥肠的霸道呀!!!

ScriptingTracker用一用

ScriptingTracker有录制操作生成脚本的功能,并且支持python、java、powerShell等脚本语言导出。所以就对我们很友好啦。

首先我们进入后,先做一下scan,会扫出在运行的gui的进程。
然后进入Recorder视图,
选取到扫出来的sap session,选择要输出的脚本语言(我写python脚本,就选择python)。然后开始录制。
这时候在sapgui上操作就可以了,输入账号密码回车确认,就会发现recorder同步录制到了操作脚本。

录制到的脚本,有一些是实际上不需要的,所以需要后期依据需要做一些删减。

注意点

要考虑到一种情况,
比如,我已经登陆了2个client了,但是我现在要登陆第3个,
那么我在获取这第三个client的登陆窗口时,就要判断下找到的是它,而不是选到了另外2个client的窗口,否则输入账号密码肯定是会报错的。

还有要注意脚本跑的会很快,但是程序的窗口上的操作时有时间延时的,所以需要在脚本上注意加一些时间的buffer空闲。

相关代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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

# 会检测当前的连接,如果存在连接,即application.Children(0)已经有了。则后面session输入账号密码就会报错。
# 所以优化下,判断当前application.Children(n+1)是否存在,存在,则加1。
# 需要注意的是Children(0)是一定有的,不会不存在。检查的是下一个Children(n+1)是否存在,不存在,就取出Children(n),这个有点绕。
n = 0
while True:
try:
application.Children(n+1)
except:
break
n += 1
# connection = application.Children(0)
connection = application.Children(n)
if not type(connection) == win32com.client.CDispatch:
application = None
SapGuiAuto = None
return
time.sleep(2)

flag=0
while flag==0:
try:
session = connection.Children(0)
flag=1
except:
time.sleep(0.5)

if not type(session) == win32com.client.CDispatch:
connection = None
application = None
SapGuiAuto = None
return
session.findById("wnd[0]/usr/txtRSYST-BNAME").text = id #SAP登陆用户名
session.findById("wnd[0]/usr/pwdRSYST-BCODE").text = pwd #SAP登陆密码
session.findById("wnd[0]").sendVKey(0)

代码的部分说明:

  • 代码里可以看到,定义了4个变量,在来回的用。
    connection、application、SapGuiAuto、session这个怎么理解呢?
    我们是要做一些判断的,这样才能找到正确的窗口。
    可以简单这么理解,SapGuiAuto是用来找gui的程序,application对应client界面,connection对应client里新的界面,session是最后找到的输入账号密码的窗口。

好啦,这样子sap界面的脚本执行操作,这部分的代码也差不多就这样了。
基本上两个大的代码段——句柄&SAP,就完事了。

后面展示下成品的效果吧。