首页 > 编程语言 > 详细

Python驱动SAP GUI完成自动化(选择布局+动态获取节点值)

时间:2020-05-30 21:53:46      阅读:203      评论:0      收藏:0      [点我收藏+]

  小爬在之前的文章中(Python结合SAP GUI Script操作sap的简易教程

讨论过如何利用工具Scripting Tracker录制python操纵SAP GUI的py脚本。软件的录制和生成的代码界面如下:

技术分享图片

 

 

 

  场景一:实际业务中,除了一些常规步骤,我们可能会驱动SAP GUI中的一些布局,改变数据的展现形式,如:

技术分享图片

 

 

  譬如这段点击“选择布局”,选中“/GX发出商品"布局的操作,我们用工具得到的python代码如下:

    session.findById("wnd[0]/tbar[1]/btn[33]").press() # 点击”选择布局"按钮
    session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").setCurrentCell(14, "TEXT") # 选中某个单元格
    session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").firstVisibleRow = 3 # 驱动纵向滚动条
    session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectedRows = "14" # 选中第15行
    session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").clickCurrentCell()  # 单击选中的单元格

  通过观察实际界面可知,我们要的“/GX发出商品"属于从上至下的第15个布局(索引号从0开始,因此这里的索引号应该是14),但是考虑到很多用户都有权限去设置布局或者变式,导致我们的自动化脚本如果直接以索引号来定位某个布局的做法,非常不稳定,易出错。更稳妥的做法是基于变式的“名称”,这个名称具备唯一性,哪怕将来有新增的布局,或者用户排版布局所用到的排序变了,我们依然可以通过布局的名称来定位它。

通过SAP GuiContainerShell的rowCount和visibleRowCount属性,可以分别得到该布局的shell对应的行数和 可见行数,我们遍历所有的行,然后根据 每个cell的getCellValue方法就能拿到布局的名称,最终找到相应的布局。代码就可以这样写:

    session.findById("wnd[0]/tbar[1]/btn[33]").press() # 点击”选择布局"按钮
    e=session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell")
    row_count=e.rowCount
    variant="" # 变式
    for i in range(row_count):
        variant=e.getCellValue(i,"VARIANT")
        if variant=="/GX发出商品":
            e.setCurrentCell(i, "VARIANT") # 选中某个单元格
            e.clickCurrentCell()
    if variant=="":
        print("该布局中没有找到“/GX发出商品”变式,请核实!") 

录制代码中以下这两行,在实际中,可以省略,不影响代码的执行:

    session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").firstVisibleRow = 3 # 驱动纵向滚动条
    session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectedRows = "14" # 选中第15行

 

  场景二:实际业务中,我们可能会碰到这种行数不固定,节点可以逐级展开的sap 界面,我们又该如何取到对应节点对应字段的值呢?

技术分享图片

 

 

 我们逐级展开节点到想要的位置,然后,选中某个值的过程,用tracker录制得到python代码,形式类如:

session.findById("wnd[0]").resizeWorkingPane(234, 40, 0)
session.findById("wnd[0]/shellcont/shell/shellcont[1]/shell[1]").expandNode("        339")
session.findById("wnd[0]/shellcont/shell/shellcont[1]/shell[1]").expandNode("        576")
session.findById("wnd[0]/shellcont/shell/shellcont[1]/shell[1]").expandNode("        608")
session.findById("wnd[0]/shellcont/shell/shellcont[1]/shell[1]").expandNode("        612")
session.findById("wnd[0]/shellcont/shell/shellcont[1]/shell[1]").expandNode("        613")
session.findById("wnd[0]/shellcont/shell/shellcont[1]/shell[1]").selectItem("        614", "C          1")
session.findById("wnd[0]/shellcont/shell/shellcont[1]/shell[1]").ensureVisibleHorizontalItem("        614", "C          1")
session.findById("wnd[0]/shellcont/shell/shellcont[1]/shell[1]").topNode = "          2"

这结构,每一个cell可以看作是一个Item对象,我们可以用sap GUI Scripting API手册查到它的GetItemText方法:

技术分享图片

 

 

 这里的Key 和Name就是上面录制得到的脚本中的("        614","C          1")形式:

  由于这种含可展开节点的SAP GUI界面,行数都是不确定的,为了一劳永逸,我们还是要先动态得到 key,再基于Key Name,依据getItemText方法,得到节点的名称,如果跟我们要的节点名一样,我们就可找到 对应节点的 其他字段的值。

于是关键问题演化成了,这个"        614"的key是怎么来的,我们大胆猜测,它就是一个变化的数字,前面填充空格,实际的几次试错后,小爬发现这个空格数不是固定的,而Key的长度是却固定的。

  所以,我们先用字符串的len("        614")方法得到key的长度为11,假如key中的数字 i 从1往1000(假定最大值不超过1000)变,我们可以计算其长度len(str(i)),来得到该填充的空格数,我们把整个界面用循环遍历一遍,接下来代码验证开始:

    col1_value="";col2_value="";col3_value="";node_name=""

    e=session.findById("wnd[0]/shellcont/shell/shellcont[1]/shell[1]")
    for i in range(1,1000): # 这里如果不清楚具体有多少行,可以设置一个很大的数,最后break跳出循环即可
        node_name = e.getItemText(" "*(11-len(str(i)))+str(i), "&Hierarchy")  # 索引号总共11位,除了数字,开头用多个空格符补齐,数字位数越大,则要补的空格越少
        if node_name == "损益表":
            col1_value=e.getItemText(" "*(11-len(str(i)))+str(i), "C          1")
            col2_value=e.getItemText(" "*(11-len(str(i)))+str(i), "C          3")
            col3_value=e.getItemText(" "*(11-len(str(i)))+str(i), "C          5")
            # 我们要获取 含“存货变动”关键字的 科目的cmp金额
        elif "存货变动" in node_name:
            cmp_value=e.getItemText(" "*(11-len(str(i)))+str(i), "C          5")
        if col1_value!="" and col2_value!="" and col3_value!="":
            break

  这段代码完美运行,上面的col1_value,col2_value,col3_value就对应上图中“tot.rpt.pr  tot.cmp.pr  绝对差异”  三个字段的值。从上面的代码可以看出来,我们手工想要看到某个根节点的值,需要对节点逐级展开(expand node),操作非常繁琐,通过python对过程自动化,后台的代码不需要展开节点本身,只要拿到节点的key 和name,我们原则上就可以取到每个节点的Itemtext,非常高效~~~

  各位正在研究python-sap自动化的童鞋,一起来get新技能吧~~~

 

Python驱动SAP GUI完成自动化(选择布局+动态获取节点值)

原文:https://www.cnblogs.com/new-june/p/12994634.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!