Case Study: JavaScript in ABAP Usage

By | December 8, 2011 | Case Study, JavaScript, Tricks | 3,198 | 3

Sometimes, we need to evaluate complex expression. I had faced the similar issue. I was able to use JavaScript (JS) effectively to find a solution.

The Background

At one of my client’s place, we were moving away from Legacy Systems by implementing SAP. Client gets orders from its Customers. This Customers have unique requirement to format certain fields. Lets say the field is on the Sales Order. We’ll refer it as INPUT value. Based on certain rule, Legacy system used to generate the formatted number. One of the rule is similar to this.

Complex Expression

 
"  'PAD(LTRIM(UPROP(V_INPUT), 2), 4, 0) '
"  '+ K(-) + RTRIM(LTRIM(UPROP(V_INPUT), 9), 7) '
"  '+ K(-) + RTRIM(UPROP(V_INPUT), 4)'
 

Now when we move into SAP, we had couple of options: A) Change all the rules to other rules which SAP can interpret and format the number. B) Use other techniques which can evaluate expression in the same manner without modifying existing rules. It seems Option A is better, but due to any reason people has decided to use option B.

Motivation

Now, since we go with Option B, we have to either code in a such a way that, we convert LTRIM to a function or method, which can Trim characters from Left.

In recent times, I am playing with Java, JavaScript, and other web languages. I realized that in JS, we can easily build the similar functions which can evaluate the expressions in ABAP. Moreover, clients ABAP version doesn’t support Method Chaining statement. So, if I use pure ABAP, I would end up breaking entire expression in small chunks. Where as JS allows chaining of the statements.

I built a small web page, where we give the input and it evaluates the expression and format the number as required. I created these functions: LTRIM – Trimming from Left, RTRIM – Trimming from Right, UPROP – UpperCase, PAD – Padding values. And it worked perfectly in web browser.

Code Lines

Now, the challenge is to execute this JS code in ABAP. I realized that we have built in JS library in ABAP stack, which can be used to evaluate this. I tried the simple example as posted in JavaScript in ABAP. Finally, I was able to make it work.

Here is the code lines which accepts the input and formats it as expected.

REPORT znp_js_to_format.

DATAjs_processor TYPE REF TO cl_java_script,
      js_source    TYPE string,
      return_value TYPE string.

* Dynamic Expression
DATAv_original   TYPE string,
      v_expression TYPE string,
      v_output     TYPE string.

PARAMETERSp_input TYPE LENGTH 13 OBLIGATORY DEFAULT '7154817480558'.

START-OF-SELECTION.

  IF STRLENp_input 13.
    MESSAGE 'Input should be 13 characters' TYPE 'S'.
    LEAVE LIST-PROCESSING.
  ENDIF.

  v_original p_input.
  CONCATENATE 'PAD(LTRIM(UPROP(V_INPUT), 2), 4, 0) '
              '+ K(-) + RTRIM(LTRIM(UPROP(V_INPUT), 9), 7) '
              '+ K(-) + RTRIM(UPROP(V_INPUT), 4)'
  INTO v_expression.


* JS Object
  js_processor cl_java_script=>create).

  DATAv_org_str TYPE string.
  DATAv_exp_str TYPE string.
  CONCATENATE 'var V_INPUT = ' '"'v_original'"'   ';' INTO v_org_str.
  CONCATENATE 'var vmain =   ' '"'v_expression'"' ';' INTO v_exp_str.

* JS Source
  CONCATENATE
    v_org_str
    v_exp_str
    'var vres="";'
* UpperCase
    'function UPROP(string){                      '
    '   string = string.toUpperCase();             '
    '   return string;                             '
    '}                                            '
* Left Trim
    'function LTRIM(string, length){              '
    '   var str = string;                          '
    '   string = str.substr(0,length);             '
    '   return string;                             '
    '}                                            '
* Padding
    'function PAD(string, length, val){           '
    '   var str = string;                          '
    '  while (str.length < length) {              '
    '    str = val + str;                         '
    '  }                                          '
    '  return str;                                '
    '}                                            '
* Right Trim
    'function RTRIM(string, length){              '
    '  var totlen = string.length;                '
    '   var startlen = totlen - length;            '
    '   var str = "";                              '
    '   while (startlen <= totlen) {               '
    '     str = str + string.substr(startlen,1);   '
    '     startlen++;                              '
    '   }                                          '
    '   return str;                                '
    '}                                            '
* Evaluate Expression
    'function evaluate_expression(){                '
    '  var vformulas = vmain.split("+");            '
    '  for(var idx=0; idx<vformulas.length; idx++){ '
    '      vformulas[idx].replace(/\s/g,"");        '
    '  }                                            '
    '  for(var idx=0; idx<vformulas.length; idx++){ '
    '     var v_neg = vformulas[idx].search("-")    '
    '     if (v_neg != -1){                         '
    '      vres = vres + "-";                       '
    '     } else {                                  '
    '      vres = vres + eval(vformulas[idx]);      '
    '     }                                         '
    '  }                                            '
    '}                                              '
* call Function and write the value
    'evaluate_expression();                         '
    'vres;                                          '
      INTO js_source SEPARATED BY cl_abap_char_utilities=>cr_lf.

* return after evaluation
  return_value js_processor->evaluatejs_source ).

* Error
  IF js_processor->last_condition_code IS NOT INITIAL.
    WRITE/'Error message'js_processor->last_error_message,
           /'Error Code'js_processor->last_condition_code.
* Result
  ELSE.
    WRITE/'Input 'p_input.
    write/'Output'return_value.
    skip 2.
    WRITE/'Expression'v_expression.
  ENDIF.

Output

It generates the output like this:

Like It? Share!!

Don't miss an Update

Get notified of the new post, right into your inbox

Naimesh Patel{272 articles}

I'm SAP ABAP Consultant for more than a decade. I like to experiment with ABAP especially OO. I have been SDN Top Contributor.
Follow :

Explore all of his 272 articles.

Load comments

3 Comments

  • Clemens Li

    Great!

    Thank you for the nice example.

    Regards Clemens

  • steven.oldner

    Nice! Now we can use REGEX in ABAP, but your JavaScript is much easier to read.

  • Is exacly what i need. Thanks!

Comments on this Post are now closed. If you have something important to share, you can always contact me.

You seem to be new here. Subscribe to stay connected.