配置公式计算示例
功能介绍:
用户会配置如下的表,以指定公式:
实现下列功能:
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 = strlen( p_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.
"调用语言转换方法计算结果
DATA: js_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