• Python结合SAP GUI Script操作sap的简易教程


      众所周知,如果要用Python做一些桌面WIN32应用的自动化工作,就需要用到著名的pywin32尤其是其中的win32com.client模块,pywin32的安装不能直接通过pip install方法,奉上pywin32的官方github链接:https://github.com/mhammond/pywin32/releases。选择与桌面系统版本、python版本对应的版本安装即可:

    如果一切正常,在Ipython中导入该模块时不会报异常!如:

    In [1]: import win32com.client

    接下拉就是建立与sap GUI的连接,如下:

     1     SapGuiAuto = win32com.client.GetObject("SAPGUI")
     2     if not type(SapGuiAuto) == win32com.client.CDispatch:
     3       return
     4 
     5     application = SapGuiAuto.GetScriptingEngine
     6     if not type(application) == win32com.client.CDispatch:
     7       SapGuiAuto = None
     8       return
     9 
    10     connection = application.Children(0)
    11     if not type(connection) == win32com.client.CDispatch:
    12       application = None
    13       SapGuiAuto = None
    14       return
    15 
    16     session = connection.Children(0)
    17     if not type(session) == win32com.client.CDispatch:
    18       connection = None
    19       application = None
    20       SapGuiAuto = None
    21       return

    代码的剩余部分可以通过sap原生的“脚本录制与回放”功能生成vbs脚本语句,直接插入python代码中即可!

    需要强调的是,脚本录制功能并不会记录下所有鼠标键盘操作,过程中如果有些窗口是操作系统本身窗口,依旧需要结合windows句柄的捕获、结合sendmessage、postmessage等win32 API函数来处理。

    当然,还需要查阅sap gui script的帮助文件,里面会列出所有的sap底层对象的属性、方法、对应的参数类型、数量等,界面如下:

    在我的一项实际工作中,需要获得一个shell表单的某个类似于excel 单元格的值,表格是ALV格式的,但是实际录制中没法录制到单元格值,也许你绞尽脑汁,最后通过其他方法(比如 用sendkey结合 ctrl + Y,CTRL + C)达到了同样的效果,但是笔者依然推荐用sap script 原生的API来解决。通过查阅SAP GUI知道它属于“GuiGridView Object”,具有方法“GetCellValue Method”,方法如下:

    Public Function GetCellValue( _
       ByVal Row As Long, _
       ByVal Column As String _
    ) As String
    

      其中column参数为字符串string类型,通过录制sap脚本,双击对应可以录制到列名称,通常录制代码类似:

    session.findById("wnd[0]/usr/cntlCTRL_CONTAINERBSEG/shellcont/shell").currentCellColumn = "SGTXT"

    所以如果想要取得某个单元格(sap中称之为cell)的值,语法如下:

    sgtxt = Table.GetCellValue(0, "SGTXT")

    需要注明的是,SAP底层的ALV格式表格中行号是从 0开始的,如果想要知道表格共有多少数据行,两行代码即可搞定(表格的ID通过脚本录制即可得到):

    Set Table = session.findById("wnd[0]/usr/cntlCTRL_CONTAINERBSEG/shellcont/shell")
           
    tableRowCount = Table.RowCount

    如果要获取sap窗口标题来辅助程序判断,语法也很简单,直接调用session对象的text属性即可,如:

    window_caption=session.findById("wnd[0]").Text

      这些属性方法的操作看似简单,但是如果不查阅相关sap gui script API文档,对API不了解,你自己很难实验出来,也许勉强用别的方法实现,却难免走了弯路或者牺牲了稳定性。毕竟无论是VB、还是Python的编译器,都不会对sap底层的api进行代码提示和自动补充。所以必要时,务必要查阅“帮助文件”。

    此处推荐SAP博客站的一个著名博主:以及他开发的免费的sap脚本工具:

    Scripting Tracker – Development Tool for SAP GUI Scripting,附上博客链接:https://blogs.sap.com/2014/11/20/scripting-tracker-development-tool-for-sap-gui-scripting/

    内含scripting Tracker的下载链接:https://tracker.stschnell.de/

    该工具比原生的sap script更加可视化更加易用,其中Analyser模块界面如下,依靠它可以清晰捕获到sap界面的树形结构和对应的元素id等属性:

    你们关心的脚本录制工具recorder长这样,它支持录制脚本,且支持vb、python、java、powerShell等多种脚本语言的导出:

    实在是良心应用,强烈推荐!

    有了这些,用Python 控制操作SAP,从此不再是难事!

    下面为一个python 操作sap打开T-code ”mm03“的简单示例,供参考:

     1 #-Begin-----------------------------------------------------------------
     2 
     3 #-Includes--------------------------------------------------------------
     4 import sys, win32com.client
     5 
     6 #-Sub Main--------------------------------------------------------------
     7 def Main():
     8 
     9   try:
    10 
    11     SapGuiAuto = win32com.client.GetObject("SAPGUI")
    12     if not type(SapGuiAuto) == win32com.client.CDispatch:
    13       return
    14 
    15     application = SapGuiAuto.GetScriptingEngine
    16     if not type(application) == win32com.client.CDispatch:
    17       SapGuiAuto = None
    18       return
    19 
    20     connection = application.Children(0)
    21     if not type(connection) == win32com.client.CDispatch:
    22       application = None
    23       SapGuiAuto = None
    24       return
    25 
    26     session = connection.Children(0)
    27     if not type(session) == win32com.client.CDispatch:
    28       connection = None
    29       application = None
    30       SapGuiAuto = None
    31       return
    32 
    33 
    34     #session.findById("wnd[0]").resizeWorkingPane(65, 19, 0)
    35     session.findById("wnd[0]/tbar[0]/okcd").text = "mm03"
    36     session.findById("wnd[0]").sendVKey(0)
    37     session.findById("wnd[0]/usr/ctxtRMMG1-MATNR").Text="9000000000012"
    38     session.findById("wnd[0]").sendVKey(0)
    39     session.findById("wnd[1]/tbar[0]/btn[0]").press()
    40     session.findById("wnd[0]/usr/tabsTABSPR1/tabpSP02").select()
    41 
    42   except:
    43     print(sys.exc_info()[0])
    44 
    45   finally:
    46     session = None
    47     connection = None
    48     application = None
    49     SapGuiAuto = None
    50 
    51 #-Main------------------------------------------------------------------
    52 if __name__ == "__main__":
    53   Main()
    54 
    55 #-End-------------------------------------------------------------------

    PS:1、实际的sap脚本录制过程,会录制大量诸如 setfocus,caretposition,resizeWorkingPane等对程序无实际帮助的语句,为了提升程序执行效率,建议对录制的脚本语句进行适当注释和删除;

    2、本文部分sap script api语句用的VB,需要适当修改才能运用到python中。

  • 相关阅读:
    获取与端点的连接
    判断div内滚动条是否在底部
    MVC的使用!
    格式转换解决存取数据安全问题
    JQuery input file 上传图片
    contenteditable 常用的一些CSS !!
    C# 生成Json类型数据
    生成Excel
    生成验证码
    图片水印
  • 原文地址:https://www.cnblogs.com/new-june/p/NewJune.html
Copyright © 2020-2023  润新知