小爬之前已经就“Python驱动SAP GUI完成自动化”问题写过几篇文章,其核心都是恰当运用SAP GUI Scripting API中元素的属性和方法,来操纵SAP session的元素。下面来看看两个新场景下的新问题。
常见场景一:
我们先来看看对象的changeable属性怎么为我所用来解决特定的问题。
如上图所示,菜单栏的“基本清单(B)”项 字体为浅灰色,对应的属性其实就是changeable=False,黑色字体的项则表示changeable=True。我们可以使用工具Tracker的 Analyser模块扫描下整个sap session会话,结果如下:
工具得到的结果,changeable属性勾选了的元素,正好对应页面中菜单栏子菜单为“浅灰色字体”的子元素。
最近,小爬给同事写的一个自动化脚本,需要根据Faglb03来查找总账项目,好好的脚本,在用户电脑上不可用。经仔细对比发现,部分用户的SAP GUI对应事务代码下的 清单模式 跟我的不一样。只要用户依次点击了 SAP菜单栏的“设置”、“切换清单(I)”,切换到对应的清单模式,我写的脚本便可以顺利执行。
那么问题就转化为:如何知道用户的SAP界面当前使用的哪类清单模式呢?
思路一:
可以借助,Python中的try……except模块来查找某个清单模式下的元素,当找不到该元素出错时,我们就可以在except中执行“切换清单”的语句。
思路二:
小爬观察到,“切换清单”之前 和之后,对应的 SAP “设置”菜单的子项“基本清单(B)”,其属性 changeable由 False变为了True:我们只要捕获该属性,便知道是否需要执行“切换清单”,见下图标红处字体颜色可知:
此处的Python代码示例如下:
# 判断changeable属性后,决定是否点击“切换清单”,来统一用户界面显示状态 If session.findById("wnd[0]/mbar/menu[5]/menu[0]").changeable = True: session.findById("wnd[0]/mbar/menu[5]/menu[8]").Select() # 点击切换清单
常见场景二:
我们如何捕获SAP中,某个界面输入过滤条件后的一长串结果值,如下图:
上面两张图中,step1的传参步骤都可以通过SAP的脚本录制功能得到可用的代码,问题是step2,假如我想获得所有过滤条件后的总账科目数据,放入剪贴板,该怎么办?
我们同样可以有两种思路:
思路一:
通过录制脚本的过程中,点击“总账科目”列某一行,就可以根据捕获的脚本代码知道元素的ID,然后根据
要使用findAllByName 方法,我们需要知道这些元素的Name和Type,这个可以用 Tracker 工具的analyser扫描后得到,见下图:
从上图可知,我们需要的总账科目编号就是 某个元素的文本,这些元素的共性:Type为GuiLabel (30),而Name为空。有了这些分析,我们就可以用如下的代码,拿到所有的总账科目编号,形成列表,最后再push到系统的剪贴板里,供后面的步骤使用:
import sys, win32com.client import win32api,win32con,win32gui,time import win32clipboard as w def get_text(): # 获取剪贴板中内容 w.OpenClipboard() copy_text = w.GetClipboardData(win32con.CF_TEXT) w.CloseClipboard() return copy_text def set_text(astring): #复制内容到剪切板 w.OpenClipboard() w.EmptyClipboard() d=w.SetClipboardData(win32con.CF_TEXT,astring) w.CloseClipboard() 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 subjects=[] groupMembers=session.ActiveWindow.findAllByName("","GuiLabel (30)") for groupMember in groupMembers: if groupMember.text.startswith("6"): subjects.append(groupMember.text) subjects_string=" ".join(subjects).encode()
tips:上面代码中 set_text(astring)方法可以把 字符串传给系统的剪贴板,get_text()方法可以获取剪贴板内容,我们完全可以手工Ctrl+Y & Ctrl+C的方法将这些总账科目批量复制到剪贴板中,利用 get_text()方法 得到系统中数据的呈现格式,然后利用 set_text(astring)来构造剪贴板内容。
如果您在使用 Python来实现 SAP GUI的一些自动化操作,也遇到过类似的问题场景,上面的对象changeable属性,findAllByName方法结合Tracker的analyser工具,就提供了一套很好的解决思路,小伙伴们,赶紧动手试试吧!