Python驱动SAP GUI完成自动化(三)

  小爬之前已经就“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,然后根据

session.findById(your_Id).text方法获得对应的文本。可惜该界面都是lbl(label元素),小爬没有找到它的rowCount属性,所以不好确定遍历的范围,不过可以通过万能的while True 结合Try except语句来解决。
思路二:
  利用 该对象的findAllByName方法得到元素的集合,再来提取符合条件的label,即我们这里要获取的“总账科目”:

 要使用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工具,就提供了一套很好的解决思路,小伙伴们,赶紧动手试试吧!

原文地址:https://www.cnblogs.com/new-june/p/13073895.html