SAP接口编程 - PyRFC +Flask+Power Query 实现 SAP 系统科目余额表

得益于 Python 的简洁以及 PyRFC 的加持,SAP 接口编程变得非常简单。本篇介绍如何使用 PyRFC 和 Flask 提供 Restful 服务,程序要实现的目标为:在 Excel 中通过 Restful Service 连接到 SAP系统,在 Excel 中创建科目余额表,报表功能与 SAP 事务码 F.08 类似。选择 Python 而非 用 ABAP 实现 Restful 服务,优点之一是对 SAP 没有侵入性。

需要要用到两个函数:

  • BAPI_GL_ACC_GETLIST : 根据公司代码获取会计科目的清单
  • BAPI_GL_ACC_GETPERIODBALANCES: 获取会计科目在会计年度内各个月份的借方发生额、贷方发生额和余额,与 事务码 FAGLB03 类似

不熟悉两个函数用法的小伙伴,可以在 SAP 系统中用 SE37 来测试,了解函数的参数和返回值。

Restful API

新建一个项目,项目的文件结构如下:

首先,在 sap_system.py 文件中,使用一个 dict 存放连接到 SAP 系统的登录参数:

# 登录到SAP系统的参数
sap_conn_params = {
    
    
    "user": "stone",
    "passwd": "w123456",
    "ashost": "192.168.44.100",
    "sysnr": "00",
    "lang": "EN",
    "client": "001"
}

调用 SAP 函数的代码在 GL.py 文件中编写,PyRFC 自动管理 SAP 连接,不需要手动打开和关闭连接,但应该避免每个函数都创建一个连接对象,我将获取 SAP 连接的代码放在一个单独的函数中。

def get_sap_connection():
    logon_params = sap_system.sap_conn_params
    conn = pyrfc.Connection(**logon_params)

    return conn

调用 BAPI_GL_ACC_GETLIST 返回 科目清单的方法:

class SAPGL(object):
    def __init__(self) -> None:
        self.sap_connection = get_sap_connection()

    # OTHER CODES
        
    def get_gl_acc_list(self, cocd, lang):
        """
        获取会计科目清单
        """

        conn = self.sap_connection

        result = conn.call("BAPI_GL_ACC_GETLIST",
                           COMPANYCODE=cocd,
                           LANGUAGE=lang)
        return result['ACCOUNT_LIST']

调用 BAPI_GL_ACC_GETPERIODBALANCES 函数获取某一个会计科目的在某一年度的借方发生额、贷方发生额和余额:

class SAPGL(object):    
    def get_acc_balances(self, cocd, gl_account, fiscal_year):
        """
        获取会计科目在某一会计年度内按月份的发生额和余额
        """

        conn = self.sap_connection
        result = conn.call("BAPI_GL_ACC_GETPERIODBALANCES",
                           COMPANYCODE=cocd,
                           GLACCT=g_laccount,
                           FISCALYEAR=fiscal_year,
                           CURRENCYTYPE="10")
        return result['ACCOUNT_BALANCES'] 

结合这两个函数,获取所有会计科目的科目余额:

  def get_all_acc_balances(self, cocd, fiscal_year):
       """
       获取所有会计科目在某一会计年度内按月份的发生额和余额
       """

       # results for account balances
       gl_acc_balances = []

       # 获取所有会计科目
       accounts = self.get_gl_acc_list(cocd, '1') # 1表示简体中文

       # 遍历会计科目,获取每一个科目的发生额和余额
       for item in accounts:
           account = item.get('GL_ACCOUNT')
           balances_in_year = self.get_acc_balances(cocd, account, fiscal_year)

           for period_balance in balances_in_year:
               gl_acc_balances.append(period_balance)

       return gl_acc_balances

通过 Flask 提供三个 Web API:

# 会计科目列表
- /acclist/<cocd>

# 会计科目年度发生额和余额
- /accbal/<cocd>/<account>/<year>
- 
# 根据公司代码获取所有会计科目的发生额和余额
- /balances/<cocd>/<year>

代码很直观:

from flask import Flask, request, make_response, jsonify
from SAP.GL import SAPGL

app = Flask(__name__)

@app.route("/")
def index():
    return "index page"

@app.route("/accbal/<cocd>/<account>/<year>")
def get_acc_balances(cocd, account, year):   
    sap_gl = SAPGL();
    acc_balances = sap_gl.get_ac_balances(str.upper(cocd), account, year)

    return jsonify(acc_balances)

@app.route("/acclist/<cocd>")
def get_gl_acc_list(cocd):
    sap_gl = SAPGL();
    gl_list = sap_gl.get_gl_acc_list(str.upper(cocd), '1')

    return jsonify(gl_list)

@app.route('/balances/<cocd>/<year>')
def get_all_acc_balances(cocd, year):  
    sap_gl = SAPGL();
    balances = sap_gl.get_all_acc_balances(str.upper(cocd), year)
    return jsonify(balances)


if __name__ == "__main__":
    app.run()

Power Query 消费 Restful API

接下来,在 Excel 中通过消费这些 Restful Service,首先获取会计科目清单。对 Power Query 不熟悉的小伙伴请参考我之前写的 Power Query 系列。


Power Query 从网站获取的 json 格式数据,转换成表格基本都是下面要演示的几个步骤,首先将列表(List)转换为表:


然后点击表头的展开图标进行展开:

得到如下所示的结果:

高级编辑器中查看对应的脚本:


将查询命名为 acclist,acclist 的结果不需要上载到 Excel 工作表,仅仅保留在 Power Query 中(上载的时候选择仅连接)。

用同样的方法从 URL : http://127.0.0.1:5000/balances/z900/2020 将所有科目的发生额和余额导入到 Power Query 作为第二个查询,将查询命名为 accbalances。因为 python 对 account balances 用的 dict 数据类型,dict 是没有顺序的,所以导入到 Power Query 后字段的顺序并不符合我们的需要,需要在 Power Query 的界面中做调整,并且删除不需要的字段。完成后界面如下:

我们可以看到,会计科目的借方发生额、贷方发生额和余额都有,但没有期初余额。期初余额字段可以在 Power Query 中添加计算字段得到。然后再通过合并查询的功能,从查询 acclist 中关联的方式获得会计科目的描述:

合并查询得到的是一个 table 类型的结构化字段,通过展开操作,选择 LONG TEXT 字段。将完成的查询上载到 Excel 工作表。

查询 accbalances 上载到 Excel 的工作表包含一个会计年度的数据,为了方便查看,将期间字段设为切片器,这样就做好了一个方便查看任意月份的科目余额表。

源码

github - pyrfc

猜你喜欢

转载自blog.csdn.net/stone0823/article/details/109378657
SAP