matinal:SAP ABAP 如何在程序里实现动态计算公式

1.计算公式拆分出计算变量

代码语言:javascript
复制
*&---------------------------------------------------------------------*
*& Form FRM_SPLIT_FORMEL
*&---------------------------------------------------------------------*
*& text 按照运算符拆分公式
*&---------------------------------------------------------------------*
*&      --> LT_FORMEL_RESULT[]
*&      --> LV_FORMEL
*&---------------------------------------------------------------------*
FORM frm_split_formel  TABLES   et_formel STRUCTURE t418f
                        USING   iv_formel.
  DATA:BEGIN OF lt_formel OCCURS 0,
         formel TYPE char1024,
       END OF lt_formel.
  DATA: lv_formel  TYPE string.

CLEAR: lv_formel.
lv_formel = iv_formel.
"按照+分割
SPLIT lv_formel AT '+' INTO TABLE lt_formel.
CONCATENATE LINES OF lt_formel INTO lv_formel SEPARATED BY space.
"按照-分割
SPLIT lv_formel AT '-' INTO TABLE lt_formel.
CONCATENATE LINES OF lt_formel INTO lv_formel SEPARATED BY space.
"按照分割
SPLIT lv_formel AT '
' INTO TABLE lt_formel.
CONCATENATE LINES OF lt_formel INTO lv_formel SEPARATED BY space.
"按照/分割
SPLIT lv_formel AT '/' INTO TABLE lt_formel.
CONCATENATE LINES OF lt_formel INTO lv_formel SEPARATED BY space.
"按照(分割
SPLIT lv_formel AT '(' INTO TABLE lt_formel.
CONCATENATE LINES OF lt_formel INTO lv_formel SEPARATED BY space.
"按照)分割
SPLIT lv_formel AT ')' INTO TABLE lt_formel.
CONCATENATE LINES OF lt_formel INTO lv_formel SEPARATED BY space.
"按照空格分割
SPLIT lv_formel AT space INTO TABLE lt_formel.

"赋值
LOOP AT lt_formel INTO DATA(ls_formel).
CONDENSE ls_formel-formel NO-GAPS.
IF ls_formel-formel IS NOT INITIAL.
CLEAR: et_formel.
et_formel-formel = ls_formel-formel.
APPEND et_formel.
ENDIF.
ENDLOOP.

ENDFORM.

2.公式计算

代码语言:javascript
复制
&---------------------------------------------------------------------
*& Form FRM_EVAL_FORMULA
&---------------------------------------------------------------------
*& text 公式计算
&---------------------------------------------------------------------
*& --> LV_FORMEL_CHAR
*& <-- CV_BETRG
&---------------------------------------------------------------------
FORM frm_eval_formula USING iv_formel_char
CHANGING cv_betrg.
DATA: lv_formel_char TYPE string,
lv_retcode TYPE sy-subrc,
lv_funcname(30) TYPE c,
lv_message(70) TYPE c,
lv_pos TYPE i,
lv_eval_formula TYPE cha_class_data-sollwert,
lv_eval_formula_out TYPE cha_class_view-sollwert.

TRY.

  • check formula
    CLEAR: lv_formel_char.
    lv_formel_char = iv_formel_char.

    "校验计算公式是否合法
    CLEAR: lv_retcode,lv_funcname,lv_message,lv_pos.
    CALL FUNCTION 'CHECK_FORMULA'
    EXPORTING
    formula = lv_formel_char
    program = sy-repid
    IMPORTING
    subrc = lv_retcode
    funcname = lv_funcname
    message = lv_message
    pos = lv_pos
    EXCEPTIONS
    error_in_formula = 1
    missing_parameter = 2
    OTHERS = 3.
    IF sy-subrc EQ 0 AND lv_retcode EQ 0."formula is ok

  • work out formula
    CLEAR: lv_eval_formula.
    CALL FUNCTION 'EVAL_FORMULA'
    EXPORTING
    formula = lv_formel_char
    program = sy-repid
    IMPORTING
    value = lv_eval_formula
    EXCEPTIONS
    division_by_zero = 1
    exp_error = 2
    formula_table_not_valid = 3
    invalid_expression = 4
    invalid_value = 5
    log_error = 6
    parameter_error = 7
    sqrt_error = 8
    units_not_valid = 9
    missing_parameter = 10
    OTHERS = 11.
    "将科学计数法数据转为正常数据
    CLEAR: lv_eval_formula_out.
    CALL FUNCTION 'QSS0_FLTP_TO_CHAR_CONVERSION'
    EXPORTING
    i_number_of_digits = 2
    i_fltp_value = lv_eval_formula
    i_value_not_initial_flag = 'X'
    i_screen_fieldlength = 16
    IMPORTING
    e_char_field = lv_eval_formula_out.
    IF lv_eval_formula_out IS NOT INITIAL.
    REPLACE ALL OCCURRENCES OF ',' IN lv_eval_formula_out WITH space.
    CONDENSE lv_eval_formula_out NO-GAPS.
    cv_betrg = lv_eval_formula_out.
    ENDIF.
    ENDIF.
    CATCH cx_root INTO DATA(lo_ret).
    ENDTRY.
    ENDFORM.