Registration

Dear SAP Community Member,
In order to fully benefit from what the SAP Community has to offer, please register at:
http://scn.sap.com
Thank you,
The SAP Community team.
Skip to end of metadata
Go to start of metadata

 

Program to evaluate formula in a string

Summary

1)First program demonstrates how to evaluate the formula in a string. It uses two standard function modules CHECK_FORMULA & EVALUATE_FORMULA

2) Second program performs the same operation using the methods of class CL_JAVA_SCRIPT

Author(s):  

Name: Kesavadas Thekkillath

Company: Atos

 Solution :

We can useCL_JAVA_SCRIPT class to execute JavaScript programs .

Variables and objects in JavaScript can be linked to data objects and references to objects in ABAP using BIND. Changes in the JavaScript program also change the objects in ABAP. Objects of ABAP Objects can also be connected directly to BIND_INSTANCE.

The method used in order of call are as below :

Create for creating a JavaScript context.

COMPLIE  for compiling a JavaScript source in the current context .

EXECUTE for  executing a compiled JavaScript

DESTROY for destroying a compiled JavaScript from the context. 

Error rendering macro 'code': Invalid value specified for parameter 'lang'
TYPES:BEGIN OF ty_val,
      operand TYPE c,
      value TYPE string,
      END OF ty_val,

      BEGIN OF ty_frm,
      formula TYPE char50,
      END OF ty_frm.

DATA:it_val TYPE TABLE OF ty_val,
     it_formula TYPE TABLE OF ty_frm,
wa_val TYPE ty_val,
     wa_frm TYPE ty_frm,
wf_string TYPE char255,
     wf_len TYPE i,
     wf_formula TYPE char50,
     wf_retcode      TYPE sy-subrc,
     wf_funcname(30) TYPE c,
     wf_message(70)  TYPE c,
     wf_pos          TYPE i,
     wf_c            TYPE i.

*Assign the values for the formula

wa_val-operand = 'A'. wa_val-value = '1'.  APPEND wa_val TO it_val.
write :/ wa_val-operand,'=',wa_val-value.
wa_val-operand = 'B'. wa_val-value = '2'.  APPEND wa_val TO it_val.
write :/ wa_val-operand,'=',wa_val-value.
wa_val-operand = 'C'. wa_val-value = '3'.  APPEND wa_val TO it_val.
write :/ wa_val-operand,'=',wa_val-value.
Write :/ '____________________________________________________'.
Write:/.

wa_frm-formula = '(A)*(B)+(C)'. APPEND wa_frm TO it_formula.
wa_frm-formula = '(C)*((A)-(B))'. APPEND wa_frm TO it_formula.

LOOP AT it_formula INTO wa_frm.

  CLEAR:wf_string, wf_formula, wf_len, wf_retcode, wf_funcname, wf_message, wf_pos.

  wf_string = wf_formula = wa_frm-formula.
  REPLACE ALL OCCURRENCES OF REGEX '[^:alpha:]' IN wf_string WITH ` `.
  CONDENSE wf_string NO-GAPS.
  wf_len = STRLEN( wf_string ).

  DO wf_len TIMES.
    sy-index = sy-index - 1.
    READ TABLE it_val INTO wa_val WITH KEY operand = wf_string+sy-index(1).
    IF sy-subrc = 0.
      REPLACE ALL OCCURRENCES OF wf_string+sy-index(1)
                              IN wf_formula
                              WITH wa_val-value.
    ENDIF.
  ENDDO.

  CALL FUNCTION 'CHECK_FORMULA'
    EXPORTING
      formula  = wf_formula
    IMPORTING
      subrc    = wf_retcode
      funcname = wf_funcname
      MESSAGE  = wf_message
      pos      = wf_pos.

  IF wf_retcode IS INITIAL.
    CALL FUNCTION 'EVAL_FORMULA'
      EXPORTING
        formula = wf_formula
      IMPORTING
        value   = wf_c
      EXCEPTIONS
        OTHERS  = 1.
    IF sy-subrc = 0.
      WRITE: / wa_frm-formula,'=', wf_c.
    ELSE.
      WRITE: / 'Error'.
    ENDIF.
  ELSE.
    WRITE: / wf_funcname, wf_message, wf_pos.
  ENDIF.

ENDLOOP.

Program performs the above  operation using the methods of class CL_JAVA_SCRIPT.

Error rendering macro 'code': Invalid value specified for parameter 'lang'
 ----------------------------------------------------------------------
*       CLASS lcl_evaluate_formula DEFINITION
----------------------------------------------------------------------
*
----------------------------------------------------------------------
CLASS lcl_evaluate_formula DEFINITION.
  PUBLIC SECTION.
    DATA:wf_string TYPE string.
    METHODS:execute IMPORTING p_formula TYPE  char50
                    EXPORTING p_out TYPE string.
  PRIVATE SECTION.
    DATA:wf_script TYPE REF TO cl_java_script.
    METHODS:create_script IMPORTING p_input TYPE char50
                          EXPORTING p_scode TYPE string.
    METHODS:evaluate  IMPORTING p_scode TYPE string
                      EXPORTING p_output TYPE string.
ENDCLASS.                    "lcl_evaluate_formula DEFINITION
*--Types
TYPES:BEGIN OF ty_val,
      operand TYPE c,
      value TYPE string,
      END OF ty_val,

      BEGIN OF ty_frm,
      formula TYPE char50,
      END OF ty_frm.

*--Variables and Internal tables
DATA:it_val TYPE TABLE OF ty_val,
     it_formula TYPE TABLE OF ty_frm,
     wa_val TYPE ty_val,
     wf_obj TYPE REF TO lcl_evaluate_formula,
     wa_frm TYPE ty_frm,
     wf_string TYPE char255,
     wf_len TYPE i,
     wf_formula TYPE char50,
     wf_c            TYPE string.

*Assign the values for the formula
*Assign the values for the formula
wa_val-operand = 'A'. wa_val-value = '1'.  APPEND wa_val TO it_val.
write :/ wa_val-operand,'=',wa_val-value.
wa_val-operand = 'B'. wa_val-value = '2'.  APPEND wa_val TO it_val.
write :/ wa_val-operand,'=',wa_val-value.
wa_val-operand = 'C'. wa_val-value = '3'.  APPEND wa_val TO it_val.
write :/ wa_val-operand,'=',wa_val-value.
Write :/ '____________________________________________________'.
Write:/.

*Build equation
wa_frm-formula = '(A)*(B)+(C)'.   APPEND wa_frm TO it_formula.
wa_frm-formula = '(C)*((A)-(B))'. APPEND wa_frm TO it_formula.

CREATE OBJECT wf_obj.

LOOP AT it_formula INTO wa_frm.

  CLEAR:wf_string,wf_formula,wf_len.

  wf_string = wf_formula = wa_frm-formula.
  REPLACE ALL OCCURRENCES OF REGEX '[^:alpha:]' IN wf_string WITH ` `.
  CONDENSE wf_string NO-GAPS.
  wf_len = STRLEN( wf_string ).

*--Replace the operands with the values
  DO wf_len TIMES.
    sy-index = sy-index - 1.
    READ TABLE it_val INTO wa_val WITH KEY operand = wf_string+sy-index(1).
    IF sy-subrc = 0.
      REPLACE ALL OCCURRENCES OF wf_string+sy-index(1)
                              IN wf_formula
                              WITH wa_val-value.
    ENDIF.
  ENDDO.

*--Execute the formula
  wf_obj->execute(
          EXPORTING p_formula = wf_formula
          IMPORTING p_out = wf_c ).

  WRITE:/ wa_frm-formula , '=',wf_c.
ENDLOOP.

----------------------------------------------------------------------
*       CLASS lcl_evaluate_formula IMPLEMENTATION
----------------------------------------------------------------------
*
----------------------------------------------------------------------
CLASS lcl_evaluate_formula IMPLEMENTATION.

  METHOD execute.

*--Get the script code of java
    CALL METHOD me->create_script(
      EXPORTING
        p_input = p_formula
      IMPORTING
        p_scode = wf_string ).
       
*--Execute builded java source
    CALL METHOD me->evaluate(
      EXPORTING
        p_scode  = wf_string
      IMPORTING
        p_output = p_out ).

  ENDMETHOD.                    "execute

  METHOD create_script.

*--Create the script
    wf_script = cl_java_script=>create( ).
    CONCATENATE
       'var string = ' p_input ';'
       'function Set_String()                          '
       '
{ string = eval(string);                     '        '  }

                                            '
       'Set_String();                                  '
       'string;                                        '
         INTO  p_scode SEPARATED BY cl_abap_char_utilities=>cr_lf.

  ENDMETHOD.                    "create_script

  METHOD evaluate.
    p_output = wf_script->evaluate( p_scode ).
  ENDMETHOD.                    "evaluate

ENDCLASS.                    "lcl_evaluate_formula IMPLEMENTATION

3 Comments

  1. Former Member

    Instead

    REPLACE ALL OCCURRENCES OF REGEX 'alpha:' IN wf_string WITH ` `.

    use

    REPLACE ALL OCCURRENCES OF REGEX '[^alpha:]' IN wf_string WITH ` `

  2. Former Member

    This link is a delight as it is from NON SAP Source   http://www.webdbtips.com/119115/

    The real power of EVAL_FORMULA is missed without a call back routine

    I had to spend 6 hours before I got it right; test program below

    *&---------------------------------------------------------------------*
    *& Report  YJNCTEST76    http://ojnc.byethost11.com
    *&---------------------------------------------------------------------*
    REPORT  yjnctest76.
    DATA: dataf  TYPE f,
          datap  TYPE lbkum.
    PARAMETER: formel(40) DEFAULT 'A*B*C*D',
               a      TYPE lbkum DEFAULT 3,
               b      TYPE lbkum DEFAULT 1,
               c      TYPE lbkum DEFAULT 2,
               d      TYPE lbkum DEFAULT 4.
    START-OF-SELECTION.
      CALL FUNCTION 'EVAL_FORMULA'
        EXPORTING
          formula                 = formel
          program                 = sy-repid
          routine                 = 'VAR_GET'
        IMPORTING
          value                   = dataf
        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.
      IF sy-subrc <> 0.
        WRITE:/ formel, sy-subrc ,' ERROR!'.
      ELSE.
        MOVE dataf TO datap.
        WRITE:/ formel, datap.
      ENDIF.
    *---------------------------------------------------------------------*
    *       FORM VAR_GET                                                  *
    *---------------------------------------------------------------------*
    FORM var_get USING value(name)
                 CHANGING value(value)
                          value(subrc).
      subrc = 0.
      value = 0.  "Default if other than A B C D
      CASE name.
        WHEN 'A'.
          value = a.
        WHEN 'B'.
          value = b.
        WHEN 'C'.
          value = c.
        WHEN 'D'.
          value = d.
      ENDCASE.
    ENDFORM.                    "VAR_GET
    *&---------------------------------------------------------------------*

    *& Report  YJNCTEST76    http://ojnc.byethost11.com

    *&---------------------------------------------------------------------*

    REPORT  yjnctest76.

    DATA: dataf  TYPE f,

          datap  TYPE lbkum.

    PARAMETER: formel(40) DEFAULT 'A*B*C*D',

               a      TYPE lbkum DEFAULT 3,

               b      TYPE lbkum DEFAULT 1,

               c      TYPE lbkum DEFAULT 2,

               d      TYPE lbkum DEFAULT 4.

    START-OF-SELECTION.

      CALL FUNCTION 'EVAL_FORMULA'

        EXPORTING

          formula                 = formel

          program                 = sy-repid

          routine                 = 'VAR_GET'

        IMPORTING

          value                   = dataf

        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.

      IF sy-subrc <> 0.

        WRITE:/ formel, sy-subrc ,' ERROR!'.

      ELSE.

        MOVE dataf TO datap.

        WRITE:/ formel, datap.

      ENDIF.

    *---------------------------------------------------------------------*

    *       FORM VAR_GET                                                  *

    *---------------------------------------------------------------------*

    FORM var_get USING value(name)

                 CHANGING value(value)

                          value(subrc).

      subrc = 0.

      value = 0.  "Default if other than A B C D

      CASE name.

        WHEN 'A'.

          value = a.

        WHEN 'B'.

          value = b.

        WHEN 'C'.

          value = c.

        WHEN 'D'.

          value = d.

      ENDCASE.

    ENDFORM.                    "VAR_GET

  3. Former Member

    Raaaapaiz... 

     

    Try this form:

    Data: value type p decimals 2.

    value = cl_java_script=>create( )->evaluate( ‘eval( 1 + 2 + 3 );’ ).

     

     

    Life to happy (wink)