abap数值公式计算函数

10842258_200907181625001.jpg

10842258_200907181625002.jpg

10842258_200907181625003.jpg

Source code:

FUNCTION zformel_compute.
*"----------------------------------------------------------------------
*"*"Local interface:
*"  IMPORTING
*"     VALUE(FORMEL) TYPE  CHAR1024
*"  EXPORTING
*"     REFERENCE(DATA) TYPE  STRING
*"  EXCEPTIONS
*"      FORMEL_ERROR
*"----------------------------------------------------------------------
*  TYPES: formel(255).
  DATA: result TYPE TABLE OF formel WITH HEADER LINE.
  DATA: i TYPE i,ch,line TYPE i,m TYPE i.
  DATA:top_operator TYPE formel,ture,theta TYPE formel,a TYPE formel,b TYPE formel,xtheta TYPE formel.


  CLEAR:lt_vs[],lt_optr[],lt_opdn[].
  PERFORM. init.

  CONDENSE formel NO-GAPS.

  IF formel IS INITIAL.
    EXIT.
  ENDIF.


* 判断是否为数字表达式
  DATA:tmp_formel TYPE formel,p TYPE p DECIMALS 6.
  tmp_formel = formel.
  SPLIT tmp_formel AT '+' INTO TABLE result.
  CONCATENATE LINES OF result INTO tmp_formel SEPARATED BY space.
  SPLIT tmp_formel AT '-' INTO TABLE result.
  CONCATENATE LINES OF result INTO tmp_formel SEPARATED BY space.
  SPLIT tmp_formel AT '*' INTO TABLE result.
  CONCATENATE LINES OF result INTO tmp_formel SEPARATED BY space.
  SPLIT tmp_formel AT '/' INTO TABLE result.
  CONCATENATE LINES OF result INTO tmp_formel SEPARATED BY space.
  SPLIT tmp_formel AT '(' INTO TABLE result.
  CONCATENATE LINES OF result INTO tmp_formel SEPARATED BY space.
  SPLIT tmp_formel AT ')' INTO TABLE result.
  CONCATENATE LINES OF result INTO tmp_formel SEPARATED BY space.
  SPLIT tmp_formel AT space INTO TABLE result.

  LOOP AT result.

    CATCH SYSTEM-EXCEPTIONS arithmetic_errors = 1
                            THERS = 2.
      p = result.

    ENDCATCH.
    IF sy-subrc <> 0.
      RAISE formel_error.
    ENDIF.

*      CATCH cx_sy_conversion_no_number.

  ENDLOOP.

  CLEAR result[].

*


  i = STRLEN( formel ) - 1.
  ch = formel+i(1).

  SPLIT formel AT '+' INTO TABLE result.
  CONCATENATE LINES OF result INTO formel SEPARATED BY ' + '.

  SPLIT formel AT '-' INTO TABLE result.
  CONCATENATE LINES OF result INTO formel SEPARATED BY ' - '.

  SPLIT formel AT '*' INTO TABLE result.
  CONCATENATE LINES OF result INTO formel SEPARATED BY ' * '.

  SPLIT formel AT '/' INTO TABLE result.
  CONCATENATE LINES OF result INTO formel SEPARATED BY ' / '.

  SPLIT formel AT '(' INTO TABLE result.
  CONCATENATE LINES OF result INTO formel SEPARATED BY ' ( '.

  SPLIT formel AT ')' INTO TABLE result.
  CONCATENATE LINES OF result INTO formel SEPARATED BY ' ) '.

  IF ch = ')'.
    CONCATENATE formel ' )' INTO formel.
  ENDIF.
*  REPLACE - the '' charactor is ignored

*  REPLACE ALL OCCURRENCES OF '+' IN formel WITH ' + '.
*  REPLACE ALL OCCURRENCES OF '-' IN formel WITH ' - '.
*  REPLACE ALL OCCURRENCES OF '*' IN formel WITH ' * '.
*  REPLACE ALL OCCURRENCES OF '/' IN formel WITH ' / '.
  CONCATENATE formel ' #' INTO formel.
  FIND '#' IN formel.
  IF sy-subrc <> 0.
* formel长度不够
    RAISE formel_error.
  ENDIF.
  SPLIT formel AT space INTO TABLE result.
  LOOP AT result.
    IF result = ''.
      DELETE result.
      CONTINUE.
    ELSE.
      CONDENSE result NO-GAPS.
      MODIFY result.
    ENDIF.
  ENDLOOP.
*  DESCRIBE TABLE result LINES line.

  m = 1.
  READ TABLE result INDEX m.
  PERFORM. gettop TABLES lt_optr CHANGING top_operator.

  WHILE result <> '#' OR top_operator <> '#'.
    PERFORM. is_operator USING result CHANGING ture.
    IF ture <> 'X'.
      PERFORM. push_opdn TABLES lt_opdn USING result.
      m = m + 1.
      READ TABLE result INDEX m.
    ELSE.
      PERFORM. gettop TABLES lt_optr CHANGING top_operator.
      READ TABLE lt_vs WITH KEY op1 = top_operator op2 = result.
      IF sy-subrc = 0.
        CASE lt_vs-vs.
          WHEN '>'.

            PERFORM. pop_optr TABLES lt_optr CHANGING theta.
            PERFORM. pop_opdn TABLES lt_opdn CHANGING b.
            PERFORM. pop_opdn TABLES lt_opdn CHANGING a.
            PERFORM. oprate TABLES lt_opdn USING a b theta.

          WHEN '            PERFORM. push_optr TABLES lt_optr USING result .
            m = m + 1.
            READ  TABLE result INDEX m.
          WHEN '='.
            PERFORM. pop_optr TABLES lt_optr CHANGING xtheta.
            m = m + 1.
            READ  TABLE result INDEX m.
          WHEN OTHERS.
            RAISE formel_error.
        ENDCASE.
      ENDIF.
*      CLEAR top_operator.
    ENDIF.
    PERFORM. gettop TABLES lt_optr CHANGING top_operator.

  ENDWHILE.

  READ TABLE lt_opdn INDEX 1.
  data = lt_opdn-opdn.

*  WRITE data.
ENDFUNCTION.

Global Data:

FUNCTION-POOL zgroup.                         "MESSAGE-ID ..
TYPES:formel(1024).

* 规则
TYPES:BEGIN OF vs,
        op1,
        op2,
        vs,
      END OF vs.

DATA lt_vs TYPE TABLE OF vs WITH HEADER LINE.


* 运算符
TYPES:BEGIN OF wc,
        optr,
      END OF wc.
DATA lt_optr TYPE TABLE OF wc WITH HEADER LINE.


* 运算数
TYPES:BEGIN OF wd,
        opdn TYPE formel,
      END OF wd.
DATA lt_opdn TYPE TABLE OF wd WITH HEADER LINE.

Form:

*&---------------------------------------------------------------------*
*&      Form  INIT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  --&gt  p1        text
*  *----------------------------------------------------------------------*
FORM. init .

* init lt_optr
  lt_optr = '#'.
  APPEND lt_optr.

* +
  lt_vs-op1 = '+'.
  lt_vs-op2 = '+'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = '+'.
  lt_vs-op2 = '-'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = '+'.
  lt_vs-op2 = '*'.
  lt_vs-vs  = '  APPEND lt_vs.

  lt_vs-op1 = '+'.
  lt_vs-op2 = '/'.
  lt_vs-vs  = '  APPEND lt_vs.

  lt_vs-op1 = '+'.
  lt_vs-op2 = '('.
  lt_vs-vs  = '  APPEND lt_vs.

  lt_vs-op1 = '+'.
  lt_vs-op2 = ')'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = '+'.
  lt_vs-op2 = '#'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

* -
  lt_vs-op1 = '-'.
  lt_vs-op2 = '+'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = '-'.
  lt_vs-op2 = '-'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = '-'.
  lt_vs-op2 = '*'.
  lt_vs-vs  = '  APPEND lt_vs.

  lt_vs-op1 = '-'.
  lt_vs-op2 = '/'.
  lt_vs-vs  = '  APPEND lt_vs.

  lt_vs-op1 = '-'.
  lt_vs-op2 = '('.
  lt_vs-vs  = '  APPEND lt_vs.

  lt_vs-op1 = '-'.
  lt_vs-op2 = ')'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = '-'.
  lt_vs-op2 = '#'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

* *
  lt_vs-op1 = '*'.
  lt_vs-op2 = '+'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = '*'.
  lt_vs-op2 = '-'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = '*'.
  lt_vs-op2 = '*'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = '*'.
  lt_vs-op2 = '/'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = '*'.
  lt_vs-op2 = '('.
  lt_vs-vs  = '  APPEND lt_vs.

  lt_vs-op1 = '*'.
  lt_vs-op2 = ')'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = '*'.
  lt_vs-op2 = '#'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

* /
  lt_vs-op1 = '/'.
  lt_vs-op2 = '+'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = '/'.
  lt_vs-op2 = '-'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = '/'.
  lt_vs-op2 = '*'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = '/'.
  lt_vs-op2 = '/'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = '/'.
  lt_vs-op2 = '('.
  lt_vs-vs  = '  APPEND lt_vs.

  lt_vs-op1 = '/'.
  lt_vs-op2 = ')'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = '/'.
  lt_vs-op2 = '#'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

* (
  lt_vs-op1 = '('.
  lt_vs-op2 = '+'.
  lt_vs-vs  = '  APPEND lt_vs.

  lt_vs-op1 = '('.
  lt_vs-op2 = '-'.
  lt_vs-vs  = '  APPEND lt_vs.

  lt_vs-op1 = '('.
  lt_vs-op2 = '*'.
  lt_vs-vs  = '  APPEND lt_vs.

  lt_vs-op1 = '('.
  lt_vs-op2 = '/'.
  lt_vs-vs  = '  APPEND lt_vs.

  lt_vs-op1 = '('.
  lt_vs-op2 = '('.
  lt_vs-vs  = '  APPEND lt_vs.

  lt_vs-op1 = '('.
  lt_vs-op2 = ')'.
  lt_vs-vs  = '='.
  APPEND lt_vs.

  lt_vs-op1 = '('.
  lt_vs-op2 = '#'.
  lt_vs-vs  = ''.
  APPEND lt_vs.

* )
  lt_vs-op1 = ')'.
  lt_vs-op2 = '+'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = ')'.
  lt_vs-op2 = '-'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = ')'.
  lt_vs-op2 = '*'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = ')'.
  lt_vs-op2 = '/'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = ')'.
  lt_vs-op2 = '('.
  lt_vs-vs  = ''.
  APPEND lt_vs.

  lt_vs-op1 = ')'.
  lt_vs-op2 = ')'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

  lt_vs-op1 = ')'.
  lt_vs-op2 = '#'.
  lt_vs-vs  = '>'.
  APPEND lt_vs.

* #
  lt_vs-op1 = '#'.
  lt_vs-op2 = '+'.
  lt_vs-vs  = '  APPEND lt_vs.

  lt_vs-op1 = '#'.
  lt_vs-op2 = '-'.
  lt_vs-vs  = '  APPEND lt_vs.

  lt_vs-op1 = '#'.
  lt_vs-op2 = '*'.
  lt_vs-vs  = '  APPEND lt_vs.

  lt_vs-op1 = '#'.
  lt_vs-op2 = '/'.
  lt_vs-vs  = '  APPEND lt_vs.

  lt_vs-op1 = '#'.
  lt_vs-op2 = '('.
  lt_vs-vs  = '  APPEND lt_vs.

  lt_vs-op1 = '#'.
  lt_vs-op2 = ')'.
  lt_vs-vs  = ''.
  APPEND lt_vs.

  lt_vs-op1 = '#'.
  lt_vs-op2 = '#'.
  lt_vs-vs  = '='.
  APPEND lt_vs.

ENDFORM.                    " INIT
*&---------------------------------------------------------------------*
*&      Form  GETTOP
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      --&gtP_LT_OPTR  text
*      *----------------------------------------------------------------------*
FORM. gettop  TABLES   p_lt_optr
             CHANGING p_top_operator TYPE formel.
  DATA line TYPE i.
  DATA wa TYPE wc.
  CLEAR p_top_operator.
  DESCRIBE TABLE p_lt_optr LINES line.
  READ TABLE p_lt_optr INDEX line INTO wa.
  IF sy-subrc = 0.
    p_top_operator = wa-optr.
  ENDIF.

ENDFORM.                    " GETTOP
*&---------------------------------------------------------------------*
*&      Form  IS_OPERATOR
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      --&gtP_RESULT  text
*      *----------------------------------------------------------------------*
FORM. is_operator  USING    p_result
                  CHANGING p_ture.
  CLEAR p_ture.
  IF p_result = '+' OR p_result = '-' OR p_result = '*' OR p_result = '/' OR p_result = '(' OR p_result = ')' OR p_result = '#'.
    p_ture = 'X'.
  ELSE.
    CLEAR p_ture.
  ENDIF.
ENDFORM.                    " IS_OPERATOR

*&---------------------------------------------------------------------*
*&      Form  PUSH_OPTR
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      --&gtP_LT_OPTR  text
*      --&gtP_RESULT  text
*----------------------------------------------------------------------*
FORM. push_optr  TABLES   p_lt_optr
                USING    p_result  TYPE formel.
  DATA wa TYPE wc.
  wa-optr = p_result.
  APPEND wa TO p_lt_optr.


ENDFORM.                    " PUSH_OPTR
*&---------------------------------------------------------------------*
*&      Form  PUSH_OPDN
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      --&gtP_LT_OPDN  text
*      --&gtP_RESULT  text
*----------------------------------------------------------------------*
FORM. push_opdn  TABLES   p_lt_opdn
                USING    p_result  TYPE formel.
  DATA wa TYPE wd.
  wa-opdn = p_result.
  APPEND wa TO p_lt_opdn.

ENDFORM.                    " PUSH_OPDN
*&---------------------------------------------------------------------*
*&      Form  POP_OPTR
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      --&gtP_LT_OPTR  text
*      *----------------------------------------------------------------------*
FORM. pop_optr  TABLES   p_lt_optr
               CHANGING p_theta  TYPE formel.
  CLEAR p_theta.
  DATA line TYPE i.
  DATA wa TYPE wc.
  DESCRIBE TABLE p_lt_optr LINES line.
  READ TABLE p_lt_optr INDEX line INTO wa.
  IF sy-subrc = 0.
    p_theta = wa-optr.
    DELETE p_lt_optr INDEX line.
  ENDIF.

ENDFORM.                    " POP_OPTR
*&---------------------------------------------------------------------*
*&      Form  POP_OPDN
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      --&gtP_LT_OPDN  text
*      *----------------------------------------------------------------------*
FORM. pop_opdn  TABLES   p_lt_opdn
               CHANGING p_opdn  TYPE formel.
  CLEAR p_opdn.
  DATA line TYPE i.
  DATA wa TYPE wd.
  DESCRIBE TABLE p_lt_opdn LINES line.
  READ TABLE p_lt_opdn INDEX line INTO wa.
  IF sy-subrc = 0.
    p_opdn = wa-opdn.
    DELETE p_lt_opdn INDEX line.
  ENDIF.

ENDFORM.                    " POP_OPDN
*&---------------------------------------------------------------------*
*&      Form  OPRATE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      --&gtP_LT_OPDN  text
*      --&gtP_A  text
*      --&gtP_B  text
*      --&gtP_THETA  text
*----------------------------------------------------------------------*
FORM. oprate  TABLES   p_lt_opdn
             USING    p_a  TYPE formel
                      p_b  TYPE formel
                      p_theta  TYPE formel.
  DATA:formel TYPE formel,wa TYPE wd.
  CASE p_theta.
    WHEN '+'.
      formel = p_a + p_b.
    WHEN '-'.
      formel = p_a - p_b.
    WHEN '*'.
      formel = p_a * p_b.
    WHEN '/'.
      formel = p_a / p_b.
    WHEN OTHERS.
  ENDCASE.
*  wa-opdn = formel.
*  APPEND wa TO p_lt_opdn.
  CONDENSE formel NO-GAPS.
  PERFORM. push_opdn TABLES p_lt_opdn USING formel.

ENDFORM.                    " OPRATE

 

运行效果:

10842258_200907201146411.jpg

fj.pngimport.JPG

fj.pngexport.JPG

fj.pngexceptions.JPG

fj.pngcompute.JPG

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10842258/viewspace-609590/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10842258/viewspace-609590/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值