SAP系统定位动态元素

场景介绍

在项目中我们会遇到SAP客户端,在某个项目中需要抓取到SAP系统查出来的金额值,但是此SAP界面是根据位置来得到元素,所以位置变化,相应元素也会发生变化,且每个查询的结果位置都不在同一个坐标,如下图所示:

成本中心1 成本中心2

基于上图使用Creator操作发现以下几点问题:

  1. 此SAP页面元素是根据坐标来获取的,因为每次所在的位置不一值,所以元素也会跟着变化。

  2. 某些部门数据行数不一致,需要滑动鼠标才可见”过量吸收/不足“,并获取旁边的金额。

这些问题导致无法灵活获取目标值,此案例用来解决该类问题。

解决方案

分析目标

在Creator中通过“目标选择器”选定金额值所在的元素,该元素会有一个明显特征,ID参数上会有类似坐标的两维参数。在这里我们为了简单起见,采用第一个参数,第二个参数来描述。

第一个参数:查询到元素ID的第一个参数 成本中心2

第二个参数:查询到元素ID的第二个参数 成本中心2

根据观测SAP元素,发现"第二个参数"会根据滑动产生变化,而"第一个参数"总是不变,如下图所示。 可视化

源代码

流程思路

详细的流程思路图如下: 流程图

从以上流程思路得知采用屏幕文本查找方式来获取“金额”的相对元素。根据"第一个参数"不变,并获取同行“过量/吸收不足正常”的"第二个参数",从而来得到目标金额。


疑问:

  1. 为什么鼠标滚动是2下,不是3下,4下? 答:鼠标滚动幅度,需要根据开发者分辨率情况来定,笔者在此采用的是1920x1080分辨率,使用滚动幅度2下最佳。

  2. 流程图中是否已执行20次,为什么是20次,这个标准是哪里来的? 答:目标框3-5次滚动就可以到底,20次完成是为了保证稳定,避免后续数据增加导致无法使用


实现步骤

1.移动到目标查询结果框获取改框焦点

//移动到数据界面,确保可以进行鼠标下滑
Mouse.Move(880, 500, false,{"iDelayAfter":300,"iDelayBefore":200})

成本中心3

2.鼠标滚动

//鼠标滚动2下,滚动2下是为了滚动幅度大一点
Mouse.Wheel(2,"down", [],{"iDelayAfter":300,"iDelayBefore":200})

3.判断目标元素的相对元素是否存在

//判断 “过量/吸收不足正常 文本是否存在”
#icon("@res:36pat1m0-4slj-9pbm-tclq-jq5o3tsvsoun.png")
bRet = Text.Exists({"wnd":[{"cls":"SAP_FRONTEND_SESSION","title":"成本中心: 实际/计划/差异","app":"saplogon"}],"sap":{"id":"/app/con[0]/ses[0]/wnd[0]/usr"}},"过量","instr",1,10000,{"bContinueOnError":false,"iDelayAfter":300,"iDelayBefore":200,"bSetForeground":true})

结果不存在则向下循环滚动鼠标,直到出现文本“过量/吸收不足正常”


4.结果存在查找界面文本获取“过量/吸收不足正常”的元素

//存在的话获取“过量/吸收不足正常”的元素
#icon("@res:asu7tjeb-7orb-kv4c-jtmh-4h3rqmon7rml.png")
objUiElement = Text.Find({"wnd":[{"cls":"SAP_FRONTEND_SESSION","title":"成本中心: 实际/计划/差异","app":"saplogon"}],"sap":{"id":"/app/con[0]/ses[0]/wnd[0]/usr"}},"过量","instr",1,10000,{"bContinueOnError":false,"iDelayAfter":300,"iDelayBefore":200,"bSetForeground":true})
TracePrint objUiElement

打印对象

5.单独拿出 id

//单独拿出 id
oldId=objUiElement["sap"]["id"]

id

6.拼装目标元素id

//把逗号出现的位置拿出来
iRet = InStr(oldId,",",1,false)

//因目标金额“第一个值”是36,将36替换进查找的元素中

newId = SubStr(oldId,1,iRet-2)&"36"&SubString(oldId,iRet,Len(oldId)+1)

说明:根据每个部门的元素分析,发现金额栏的“第一个参数”全是36,这时就可将“第一个参数”替换为固定值36

SubStr(oldId,1,iRet-2)&"36"

![id2](/images/Application-Automation/SAP-Target-Object-ID-Print2.png

因“过量/吸收不足”的“第二个参数”与金额“第二个参数”肯定一致,所以将“过量/吸收不足”的“第二个参数”提取出来拼接到金额中去

SubString(oldId,iRet,Len(oldId)+1)

7.将新赋值的元素id放入到objUiElement

objUiElement["sap"]["id"]=newId

8.通过GetValue获取文本值

compareValue=UiElement.GetValue(objUiElement)

打印结果发现金额已经获取到了

TracePrint compareValue) 

![金额](/images/Application-Automation/SAP-Target-Cost-Print.png

代码展示

//循环查找 “过量/吸收不足正常 文本所在位置”
Do
    //移动到数据界面,确保可以进行鼠标下滑
    Mouse.Move(880, 500, false,{"iDelayAfter":300,"iDelayBefore":200})
    //鼠标滚动2下
    Mouse.Wheel(2,"down", [],{"iDelayAfter":300,"iDelayBefore":200})
    //判断 “过量/吸收不足正常 文本是否存在”
    #icon("@res:36pat1m0-4slj-9pbm-tclq-jq5o3tsvsoun.png")
    bRet = Text.Exists({"wnd":[{"cls":"SAP_FRONTEND_SESSION","title":"成本中心: 实际/计划/差异","app":"saplogon"}],"sap":{"id":"/app/con[0]/ses[0]/wnd[0]/usr"}},"过量","instr",1,10000,{"bContinueOnError":false,"iDelayAfter":300,"iDelayBefore":200,"bSetForeground":true})
    TracePrint(bRet)
    If bRet
        //存在的话获取“过量/吸收不足正常”的元素
        #icon("@res:asu7tjeb-7orb-kv4c-jtmh-4h3rqmon7rml.png")
        objUiElement = Text.Find({"wnd":[{"cls":"SAP_FRONTEND_SESSION","title":"成本中心: 实际/计划/差异","app":"saplogon"}],"sap":{"id":"/app/con[0]/ses[0]/wnd[0]/usr"}},"过量","instr",1,10000,{"bContinueOnError":false,"iDelayAfter":300,"iDelayBefore":200,"bSetForeground":true})
        TracePrint objUiElement
        //单独拿出 id
        oldId=objUiElement["sap"]["id"]
        //把逗号出现的位置拿出来
        iRet = InStr(oldId,",",1,false)
        //因目标固定列是36行,将36替换进查找的元素中
        newId = SubStr(oldId,1,iRet-2)&"36"&SubString(oldId,iRet,Len(oldId)+1)
        objUiElement["sap"]["id"]=newId
        compareValue=UiElement.GetValue(objUiElement)
        TracePrint compareValue
        If compareValue=""
            TracePrint "过量/吸收不足正常"
        Else
            //发送邮件提醒
            TracePrint "发送邮件提醒"
        End If

        Break 

    Else
    count=count+1
        If count=20
            count=1
            Break
        Else
                TracePrint "没有查到“过量/吸收不足正常,继续进行下一次循环”"
                count=1

            End If       
        End If
Loop
最后更新于 5th Nov 2020