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

2023-11-10 08:36:49 浏览数 (2)

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.

0 人点赞