SAP Scripting Tracker基本使用技巧

SAP Scripting Tracker 是一款实用工具,该工具能记录在 SAP 系统中的操作,并根据所选择的编程语言 (支持 PowerShell, VB.Net ,C#, Python JShell for Java 等多种语言),以脚本的方式进行回放,从而提升工作效率。SAP 曾经提供过基于 COM 技术的 SAP GUI Scripting, 但因为微软从 Windows 7 之后停止了代理(agent, 也称向导)的发布,所以 SAP GUI Scripting 也不能使用,因为 SAP GUI Scripting 依赖该技术 (详见 oss note 1633639)。所以 SAP Scripting Tracker 就成为 SAP GUI Scripting 的一个很好的替代品。

软件下载和安装

SAP Scripting Tracker 是一款自由软件,可以自由使用,软件可以在 https://tracker.stschnell.de 下载。

使用前的环境配置

软件 解压后,在根目录下面有一篇 Tracker.pdf 文档,是对该软件使用的详细说明,可以仔细研读一遍。我根据自己的理解,将最基本的使用要求说明如下:

SAP GUI 前台配置

允许使用脚本

注意,在安装 SAP GUI 的时候,要安装 SAP GUI Scripting,在 SAP GUI 中配置允许使用脚本,但取消消息提示:

设置F1和F4帮助提示框的类型

需要将 F1 和 F4 帮助提示框的样式都改成 dialog,进入系统在菜单 【Help】- 【Settings】进行设置:

SAP服务器端设置

设置 sapgui/user_scripting 参数,将 Current Value 设置为 TRUE:

点击 Display 按钮,进入下一屏幕更改。

SAP 操作的录制和回放

打开 Tracker.exe,通过 SAP GUI 进入 SAP Easy Access 界面。点击 Scripting Tracker 左上角 Scan Scripting objects 按钮 ,可以看到 SAP 登录信息已经被记录,包括 SID, Session,User 等。

切换到 Recorder 页签,点击红色的圆形按钮,开始录制。假设我们想用 F.08 查看总账科目余额的清单。当我们在 SAP 中操作的时候,我们发现软件已经将操作以脚本的方式进行了记录:

操作完成后,点击黄色的按钮,停止记录。此时,我们将 SAP 的界面重新退回到 SAP Easy Access 界面(/n),然后点击 Tracker 最左边的绿色按钮进行运行,可以看到,刚才的操作自动像录像一样回放。

通过脚本实现自动化

Tracker 默认使用的是 Antimalware scan,这个软件的方便之处就是支持多种编程语言,接下来我演示如何通过 Python 来记录脚本。如果想使用 Python 环境,在 PC 上需要安装 Python 解释器,并且需要安装 pywin32 模块。

框架代码 (Frame)

和刚才脚本稍微不同的是,并不是所有语言都是能自动回放的,如果是 C#, Python 这样的语言,Tracker 只记录在 session 中的操作,对于 session 中控件的识别需要有额外的框架代码。这些框架代码 tracker.pdf 已经帮我们写好了,对于 Python 来说,代码在帮助文件的 130 页。


为了方便后续使用,我将 Frame 的代码封装在 SapSession 模块中的 getSession函数中,代码如下:

import sys, win32com.client

def getSession():
    try:
        SapGuiAuto = win32com.client.GetObject("SAPGUI")
        application = SapGuiAuto.GetScriptingEngine
        application.HistoryEnabled = False
        connection = application.Children(0)

        if connection.DisabledByServer == True:
            print("Scripting is disabled by server")
            application = None
            SapGuiAuto = None
            return

        session = connection.Children(0)

        if session.Busy == True:
            print("Session is busy")
            session = None
            connection = None
            application = None
            SapGuiAuto = None
            return

        if session.Info.IsLowSpeedConnection == True:
            print("Connection is low speed")
            session = None
            connection = None
            application = None
            SapGuiAuto = None
            return

        return session
        
    except Exception as e:
        print(e)
        print(sys.exc_info()[0])
    finally:
        application.HistoryEnabled = True
        session = None
        connection = None
        application = None
        SapGuiAuto = None

然后再回到 Tracker.exe,将脚本语言选择为 Python,用刚才同样的方法录制一遍。

在录制的过程中,tracker 已经用 python 语言记录了操作的脚本:


在 Python 编辑器中,新建一个 f08.py 文件,将刚才的代码拷贝到文件中,代码如下:

from SapSession import getSession

def runF08():
    session = getSession()
    session.findById("wnd[0]").maximize()
    session.findById("wnd[0]/tbar[0]/okcd").text = "f.08"
    session.findById("wnd[0]").sendVKey(0)
    session.findById("wnd[0]/usr/ctxtSD_KTOPL-LOW").text = "Z900"
    session.findById("wnd[0]/usr/ctxtSD_BUKRS-LOW").text = "z900"
    session.findById("wnd[0]/usr/txtSD_GJAHR-LOW").text = "2022"
    session.findById("wnd[0]/usr/txtB_MONATE-LOW").text = "01"
    session.findById("wnd[0]/usr/txtB_MONATE-HIGH").text = "01"
    session.findById("wnd[0]/tbar[1]/btn[8]").press()

if __name__ == '__main__':
    runF08()

然后我们就可以以 Python 脚本的方式来运行了。

做一个可以录入会计凭证的脚本

录入的数据放在 excel 中 (importfile.xlsx):

因为只是一个简单的示意,所以字段比较少。有了基础的数据准备之后,我们使用 Python 的 pandas 来读取数据,并转化为由 dict 组成的列表:

def uploadData():
    df = pd.read_excel("importfile.xlsx")
    return df.to_dict("records")

打印的数据如下:

[{'凭证号码': 1, '凭证日期': '2022.09.05', '过账日期': '2022.09.05', '币别': 'CNY', '行': 1, '过
账码': 40, '科目': 10010100, '金额': 700}, {'凭证号码': 1, '凭证日期': '2022.09.05', '过账日期': '2022.09.05', '币别': 'CNY', '行': 2, '过账码': 50, '科目': 10020100, '金额': 700}]

通过录屏的方法生成脚本,然后对脚本稍作改造。为了防止屏幕的错误,在 SapSession 模块中增加一个函数,让屏幕回到 Easy Access 界面

def returnEasyAccess(session):
    session.findById("wnd[0]/tbar[0]/okcd").text = "/n"
    session.findById("wnd[0]").sendVKey(0)

以下是录入会计凭证的完整代码:


from SapSession import getSession, returnEasyAccess
import pandas as pd

def uploadData():
    df = pd.read_excel("importfile.xlsx")
    return df.to_dict("records")

def fiDocumentEntry():
    # 获取数据
    data = uploadData()

    session = getSession()
    returnEasyAccess(session)

    # F-02 事务码
    session.findById("wnd[0]").maximize()
    session.findById("wnd[0]/tbar[0]/okcd").text = "F-02"
    session.findById("wnd[0]").sendVKey(0)

    # 会计凭证抬头
    session.findById("wnd[0]/usr/ctxtBKPF-BLDAT").text = data[0].get("凭证日期")  
    session.findById("wnd[0]/usr/ctxtBKPF-BUKRS").text = "Z900"
    session.findById("wnd[0]/usr/ctxtBKPF-BUDAT").text = data[0].get("过账日期")  
    session.findById("wnd[0]/usr/ctxtBKPF-WAERS").text = data[0].get("币别")

    # 循环录入每一行
    for row in data:
        session.findById("wnd[0]/usr/ctxtRF05A-NEWBS").text = row["过账码"]
        session.findById("wnd[0]/usr/ctxtRF05A-NEWKO").text = row["科目"]
        session.findById("wnd[0]/usr/ctxtRF05A-NEWKO").setFocus()
        session.findById("wnd[0]/usr/ctxtRF05A-NEWKO").caretPosition = 8
        session.findById("wnd[0]").sendVKey(0)  # 回车
        session.findById("wnd[0]/usr/txtBSEG-WRBTR").text = row["金额"]

        if str(row["科目"]) == "10020100": # 银行科目需要起息日
            session.findById("wnd[0]/usr/ctxtBSEG-VALUT").text = row["过账日期"]       

    # 模拟后过账
    session.findById("wnd[0]/mbar/menu[0]/menu[3]").select()
    session.findById("wnd[0]/tbar[0]/btn[11]").press()

if __name__ == '__main__':
    fiDocumentEntry()

参考

Tip: An Effective Way to use SAP GUI Scripting Recording | Community Chat (blueprism.com)

推荐阅读更多精彩内容