【SAP FICO】财务三大报表_2-进阶(利润表-数据表结构、取数逻辑)

系列文章目录


前言

承接上篇财务三大报表_2-进阶(资产负债表-数据表结构、取数逻辑),本篇继续详细介绍利润表的相关数据表结构、取数逻辑等(事实上,两个报表的逻辑、处理顺序都是一致的)
写的不周到的地方还请大家批评指正,互相学习


一、利润表

TCODE:ZFIR003
选择公司代码、会计年度、期间,即可看到该公司在某一会计年度某一期间的详细利润表,如下:
在这里插入图片描述
可以清楚看到行项目包括:
营业收入、营业成本、税金附加、销管研财费用、信用减值损失、资产减值损失、公允价值变动收益、投资收益、其他收益、资产处置收益、营业利润、营业外收入、营业外支出、利润总额、所得税费用、净利润

二、利润表的数据表结构

1、核心数据表

同资产负债表一样,

  • faglflext:是SAP中的通用财务数据表,用于存储总账科目的财务数据,这里主要用于获取每个科目的发生额
    关键字段包括:科目代码racct,借贷方向drcrk,期末数和年初数的余额hsl01、hslvt
  • zfit009:是自定义的表,是财务三大报表存储表
    关键字段包括:公司代码bukrs,报表类型ztype(IS是利润表),列标识zcolumn(用于区分不同的列),行标识zrow,借方标识和贷方标识zjfbs、zdfbs,计算公式formula,正负反转reversal

2、内部数据结构

  • 三个结构体类型:typ_fag,typ_dmbtr, typ_dmbtr1
  • gt_fag和gs_fag:分别用于存储从faglflext表中检索的财务数据的表和内表记录。
    gt_fit003和gs_fit003:用于存储从配置表zfit009中检索的配置数据,这些数据定义了利润表的格式和计算方式。
    gt_dmbtr和gs_dmbtr/gt_dmbtr1和gs_dmbtr1:用于存储处理后的利润表数据。
    vid1、list1、value1用于选择屏幕的下拉框数据处理。
    gs_fieldcatalog和gt_fieldcatalog:用于定义ALV表格的列属性,如列名、数据类型、对齐方式等。
    gt_alv_sort:用于定义ALV表格的排序规则。
    gt_header和gs_header:用于定义ALV表格的标题或页眉信息。

三、利润表的取数逻辑

1、获取用户输入

通过选择屏幕获取用户输入的公司代码(p_bukrs)和会计年度(p_ryear)和期间( p_rpmax)

2、构建查询条件并获取数据

根据用户输入,构建查询faglflext表的条件。同时,根据配置表zfit009中的信息,确定需要获取哪些科目的数据
使用构建的查询条件,从faglflext表中获取对应期间、科目和功能范围的数据。
事实上就是资产负债表中写到的:获取财务数据和配置数据

3、数据处理

zfit009表字段如下:
TCODE:SE11里查
在这里插入图片描述
配置数据维护如下:
在这里插入图片描述

  • 数据获取
    在START-OF-SELECTION事件中, 程序首先执行权限校验(PERFORM CHECK_AUTHORITY),然后调用sub_get_data来获取数据。(这部分数据主要来源于faglflext表,通过拼接查询条件来获取指定公司代(rbukrs)、年份(ryear)、期间(rpmax)条件下的发生额数据。)
    核心代码如下:
FORM check_authority .

  AUTHORITY-CHECK OBJECT 'F_BKPF_BUK'
    ID 'BUKRS' FIELD p_bukrs
    ID 'ACTVT' FIELD '03'.
  IF sy-subrc <> 0.
    MESSAGE '没有查看该公司的权限' TYPE 'S' DISPLAY LIKE 'E'.
    LEAVE LIST-PROCESSING .
  ENDIF.

ENDFORM
FORM sub_get_data .

  DATA: tp_cond  TYPE string,
        tp_field TYPE c LENGTH 5.
  DATA  tp_perio TYPE char3 .
  DATA: tp_monat TYPE c LENGTH 2 VALUE '00'.

  CLEAR: tp_perio .
  IF p_rpmax = 12 .
    tp_perio = p_rpmax + 4 .
  ELSE .
    tp_perio = p_rpmax .
  ENDIF.

  CLEAR: tp_cond,tp_monat .     "整合查询条件
  DO tp_perio TIMES.
    tp_monat = tp_monat + 1 .
    SHIFT tp_monat RIGHT DELETING TRAILING space .
    OVERLAY tp_monat WITH '00' .
    CLEAR: tp_field .
    CONCATENATE 'HSL' tp_monat INTO  tp_field .
    CONCATENATE tp_cond tp_field INTO tp_cond SEPARATED BY space .
  ENDDO.
  CONCATENATE 'RBUKRS' 'RYEAR' 'RPMAX' 'RACCT' 'RTCUR' 'DRCRK' 'RFAREA' 'HSLVT'
  tp_cond 'RCNTR' INTO tp_cond SEPARATED BY space .

  SELECT (tp_cond)   "查询发生额数据
  INTO CORRESPONDING FIELDS OF TABLE gt_fag
  FROM faglflext
  WHERE rbukrs = p_bukrs
  AND ( ryear  = p_ryear OR ryear = tp_year )
  AND rldnr = '0L'
  AND  prctr IN s_prctr.

****  DELETE gt_fag WHERE racct BETWEEN '0066010003' AND '0066019999' AND rcntr = '0000300031'.

  SELECT *
  INTO CORRESPONDING FIELDS OF TABLE gt_fit003
  FROM zfit009
  WHERE ztype = 'IS'
  AND   langu = sy-langu .  "只获取IS类

  SORT gt_fit003 BY ztype zcolumn zrow .

ENDFORM.
  • 数据汇总和计算
    获取数据后,程序进入sub_deal_data处理(根据gt_fit003中的信息对获取到的发生额数据进行汇总和计算)

    • 非公式项汇总:程序会根据配置表中的科目号、起始范围等,对发生额进行分类汇总;该自开发程序中使用了RNGES对象来定义科目号和起始范围的选择条件,通过LOOP AT GT_FAG循环遍历发生额数据,使用ADD或collect操作将数据累加到对应的报表项中。nmhsl表示当期,nyhsl表示本年累计
FORM sub_deal_data .

  FIELD-SYMBOLS: <hsl> TYPE any .
  RANGES: r_saknr FOR faglflext-racct.   "科目号
  RANGES: r_rfarea FOR zfit009-frfarea . "起始范围
  RANGES: r_drcrk FOR faglflext-drcrk .

  CLEAR: gt_dmbtr[],it_zfit13,it_zfit13[].
  LOOP AT gt_fit003 ASSIGNING <gs_fit003> ."根据配置表数据  把取出的发生额加以汇总  得到报表项数据

    CLEAR: gs_dmbtr .
    MOVE-CORRESPONDING <gs_fit003> TO gs_dmbtr .

    IF <gs_fit003>-formula = '' .          "不是通过公式计算
      IF ( ( <gs_fit003>-fsaknr <> '' OR <gs_fit003>-tsaknr <> '' ) AND
      ( <gs_fit003>-zjfbs <> '' OR <gs_fit003>-zdfbs <> '' ) )  .
      *---组织整合条件
*-----------------------------------------------------------------------------
        CLEAR:r_saknr[],r_drcrk[],r_rfarea[] .   "资产负债表没有功能范围
*-----------------------------------------------------------------------*“科目范围
        CLEAR: r_saknr .
        IF <gs_fit003>-fsaknr <> '' AND <gs_fit003>-tsaknr = '' .
          r_saknr-sign = 'I'.
          r_saknr-option = 'EQ'.
          r_saknr-low = <gs_fit003>-fsaknr .
          APPEND r_saknr .
        ELSEIF <gs_fit003>-fsaknr = '' AND <gs_fit003>-tsaknr <> '' .
          r_saknr-sign = 'I' .
          r_saknr-option = 'EQ'.
          r_saknr-low = <gs_fit003>-tsaknr .
          APPEND r_saknr .
        ELSEIF <gs_fit003>-fsaknr <> '' AND <gs_fit003>-tsaknr <> '' .
          r_saknr-sign = 'I' .
          r_saknr-option = 'BT'.
          r_saknr-low = <gs_fit003>-fsaknr .
          r_saknr-high = <gs_fit003>-tsaknr.
          APPEND r_saknr .
        ENDIF.
*-----------------------------------------------------------------------*"功能范围
        CLEAR: r_rfarea.
        IF <gs_fit003>-frfarea <> '' AND <gs_fit003>-trfarea = '' .
          r_rfarea(3) = 'IEQ'.
          r_rfarea-low = <gs_fit003>-frfarea .
          APPEND r_rfarea .
        ELSEIF <gs_fit003>-frfarea = '' AND <gs_fit003>-trfarea <> '' .
          r_rfarea(3) = 'IEQ' .
          r_rfarea-low = <gs_fit003>-trfarea .
          APPEND r_rfarea .
        ELSEIF <gs_fit003>-frfarea <> '' AND <gs_fit003>-trfarea <> '' .
          r_rfarea-sign = 'I' .
          r_rfarea-option = 'BT'.
          r_rfarea-low = <gs_fit003>-frfarea .
          r_rfarea-high = <gs_fit003>-trfarea.
          APPEND r_rfarea .
        ENDIF.
*-----------------------------------------------------------------------*”借贷标识
        CLEAR:r_drcrk .
        IF <gs_fit003>-zjfbs = 'X' .
          r_drcrk(3) = 'IEQ' .
          r_drcrk-low = 'S' .
          APPEND r_drcrk .
        ENDIF .
        IF <gs_fit003>-zdfbs = 'X'.
          r_drcrk(3) = 'IEQ' .
          r_drcrk-low = 'H' .
          APPEND r_drcrk .
        ENDIF.

*-----------------------------------------------------------------------*
        IF p_ryear = '2017' AND p_rpmax LT '6'.


        ELSE.
          IF p_ryear = '2017' AND p_rpmax >= '6'.

          ENDIF.
          LOOP AT gt_fag INTO gs_fag WHERE racct IN r_saknr[] AND
                                           rfarea IN r_rfarea[] AND drcrk IN r_drcrk[] .
            IF gs_fag-ryear = p_ryear .  "当年
              DO 16 TIMES.
                ASSIGN COMPONENT ( sy-index + 8 ) OF STRUCTURE gs_fag TO <hsl> .
                CHECK sy-subrc EQ 0 .
                IF p_rpmax = 12 .
                  IF sy-index >= 12 .
                    ADD <hsl> TO gs_dmbtr-nmhsl .  "当期
                  ENDIF.
                ELSE .
                  IF sy-index = p_rpmax .
                    ADD <hsl> TO gs_dmbtr-nmhsl ."当期
                  ENDIF.
                ENDIF.
                ADD <hsl> TO gs_dmbtr-nyhsl .  "当年累计
              ENDDO.
            ELSE .  "上年
              DO 16 TIMES.
                ASSIGN COMPONENT ( sy-index + 8 ) OF STRUCTURE gs_fag TO <hsl> .
                CHECK sy-subrc EQ 0 .
                IF  p_rpmax = 12 .
                  IF sy-index >= 12 .
                    ADD <hsl> TO gs_dmbtr-lmhsl . "上年同期
                  ENDIF.
                ELSE .
                  IF sy-index = p_rpmax .
                    ADD <hsl> TO gs_dmbtr-lmhsl ."上年同期
                  ENDIF.
                ENDIF.
                ADD <hsl> TO gs_dmbtr-lyhsl . "上年累计
              ENDDO.
            ENDIF.
          ENDLOOP.

        ENDIF.
  • 公式项计算:程序调用caculate_results子例程进行计算,根据配置表中的公式对已有数据进行计算,并更新报表项的值。lmhsl表示上年同期,lyhsl表示上年累计
    核心代码如下:(不完整)
  formula_len = strlen( p_formula ) .   "计算公式长度

  CLEAR:tp_lmhsl,tp_lyhsl,tp_nmhsl,tp_nyhsl,tp_char,l_row .

  CONDENSE p_formula NO-GAPS .
  DO formula_len TIMES.

    last = sy-index - 1 .
    tp_char = p_formula+last(1) .
    IF tp_char CO '0123456789' .             "为数字
      CONCATENATE l_row tp_char INTO l_row .
      CLEAR: tp_char .
    ENDIF .
    IF tp_char CO '+-*/' OR sy-index = formula_len ."为计算符号

      SHIFT l_row RIGHT DELETING TRAILING '' .
      OVERLAY l_row WITH '000' .
      CLEAR: wa_dmbtr .
      READ TABLE gt_dmbtr INTO wa_dmbtr WITH KEY zrow = l_row .
*      IF sy-subrc = 0 .

      CLEAR:tp_value .
      tp_value = wa_dmbtr-lmhsl .
      CALL FUNCTION 'CLOI_PUT_SIGN_IN_FRONT'   "负数负号前置
        CHANGING
          value = tp_value.
      CONCATENATE tp_lmhsl '(' tp_value ')'  tp_char INTO tp_lmhsl .

      CLEAR:tp_value .
      tp_value = wa_dmbtr-lyhsl .
      CALL FUNCTION 'CLOI_PUT_SIGN_IN_FRONT'   "负数负号前置
        CHANGING
          value = tp_value.
      CONCATENATE tp_lyhsl '(' tp_value ')'  tp_char INTO tp_lyhsl .

      CLEAR:tp_value .
      tp_value = wa_dmbtr-nmhsl .
      CALL FUNCTION 'CLOI_PUT_SIGN_IN_FRONT'   "负数负号前置
        CHANGING
          value = tp_value.
      CONCATENATE tp_nmhsl '(' tp_value ')'  tp_char INTO tp_nmhsl .

      CLEAR:tp_value .
      tp_value = wa_dmbtr-nyhsl .
      CALL FUNCTION 'CLOI_PUT_SIGN_IN_FRONT'   "负数负号前置
        CHANGING
          value = tp_value.
      CONCATENATE tp_nyhsl '(' tp_value ')'  tp_char INTO tp_nyhsl .

*      ENDIF.
      CLEAR: l_row .
    ENDIF.
  ENDDO.

  IF tp_lmhsl <> ''  .
    CLEAR: l_value .
    CALL FUNCTION 'CHECK_FORMULA'
      EXPORTING
        formula = tp_lmhsl.
    IF sy-subrc = 0.
      CALL FUNCTION 'EVAL_FORMULA'
        EXPORTING
          formula = tp_lmhsl
        IMPORTING
          value   = l_value.
      p_lmhsl = l_value .
    ENDIF.
  ENDIF.

  IF tp_lyhsl <> ''  .
    CLEAR: l_value .
    CALL FUNCTION 'CHECK_FORMULA'
      EXPORTING
        formula = tp_lyhsl.
    IF sy-subrc = 0.
      CALL FUNCTION 'EVAL_FORMULA'
        EXPORTING
          formula = tp_lyhsl
        IMPORTING
          value   = l_value.
      p_lyhsl = l_value .
    ENDIF.
  ENDIF.

  IF tp_nmhsl <> ''  .
    CLEAR: l_value .
    CALL FUNCTION 'CHECK_FORMULA'
      EXPORTING
        formula = tp_nmhsl.
    IF sy-subrc = 0.
      CALL FUNCTION 'EVAL_FORMULA'
        EXPORTING
          formula = tp_nmhsl
        IMPORTING
          value   = l_value.
      p_nmhsl = l_value .
    ENDIF.
  ENDIF.

  IF tp_nyhsl <> '' .
    CLEAR: l_value .
    CALL FUNCTION 'CHECK_FORMULA'
      EXPORTING
        formula = tp_nyhsl.
    IF sy-subrc = 0.
      CALL FUNCTION 'EVAL_FORMULA'
        EXPORTING
          formula = tp_nyhsl
        IMPORTING
          value   = l_value.
      p_nyhsl = l_value .
    ENDIF.
  ENDIF.
  • 数据计算和调整
    在sub_deal_data的后续处理中,程序还会对报表项数据进行一些计算和调整----再次计算公式项:为了避免一些公式取后面值失败的情况,程序会再次遍历表gt_fit003,对公式计算项进行二次计算,这次计算会覆盖之前的结果

4、数据存储和报表生成

汇总和计算后,报表项数据存储在表gt_dmbtr中,后续会根据该表生成ALV报表,或者导出到excel中


总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值