配置公式计算示例

功能介绍:

用户会配置如下的表,以指定公式:

配置公式计算示例

配置公式计算示例

实现下列功能:

1、单科目:筛选出指定科目的金额并合计

2、区间科目:筛选出指定区间科目的金额并合计

3、计算公式:按照ZCALTEXT中指定的公式去计算,指定的计算项是ZNUM(行号)

这个表的定义如下:

配置公式计算示例

这里是通过一个rfc函数来实现的,函数的代码如下:

FUNCTION zfm_fi_re02.
*"----------------------------------------------------------------------
*"*"Local interface:
*"  IMPORTING
*"     VALUE(IM_RBUKRS) TYPE  BUKRS OPTIONAL
*"     VALUE(IM_RYEAR) TYPE  GJAHR OPTIONAL
*"     VALUE(IM_PRCTR) TYPE  PRCTR OPTIONAL
*"  TABLES
*"      EX_T_002SUM STRUCTURE  ZSFI_002
*"      EX_T_002DETAIL STRUCTURE  ZSFI_002
*"----------------------------------------------------------------------
  TYPES:
  BEGIN OF tp_faglflext,
    rbukrs TYPE faglflext-rbukrs,   "公司代码
    ryear  TYPE faglflext-ryear,    "年度
    prctr  TYPE faglflext-prctr,    "利润中心
    rfarea TYPE faglflext-rfarea,   "功能范围
    racct  TYPE faglflext-racct,    "科目
    hsl01  TYPE faglflext-hsl01,    "1月
    hsl02  TYPE faglflext-hsl02,    "2月
    hsl03  TYPE faglflext-hsl03,    "3月
    hsl04  TYPE faglflext-hsl04,    "4月
    hsl05  TYPE faglflext-hsl05,    "5月
    hsl06  TYPE faglflext-hsl06,    "6月
    hsl07  TYPE faglflext-hsl07,    "7月
    hsl08  TYPE faglflext-hsl08,    "8月
    hsl09  TYPE faglflext-hsl09,    "9月
    hsl10  TYPE faglflext-hsl10,    "10月
    hsl11  TYPE faglflext-hsl11,    "11月
    hsl12  TYPE faglflext-hsl12,    "12月
    END OF tp_faglflext.

  DATA:
        s_rbukrs TYPE RANGE OF faglflext-rbukrs WITH HEADER LINE,
        s_ryear  TYPE RANGE OF faglflext-ryear  WITH HEADER LINE,
        s_prctr  TYPE RANGE OF faglflext-prctr  WITH HEADER LINE,
        s_racct TYPE RANGE OF faglflext-racct WITH HEADER LINE,
        s_rfarea TYPE RANGE OF faglflext-rfarea WITH HEADER LINE,
        it_skat TYPE TABLE OF skat,
        lw_skat TYPE skat,
        wa_str   TYPE ty_str,
        it_data TYPE TABLE OF tp_data,  "按照序号合计金额
        wa_data TYPE tp_data,
        it_faglflext TYPE TABLE OF tp_faglflext,
        wa_faglflext TYPE tp_faglflext,
        it_config TYPE TABLE OF ztfi_002,
        wa_config TYPE ztfi_002.
*-----------------------------------------------------------------------
* 取数
  SELECT FROM ztfi_002 INTO TABLE it_config.
  IF sy-subrc 0.
    LOOP AT it_config INTO wa_config.
      "需要的科目信息
      CLEAR:s_racct.
      CASE wa_config-zcalcu.
        WHEN '1'"单科目
          s_racct-sign 'I'.
          s_racct-option 'EQ'.
          s_racct-low wa_config-racct_f.
          APPEND s_racct.
        WHEN '2'"区间科目
          s_racct-sign 'I'.
          s_racct-option 'BT'.
          s_racct-low wa_config-racct_f.
          s_racct-high wa_config-racct_t.
          APPEND s_racct.
        WHEN OTHERS.
      ENDCASE.
      "全部的功能范围
      IF wa_config-rfarea IS NOT INITIAL.
        s_rfarea-sign 'I'.
        s_rfarea-option 'EQ'.
        s_rfarea-low wa_config-rfarea.
        APPEND s_rfarea.
      ENDIF.
    ENDLOOP.
    CLEAR:s_rfarea.
    s_rfarea-sign 'I'.
    s_rfarea-option 'EQ'.
    s_rfarea-low ''.
    APPEND s_rfarea.
    SORT:s_racct[].
    DELETE ADJACENT DUPLICATES FROM s_racct[] COMPARING ALL FIELDS.
    SORT:s_rfarea[].
    DELETE ADJACENT DUPLICATES FROM s_rfarea[] COMPARING ALL FIELDS.
  ENDIF.
* 将传入参数的条件写到range table
  IF im_rbukrs IS NOT INITIAL.
    s_rbukrs-sign 'I'.
    s_rbukrs-option 'EQ'.
    s_rbukrs-low im_rbukrs.
    APPEND s_rbukrs.
  ENDIF.
  IF im_ryear IS NOT INITIAL.
    s_ryear-sign 'I'.
    s_ryear-option 'EQ'.
    s_ryear-low im_ryear.
    APPEND s_ryear.
  ENDIF.
  IF im_prctr IS NOT INITIAL.
    s_prctr-sign 'I'.
    s_prctr-option 'EQ'.
    s_prctr-low im_prctr.
    APPEND s_prctr.
  ENDIF.

  SELECT rbukrs
         ryear
         prctr
         rfarea
         racct
         hsl01
         hsl02
         hsl03
         hsl04
         hsl05
         hsl06
         hsl07
         hsl08
         hsl09
         hsl10
         hsl11
         hsl12
    INTO TABLE it_faglflext
    FROM faglflext
    WHERE rbukrs IN s_rbukrs
      AND ryear  IN s_ryear
      AND prctr  IN s_prctr
      AND racct IN s_racct
      AND rfarea IN s_rfarea.
  IF sy-subrc <> 0.
  ENDIF.
* 科目描述
  IF s_racct[] IS NOT INITIAL.
    SELECT *
      INTO TABLE it_skat
      FROM skat
      WHERE spras sy-langu
        AND ktopl '1000'
        AND saknr IN s_racct.
  ENDIF.
*-----------------------------------------------------------------------
* 编辑
  SORT:it_config BY zcalcu,
       it_skat by SAKNR.
  LOOP AT it_config INTO wa_config.
    CASE wa_config-zcalcu.
      WHEN '1'"单科目
        LOOP AT it_faglflext INTO wa_faglflext WHERE racct wa_config-racct_f.
          IF wa_config-rfarea IS NOT INITIAL AND wa_faglflext-rfarea <> wa_config-rfarea.
          ELSE.
            "合计
            CLEAR:ex_t_002sum.
            MOVE-CORRESPONDING wa_faglflext TO ex_t_002sum.
            IF wa_config-rfarea IS NOT INITIAL.
              ex_t_002sum-racct wa_faglflext-racct && '(' && wa_config-rfarea && ')'.
            ELSE.
              ex_t_002sum-racct wa_faglflext-racct.
            ENDIF.
            ex_t_002sum-ztext wa_config-ztext.  "表项文本
            ex_t_002sum-znum wa_config-znum.  "序号
            COLLECT ex_t_002sum.
            "数据表
            CLEAR:wa_data.
            MOVE-CORRESPONDING ex_t_002sum TO wa_data.
            wa_data-znum wa_config-znum.
            COLLECT wa_data INTO it_data.
            "明细
            CLEAR:ex_t_002detail.
            MOVE-CORRESPONDING wa_faglflext TO ex_t_002detail.
            ex_t_002detail-racct wa_faglflext-racct.
            CLEAR:lw_skat.
            READ TABLE it_skat INTO lw_skat WITH KEY saknr wa_faglflext-racct BINARY SEARCH.
            IF sy-subrc 0.
              ex_t_002detail-ztext lw_skat-TXT20.  "表项文本
            ENDIF.
            ex_t_002detail-znum wa_config-znum.  "序号
            APPEND ex_t_002detail.
          ENDIF.
        ENDLOOP.
      WHEN '2'"区间科目
        LOOP AT it_faglflext INTO wa_faglflext WHERE racct >= wa_config-racct_f
                                                 AND racct <= wa_config-racct_t.
          IF wa_config-rfarea IS NOT INITIAL AND wa_faglflext-rfarea <> wa_config-rfarea.
          ELSE.
            "合计
            CLEAR:ex_t_002sum.
            MOVE-CORRESPONDING wa_faglflext TO ex_t_002sum.
            IF wa_config-rfarea IS NOT INITIAL.
              ex_t_002sum-racct wa_config-racct_f && '--' && wa_config-racct_t
                                && '(' && wa_config-rfarea && ')'.  "科目
            ELSE.
              ex_t_002sum-racct wa_config-racct_f && '--' && wa_config-racct_t.  "科目
            ENDIF.
            ex_t_002sum-ztext wa_config-ztext.  "表项文本
            ex_t_002sum-znum wa_config-znum.  "序号
            COLLECT ex_t_002sum.
            "数据表
            CLEAR:wa_data.
            MOVE-CORRESPONDING ex_t_002sum TO wa_data.
            wa_data-znum wa_config-znum.
            COLLECT wa_data INTO it_data.
            "明细
            CLEAR:ex_t_002detail.
            MOVE-CORRESPONDING wa_faglflext TO ex_t_002detail.
            ex_t_002detail-racct wa_faglflext-racct.
            CLEAR:lw_skat.
            READ TABLE it_skat INTO lw_skat WITH KEY saknr wa_faglflext-racct BINARY SEARCH.
            IF sy-subrc 0.
              ex_t_002detail-ztext lw_skat-TXT20.  "表项文本
            ENDIF.
            ex_t_002detail-znum wa_config-znum.  "序号
            APPEND ex_t_002detail.
          ENDIF.
        ENDLOOP.
      WHEN 'Z'"计算公式
        "将计算公式中需要用到的项分解出来
        PERFORM frm_split_caltext TABLES gt_str USING wa_config-zcaltext .
        PERFORM frm_js_calcu TABLES it_data USING '01' wa_config-zcaltext CHANGING ex_t_002sum-hsl01.
        PERFORM frm_js_calcu TABLES it_data USING '02' wa_config-zcaltext CHANGING ex_t_002sum-hsl02.
        PERFORM frm_js_calcu TABLES it_data USING '03' wa_config-zcaltext CHANGING ex_t_002sum-hsl03.
        PERFORM frm_js_calcu TABLES it_data USING '04' wa_config-zcaltext CHANGING ex_t_002sum-hsl04.
        PERFORM frm_js_calcu TABLES it_data USING '05' wa_config-zcaltext CHANGING ex_t_002sum-hsl05.
        PERFORM frm_js_calcu TABLES it_data USING '06' wa_config-zcaltext CHANGING ex_t_002sum-hsl06.
        PERFORM frm_js_calcu TABLES it_data USING '07' wa_config-zcaltext CHANGING ex_t_002sum-hsl07.
        PERFORM frm_js_calcu TABLES it_data USING '08' wa_config-zcaltext CHANGING ex_t_002sum-hsl08.
        PERFORM frm_js_calcu TABLES it_data USING '09' wa_config-zcaltext CHANGING ex_t_002sum-hsl09.
        PERFORM frm_js_calcu TABLES it_data USING '10' wa_config-zcaltext CHANGING ex_t_002sum-hsl10.
        PERFORM frm_js_calcu TABLES it_data USING '11' wa_config-zcaltext CHANGING ex_t_002sum-hsl11.
        PERFORM frm_js_calcu TABLES it_data USING '12' wa_config-zcaltext CHANGING ex_t_002sum-hsl12.
        "其他字段赋值
        "合计
        ex_t_002sum-racct wa_config-zcaltext.  "科目
        ex_t_002sum-ztext wa_config-ztext.  "表项文本
        ex_t_002sum-znum wa_config-znum.  "序号
        COLLECT ex_t_002sum.
        "明细
        CLEAR:ex_t_002detail.
        MOVE-CORRESPONDING ex_t_002sum TO ex_t_002detail.
        APPEND ex_t_002detail.
    ENDCASE.
  ENDLOOP.

  SORT:ex_t_002sum[] BY znum,
       ex_t_002detail[] BY znum.

ENDFUNCTION.

                                                                                                  

*----------------------------------------------------------------------*
***INCLUDE LZFI_CORPF01 .
*----------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*&      Form  FRM_SPLIT_CALTEXT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_IT_STR  text
*      -->P_WA_CONFIG_ZCALTEXT  text
*----------------------------------------------------------------------*
FORM frm_split_caltext  TABLES   pt_str LIKE gt_str
                        USING    p_zcaltext.
  DATA:
        lw_str TYPE ty_str.
  DATA:
        l_strlen TYPE i,
        l_plc  TYPE i,
        l_str1 TYPE string,
        l_str2 TYPE string.

  CLEAR:pt_str[].
  l_strlen strlenp_zcaltext ).
  DO l_strlen TIMES.
    l_str1 p_zcaltext+l_plc(1)"第n位字符
    CASE l_str1.
      WHEN '+' OR '-' OR '*' OR '/' OR '(' OR ')'.
        lw_str-str l_str2.
        APPEND lw_str TO pt_str.
        CLEAR:l_str2.
      WHEN OTHERS.
        l_str2 l_str2 && l_str1.
    ENDCASE.
    l_plc l_plc + 1.
  ENDDO.
  lw_str-str l_str2.
  APPEND lw_str TO pt_str.

  SORT pt_str.
  DELETE ADJACENT DUPLICATES FROM pt_str COMPARING ALL FIELDS.
ENDFORM.                    " FRM_SPLIT_CALTEXT
*&---------------------------------------------------------------------*
*&      Form  FRM_JS_CALCU
*&---------------------------------------------------------------------*
*       计算
*----------------------------------------------------------------------*
*      -->PU_HSL          "计算列数
*      -->PU_ZCALTEXT     "计算公式
*      <--PC_HSL          "传出结果
*----------------------------------------------------------------------*
FORM frm_js_calcu  TABLES   pt_data LIKE gt_data
                   USING    pu_hsl
                            pu_zcaltext
                   CHANGING pc_hsl.
  DATA:lw_data TYPE tp_data,
        lw_str TYPE ty_str.
  DATA:lv_hsl TYPE string,
       lv_var TYPE string,
       lv_source TYPE string,
       return_value TYPE string.

  DATA:lv_field TYPE string.
  FIELD-SYMBOLS:<f_val> TYPE any,
                <fs>.
  lv_field 'HSL' && pu_hsl"当前计算的字段名称

  "读取每一项对应的数值并拼接成js定义语句
  SORT:pt_data BY znum.
  LOOP AT gt_str INTO lw_str.
    CLEAR:lw_data.
    READ TABLE pt_data INTO lw_data WITH KEY znum lw_str-str BINARY SEARCH.
    IF sy-subrc 0.
      "指针分配当前列
      ASSIGN lw_data TO <fs>.
      ASSIGN COMPONENT  lv_field OF STRUCTURE <fs> TO <f_val>.
      lv_hsl <f_val>.
      CONDENSE lv_hsl.

      IF lv_hsl CS '-'.
        SHIFT lv_hsl LEFT DELETING LEADING '-'.
        SHIFT lv_hsl RIGHT DELETING TRAILING '-'.
        lv_hsl '-' && lv_hsl.
        lv_var lw_str-str"变量名
        CONCATENATE lv_source 'var' lv_var '=' lv_hsl INTO lv_source SEPARATED BY space.
        CONCATENATE lv_source ';' INTO lv_source.
      ELSE.
        lv_var lw_str-str"变量名
        CONCATENATE lv_source 'var' lv_var '=' lv_hsl INTO lv_source SEPARATED BY space.
        CONCATENATE lv_source ';' INTO lv_source.
      ENDIF.
    ELSE.
      lv_var lw_str-str"变量名
      CONCATENATE lv_source 'var' lv_var '= 0.00' INTO lv_source SEPARATED BY space.
      CONCATENATE lv_source ';' INTO lv_source.
    ENDIF.
  ENDLOOP.

  "定义结果变量并拼接计算语句
  CONCATENATE lv_source 'var js_result = 0.00;' INTO lv_source SEPARATED BY space.
  CONCATENATE lv_source 'js_result' '=' pu_zcaltext ';' INTO lv_source SEPARATED BY space.

  "调用语言转换方法计算结果
  DATAjs_processor TYPE REF TO cl_java_script.
  js_processor cl_java_script=>create).
  TRY.
      CALL METHOD js_processor->evaluate
        EXPORTING
          java_script lv_source
        RECEIVING
          result      return_value.
      pc_hsl =  return_value.
    CATCH cx_dynamic_check .
  ENDTRY.
ENDFORM.                    " FRM_JS_CALCU