Purpose
Use JavaScript to evaluate complex arithmetic expressions encompassing GuiXT variables.

GuiXT scripts only support operations with two operands, which may result in a series of script lines for complex calculations.

Solution
Use the JavaScript function "compute" given below to evaluate arithmetic expressions which encompass numeric constants and GuiXT variables.

Examples

Set V[x1] "1124,78"
Set
V[x2] "5,39"

CallJS compute "r=x1+x2"

// display test message
Message "&V[r]"

 

Set V[amount]  "1280,35"
Set V[taxrate] "19"

CallJS compute "tax = amount * taxrate / 100"

// display test message
Message "&V[tax]"

 

The "compute" function returns a comma as decimal separator. You may change this statically in the JavaScript library or use the function  "compute_set_decimal_separator" to change the decimal separator dynamically in your script, depending on the SAP user settings, for example.

The result, if not an integer value,  is returned with 2 decimal places. You may specify a different number of decimals in the CallJS statement:

// set decimal separator for "compute"
CallJS
compute_set_decimal_separator "."

CallJS compute "r = 2 / 3"  decimals=5

// display test message
Message "&V[r]"

 

All complex arithmetic expressions are supported (parentheses, operator precedence). As operators you may use +, -, *, / and % (modulo).

Set V[amount1] "128,99"
Set
V[amount2] "7,20"
Set V[amount3] "0,98"
Set V[taxrate] "19"

CallJS compute "r = (amount1+amount2+amount3) * taxrate / 100"

// display test message
Message "&V[r]

The "compute" function also allows us to use the alternative notation

CallJS r =  compute "(amount1+amount2+amount3) * taxrate / 100"

 

JavaScript

// parameters for "compute" funcion
var compute_decimal_separator = ",";

// set decimal separator
function compute_set_decimal_separator(sep)
{
    compute_decimal_separator = sep;
};


// evaluate arithmetic expression
function compute(expression,option) {
  
    // decimal places
    var decimals = 2;
  
    // additional options specified?
    if (option && option.substr(0, 9).toLowerCase() == "decimals=")
    {
        decimals = parseInt(option.substr(9));
    };

    // remove whitepace
    expression = expression.replace(/\s/g, "");

    // isolate terms between operators
    expression = expression.replace(/\(/g, "( ");
    expression = expression.replace(/\)/g, " )");
    expression = expression.replace(/\+/g, " + ");
    expression = expression.replace(/\-/g, " - ");
    expression = expression.replace(/\*/g, " * ");
    expression = expression.replace(/\//g, " / ");
    expression = expression.replace(/\%/g, " % ");
    expression = expression.replace(/\=/g, " = ");

    // array with terms
    var terms = expression.split(" ");

    // trim terms
    for (var k=0; k<terms.length; k++)
    {
        terms[k] = myTrim(terms[k]);
    };

    // GuiXT target variable
    var target = "";

    // target specified?
    if (terms.length > 2 && terms[1] == "=")
    {
        target = terms[0];
        terms = terms.slice(2);
    };

         

    // evaluate each term
     for (var k = 0; k < terms.length; k++)
        {

        var operand = terms[k];

        if (operand != "" && "()+-*/%".indexOf(operand) == -1) {

            var x = parseFloat(operand.replace(",", "."));

            if (isNaN(x)) {
                // GuiXT variable
                operand = guixt.get(operand);
                x = parseFloat(operand.replace(",", "."));
            };

            terms[k] = x.toString();

        };

    };

    // evaluate expression
    var r = eval(terms.join(""));

    // invalid expression ?
     if (isNaN(r)) {
         alert("GuiXT script error in expression: " + expression);
         r = 0;
     };


     // generate the decimal places, if not an integer value
     if (parseInt(r) == r)
     {
         r = r.toFixed(0);
     }
    else
     {
         r = r.toFixed(decimals);
     };
   

     // set correct decimal separator
     r = r.replace(".", compute_decimal_separator);
  
    // set GuiXT result variable
    if (target != "") {
        guixt.set(target, r);
    };

    return r;
};

// remove starting/trailing white apace
function myTrim(x) {
    return x.replace(/^\s+|\s+$/gm, '');
}

 

Components
InputAssistant + Controls