Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - Benjamin Dasari

Pages: 1 ... 3 4 [5] 6 7
61
Purpose:
Create UI dynamically on the same screen based on data passed as an array by converting to hierarchical tree structure.


Liquid UI Code:

[SAPLSMTR_NAVIGATION.E0100.sjs]

load('commonFunctions.sjs');    // Loads the functions file

// This data may come from -
// a. Fixed File
// b. RFC Call
// The data from File or RFC needs to be built into an array similar to below
// "Parent,Child,Value,Tcode"

testData = [];
testData[0] = "Root,1000,K1,";
testData[1] = "1000,Uni Coiler A,K1-A,";
testData[2] = "1000,Uni Coiler B,K1-B,";
testData[3] = "1000,Uni Coiler C,K1-C,";
testData[4] = "Uni Coiler A,Uni Coiler A South East,K1-E-SE,";
testData[5] = "Uni Coiler A,Uni Coiler A North East,K1-E-NE,";
testData[6] = "Uni Coiler A South East,Uni Coiler A South East 1,K1-E-SE-1,";
testData[7] = "Uni Coiler A South East 1,Uni Coiler A South East 1A,K1-E-SE-1A,MM02";
testData[8] = "Uni Coiler A South East 1,Uni Coiler A South East 1B,10030388,IW22";
testData[9] = "Root,2000,100,";
testData[10] = ",Root,,";      // ROOT - Not displayed on screen
testData[11] = "2000,TEST_CASING,100-100,MM03";      

// User Interface
clearscreen();
if(isBlank(first_time)){
   first_time = "X";
   createTree(testData,",");      // Pass seperator to the function and use that (Eg: '^','-','^^')
}
drawUI();


[commonFunctions.sjs]

// Function to trim blank spaces at the end of the string
String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,'');}
                     
// Function to check if the string value is blank
function isBlank(jvar){
   if(typeof jvar == 'string') {
      jvar = jvar.trim();
   }
   if(typeof jvar == 'undefined') {
      jvar = '';
   }
   return(jvar == 'undefined' || jvar == undefined || jvar == null || jvar == "" || jvar == void 0);
}

// Function to paint the User Interface
function drawUI(){
   if(!isBlank(current.getChildren())){
      title(current.name);
      for(x=0; x<current.getChildren().length; x++){
         pushbutton([(x+1)*2,10], current.children[ x].name, "?", {"size":[2,30], "process":changeCurrent, "using":{"new_current":current.children[ x]}});
      }

      // If the option to go back is possible
      if(current.getParentNode() != null){
         pushbutton([TOOLBAR],"@9S@BACK","?", {"process":changeCurrent, "using":{"new_current":current.getParentNode()}});
      }
   } else{
      tcode = current.txcode;
      value = current.val;
      if(!isBlank(tcode)){
         enter({"process":navigateToTransaction, "using":{"l_tcode":tcode, "l_val":value}});
      } else{
         message('E: No transaction specified');
         first_time = '';
         enter('?');
      }
   }
}

// Function to perform some action on the last level
// Navigates to the transaction code and uses the value passed

function navigateToTransaction(param) {
   var tcode = param.l_tcode;
   first_time = '';
   enter('/n'+tcode);

   onscreen '*'            // Rest of the navigation logic based on Transaction code
      title(_title);
      if(tcode == 'MM02'){      
         set('F[Material]',param.l_val);
      } else if(tcode == 'MM03'){      
         set('F[Material]',param.l_val);
         goto MM03_PROCESS;
      } else if(tcode == 'IW22'){      
         set('F[Notification]',param.l_val);
         goto IW22_PROCESS;
      }   
      enter('?');
      goto SCRIPT_END;   
   
   onscreen 'SAPLMGMM.0600'
   MM03_PROCESS:;
      enter();
      goto SCRIPT_END;
      
   onscreen 'SAPLIQS0.0100'
   IW22_PROCESS:;
      enter();
   
   SCRIPT_END:;
}

// Function to initialize the Node containing name, value and transaction code
function Node(name,val,txcode){
   this.name = name;
   this.val = val;
   this.txcode = txcode;
   this.children = [];
   this.parent = null;
   
   this.setParentNode = function(node){
      this.parent = node;
   }
   this.getParentNode = function(){
      return this.parent;
   }
   this.addChild = function(node){
      node.setParentNode(this);
      this.children[this.children.length] = node;
   }
   this.getChildren = function(){
      return this.children;
   }
}

// Function to refresh and paint the new screen based on button click
function changeCurrent(param){
   current = param.new_current;
   enter("?");
}             

// Function which creates the tree structure from an array and the data seperator passed to it
function createTree(arr,seperator){
   // Create the root
   for(i=0; i<arr.length; i++){
      arrTemp = arr[ i].split(seperator);
      if(isBlank(arrTemp[0])){
         rootNode = new Node(arrTemp[1],arrTemp[2],arrTemp[3]);
         arr.splice(i,1);      // Delete the element in the array
         break;
      }
   }
   
   index = 0;
   while(arr.length > 0){        // While elements are in the array
      if(isBlank(arr[index]))      // Reached the end of the data array, break out of while loop
         break;
         
      arrTemp = arr[index].split(seperator);
      result = inTree(rootNode,arrTemp[0]);      // Check whether the Parent is in the Tree
      if(!isBlank(result)){
         result.addChild(new Node(arrTemp[1],arrTemp[2],arrTemp[3]));      // Add the child
         arr.splice(index,1);            // Delete the element in the array
         index = 0;
      } else{
         index++;
      }   
   }   
   current = rootNode;
}

// Function which checks to see if the Parent Node exists in current tree
function inTree(rtnode,parent){
   var nodeStack = [];
   nodeStack.push(rtnode);

   while(nodeStack.length > 0){            // Always 1 as 'nodeStack' contains the ROOT node
      processNode = nodeStack.pop();         // 'processNode' points to the beginning of the node
   
      if (processNode.name == parent) {
         return processNode;               // Returns once the node is found and adds to the tree
         break;
      } else if (processNode.children.length>0) {      
         for (ii = 0; ii < processNode.children.length; ii++) {
            nodeStack.push(processNode.children[ii]);      
         }
      }
   }
   return '';                              // Return an empty string if parent not found in the tree
}


See attachments for code samples!

62
Purpose:
Create dynamically multiple levels of hierarchy based on data and pass values along the way to be used in the last level.


Liquid UI Code:

// SAPLSMTR_NAVIGATION.E0100.sjs

// Delete AxtiveX Container on SAP Easy Access screen
del('X[IMAGE_CONTAINER]');     

// Function to trim blank spaces at the end of the string
String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,'');}
                     
// Function to check if the string value is blank
function isBlank(jvar){
   if(typeof jvar == 'string') {
      jvar = jvar.trim();
   }
   if(typeof jvar == 'undefined') {
      jvar = '';
   }
   return(jvar == 'undefined' || jvar == undefined || jvar == null || jvar == "" || jvar == void 0);
}

// Function to transform the JSON data into Tree Hierarchical structure
function generateHierarchyData(arrName) {
   var roots = [], children = {};

    // Find the top level nodes and hash the children based on parent
    for (var i = 0, len = arrName.length; i < len; ++i) {
       var item = arrName[ i];
      p = item.Parent;
      target = !p ? roots : (children[p] || (children[p] = [])); // If isBlank 'p' then target = roots, else target = (children[p] || (children[p] = []))
        target.push({ value: item });
    }

    // Function to recursively build the tree
    var findChildren = function(parent) {
        if (children[parent.value.Id]) {
            parent.children = children[parent.value.Id];
            for (var i = 0, len = parent.children.length; i < len; ++i) {
                findChildren(parent.children[ i]);
            }
        }
    };

    // Enumerate through to handle the case where there are multiple roots
    for (var i = 0, len = roots.length; i < len; ++i) {
        findChildren(roots[ i]);
    }
   return roots;
}

// Function to create the UI based on parameters passed
function generateHierarchyUI(param) {
   nodeId = param.currentNodeId;
   nodeVal = param.currentNodeVal;
   arrName = param.arrNm;
   children = [];
   
   for(var i=0; i<arrName.length; i++){   // For display for Children and Title
      var item = arrName[ i];
      if(item.Id == nodeId){            // To Display Title
         if(isBlank(txcode)){
            txcode = item.Txcode;
         }   
         titleName = item.Name;
         title(titleName);            // Push button that is clicked is displayed as the title
      }
      if(item.Parent == nodeId){         // Create children array      
         children.push({value: item});      
      }
      
   }
   
   onscreen 'SAPLSMTR_NAVIGATION.0100'
      pushScreens = false;
      enter('?');
}

// Function to perform some action on the last level
// Navigates to the transaction code and uses the value passed
function navigateNode(param) {
      var tcode = param.l_tcode;
      first_time = '';
      enter('/n'+tcode);
   
   onscreen '*'
      title(_title);
      if(tcode == 'MM02'){      // Rest of the navigation logic based on Transaction code
         set('F[Material]',param.nodevalue);
      }
         
      enter('?');
}

// Function to display the previous screen when Back button is clicked
function generateHierarchyUIBack(){
   backClicked = 'X';
   
   screenArr.pop();
   titles.pop();
   children = screenArr[screenArr.length -1].slice(0);
}



// Retrieve Data in the below format
// These data may come from-
// a. Fixed File
// b. RFC Call

var testData = [
    {"Id": "1", "Name": "1000", "Value": "", "Parent": "", "Txcode": "MM02"},
    {"Id": "2", "Name": "Uni Coiler A", "Value": "K1-A", "Parent": "1"},
    {"Id": "3", "Name": "Uni Coiler B", "Value": "K1-B", "Parent": "1"},
    {"Id": "4", "Name": "Uni Coiler C", "Value": "K1-C", "Parent": "1"},
    {"Id": "5", "Name": "Uni Coiler A South East", "Value": "K1-E-SE", "Parent": "2"},
    {"Id": "6", "Name": "Uni Coiler A North East", "Value": "K1-E-NE", "Parent": "2"},   
    {"Id": "7", "Name": "Uni Coiler A South East 1", "Value": "K1-E-SE-1", "Parent": "5"},   
    {"Id": "8", "Name": "2000", "Value": "", "Parent": "", "Txcode": "VA02"},
   {"Id": "9", "Name": "Uni Coiler A South East 1A", "Value": "K1-E-SE-1A", "Parent": "7"},   
   {"Id": "10", "Name": "Uni Coiler A South East 1B", "Value": "K1-E-SE-1B", "Parent": "7"}   
];


// Initial Entry - SAP Easy access
if(isBlank(first_time)){                  // UI for Initial entry on Log on
   first_time = "X";
   txcode = "";
   counter = 0;
   root_val = [];
   root_val = generateHierarchyData(testData);   // Pass the Data Array as parameter to the function
   firstTitle = 'Root';
   title(firstTitle);                     // Initial Title to be displayed
   for(i=0;i<root_val.length;i++){
      pushbutton([(i+1)*2,10], ""+root_val[ i].value.Name+"", {"size":[2,30], "process":generateHierarchyUI, "using":{"currentNodeId":root_val[ i].value.Id, "currentNodeVal":root_val[ i].value.Value, "arrNm":testData}});
   }
   screenArr = [];
   titles = [];
   screenArr.push(root_val);
   titles.push(firstTitle);
} else{                               // UI for Second level onwards
   if(isBlank(children)){                  // If user refreshes the screen OR On reaching the last level
      if(!isBlank(txcode)){
         enter({"process":navigateNode, "using":{"l_tcode":txcode, "nodevalue":nodeVal}});
      } else{
         enter('/0');
         first_time = '';
      }
      goto SCRIPT_END;
   } else {                           // For display Multiple levels
      if(children.length != 0){
         for(i=0;i<children.length;i++){
            pushbutton([(i+1)*2,10], ""+children[ i].value.Name+"", {"size":[2,30], "process":generateHierarchyUI, "using":{"currentNodeId":children[ i].value.Id, "currentNodeVal":children[ i].value.Value, "arrNm":testData}});      
         }
         // Code for BACK button below
         if(backClicked == 'X'){
            titleName = titles[titles.length -1];
            backClicked = '';
         }
         title(titleName);
         if(titleName != firstTitle){
            pushbutton([TOOLBAR], "@9S@BACK", '?', {"process":generateHierarchyUIBack});
         }   

         if(!pushScreens){
            screenArr.push(children);
            titles.push(titleName);
            pushScreens = true;
         }   
      }      
   }
}

SCRIPT_END:;


See attachments for code samples!

63
WS aka Web Scripts (Attended RPA for SAP) / Convert Date Format
« on: August 03, 2016, 02:47:18 PM »
Purpose:
Convert user entered date format to a new format.

Liquid UI Code:

// SAPLSMTR_NAVIGATION.E0100.sjs

// Function to trim blank spaces at the end of the string
String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,'');}
                     
// Function to check if the string value is blank
function isBlank(jvar){
   if(typeof jvar == 'string') {
      jvar = jvar.trim();
   }
   if(typeof jvar == 'undefined') {
      jvar = '';
   }
   return(jvar == 'undefined' || jvar == undefined || jvar == null || jvar == "" || jvar == void 0);
}

/**************************************************************************************
Change date from one format to another formats:
   // 1. DD.MM.YYYY
   // 2. MM/DD/YYYY
   // 3. MM-DD-YYYY
   // 4. YYYY.MM.DD
   // 5. YYYY/MM/DD
   // 6. YYYY-MM-DD
****************************************************************************************/

function changeFormat(date,dformat,outformat){
    arDateValues = check_date_format(date,dformat);
   if (arDateValues.length == 0){
      return ("E: Invalid Format");
   }
   day = arDateValues[0];
   month = arDateValues[1];
   year = arDateValues[2];
   date1 = "";
   switch (outformat){
         case '1':
            date1 = day + "." + month + "." + year;
            break;
         case '2':
            date1 = month + "/" + day + "/" + year;         
            break;
         case '3':
            date1 = month + "-" + day + "-" + year;                     
            break;
         case '4':
            date1 = year + "." + month + "." + day;         
            break;
         case '5':
            date1 = year + "/" + month + "/" + day;            
            break;
         case '6':
            date1 = year + "-" + month + "-" + day;
            break;
      }
      return (date1);   
}

// Function to validate the date format
function check_date_format(date,dformat){
   date = date.toString();
   arValues = [];
   arTmpValues = [];
   switch (parseInt(dformat)){
      case 1:
         var matches = /^([0]?[1-9]|[12][0-9]|3[01])\.([0]?[1-9]|1[012])\.[0-9]{4}/.exec(date);
         if (matches == null) return ([]);
         else {
            arTmpValues = date.split(".");
            return (arTmpValues);
         }
         break;
      case 2:
         var matches = /^([0]?[1-9]|1[012])\/([0]?[1-9]|[12][0-9]|3[01])\/[0-9]{4}/.exec(date);
         if (matches == null) return ([]);
         else {            
            arTmpValues = date.split("/");
            return ([arTmpValues[1],arTmpValues[0],arTmpValues[2]]);
         }
         break;
      case 3:
         var matches = /^([0]?[1-9]|1[012])\-([0]?[1-9]|[12][0-9]|3[01])\-[0-9]{4}/.exec(date);
         if (matches == null) return ([]);
         else {
            arTmpValues = date.split("-");
            return ([arTmpValues[1],arTmpValues[0],arTmpValues[2]]);
         }
         break;   
      case 4:
         var matches = /^[0-9]{4}\.([0]?[1-9]|1[012])\.([0]?[1-9]|[12][0-9]|3[01])/.exec(date);
         if (matches == null) return ([]);
         else {
            arTmpValues = date.split(".");
            return ([arTmpValues[2],arTmpValues[1],arTmpValues[0]]);
         }
         break;
      case 5:
         var matches = /^[0-9]{4}\/([0]?[1-9]|1[012])\/([0]?[1-9]|[12][0-9]|3[01])/.exec(date);
         if (matches == null) return ([]);
         else {
            arTmpValues = date.split("/");
            return ([arTmpValues[2],arTmpValues[1],arTmpValues[0]]);
         }
         break;
      case 6:
         var matches = /^[0-9]{4}\-([0]?[1-9]|1[012])\-([0]?[1-9]|[12][0-9]|3[01])/.exec(date);
         if (matches == null) return ([]);
         else {
            arTmpValues = date.split("-");
            return ([arTmpValues[2],arTmpValues[1],arTmpValues[0]]);
         }
         break;
   }
}

// Function to call the check and change date format functions
function changeDateFormat(){
   if(isBlank(z_date)){
      message('E: Please enter Date');
      goto SCRIPT_END;
   }
   if(isBlank(z_currdtformat)){
      message('E: Please enter Current Format');
      goto SCRIPT_END;
   }
   if(isBlank(z_newdtformat)){
      message('E: Please enter New Format');
      goto SCRIPT_END;
   }
   
   z_nwdtformat = changeFormat(z_date,z_currdtformat,z_newdtformat);
   if(z_nwdtformat.indexOf('Invalid') > -1){
      message('E: Invalid format - Date and Current Format should match');
      goto SCRIPT_END;
   } else{
      set('V[z_date]','&V[z_nwdtformat]');
      message('S: Changed format successfully');
   }
   enter('?');
   
   SCRIPT_END:;
}

// User Interface
clearscreen();
inputfield([1,1], "Enter Date", [1,22], {"name":"z_date", "required":true, "size":10});

text([2,1], "Select Current Format");
set("V[Current Format]", "=;1=1 DD.MM.YYYY;2=2 MM/DD/YYYY;3=3 MM-DD-YYYY;4=4 YYYY.MM.DD;5=5 YYYY/MM/DD;6=6 YYYY-MM-DD;");
dropdownlist([2,22], "Current Format", {"refer":"z_currdtformat", "width":15, "textfont":"verdana", "textheight":13, "textweight":4});

text([3,1], "Select New Format");
set("V[New Format]", "=;1=1 DD.MM.YYYY;2=2 MM/DD/YYYY;3=3 MM-DD-YYYY;4=4 YYYY.MM.DD;5=5 YYYY/MM/DD;6=6 YYYY-MM-DD;");
dropdownlist([3,22], "New Format", {"refer":"z_newdtformat", "width":15, "textfont":"verdana", "textheight":13, "textweight":4});

pushbutton([5,1], "@01@Change Date to New Format", "?", {"process":changeDateFormat});


See attachments for code samples!

64
WS aka Web Scripts (Attended RPA for SAP) / Read List Screen Data
« on: August 03, 2016, 12:34:25 PM »
Purpose:
Read data from a screen containing a list.


Liquid UI Code:

// SAPLSMTR_NAVIGATION.E0100.sjs

// Function to trim blank spaces at the end of the string
String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,'');}
                     
// Function to check if the string value is blank
function isBlank(jvar){
   if(typeof jvar == 'string') {
      jvar = jvar.trim();
   }
   if(typeof jvar == 'undefined') {
      jvar = '';
   }
   return(jvar == 'undefined' || jvar == undefined || jvar == null || jvar == "" || jvar == void 0);
}

/**************************************************************************************************
*** Use this function to read a single line out of a list screen.
*** This function can only be used to read data rows that are visible on the current screen, and not header rows or other rows.
*** format: readListString(<OPTION>,<FIRST_DATA_ROW_NUMBER--OPTIONAL>);
   <OPTION>: Integer specifying an absolute row number
           'last' specifying the last row of data in the list
           'lastvisible' specifying the last row of data on the current page
*** eg:  var listString = readListString(5,3);              // This will return the data in row 5 of the page
***      var listString = readListString('last',3);         // This will return the last data row
***      var listString = readListString('lastvisible',3);   //This will return the data of last row on the current page

NOTE: For 'last' and 'lastvisible' we make use of the WS variables _listlastrow and _listlastvisiblerow. These variables
return the last row number and the last visible row number, and does not take into account the header rows of the list table.
For example, if there is 1 row of headers, and the table data rows start at line 3 (headers will be rows 0,1,2), then you will need to
pass 3 as the 2nd argument in your function.

If firstDataRow is not passed in, it will be calculated as the row after 644444... which denotes |------ junction
***************************************************************************************************/

function readListString(row,firstDataRow){
   retString = "";
   value = "";
   set("V[firstVisRow]", _listfirstvisiblerow);
   set("V[lastVisRow]", _listlastvisiblerow);
   set("V[lastRow]", _listlastrow);

   firstVisRow = parseInt(firstVisRow,10);
   lastVisRow = parseInt(lastVisRow,10);
   lastRow = parseInt(lastRow,10);
   
   if (firstDataRow == void 0 || isBlank(firstDataRow.toString().trim())){
      nRow = 1;
      for (var iRow = 0; iRow < nRow; iRow++){
         objReeb = <"#["+iRow.toString()+",0]">;
         if (objReeb.name.label != void 0 && objReeb.name.label.indexOf('644444')>-1){
            firstDataRow = iRow + 1;
            break;
         }
         nRow++;
      }
   }
   
   if (row != 'lastvisible' && row != 'last'){
      if ((row > lastRow + firstDataRow - 1) || (row < firstDataRow)){
         return ('E: Cannot find data');
         goto SCRIPT_END;
      }
   }

   // if the firstDataRow is provided, check if the user is trying to read the lastRow or lastVisibleRow
   if (firstDataRow != void 0 && !isBlank(firstDataRow.toString().trim())){
      if (row == 'last' || row == 'lastvisible'){
         if (row == 'last'){   
            row = lastRow;
         } else if (row == 'lastvisible'){   
            row = lastVisRow;
         }
         row = parseInt(row,10);
         row += firstDataRow - 1;
      }   
      
      if ((row < (lastVisRow + firstDataRow)) && (row >= (firstVisRow + firstDataRow - 1))){
         //data to be read is on the same page
         //adjust row number - must be relative to the current page

         row = row - firstVisRow + 1;
         goto CONTINUE_READ;
      } else if (row >= (lastVisRow + firstDataRow)){   //scroll page down
         enter({'process':scroll_down});
         goto SCRIPT_END;
      } else {                                                   // scroll page up
         enter({'process':scroll_up});
         goto SCRIPT_END;
      }
   }
   
   CONTINUE_READ:;
   for (var col=0; col<1000; col++){
      var objReeb = <"#["+row+","+col+"]">;
      if (objReeb.isValid){
         if (objReeb.name.label == '5'|| isBlank(objReeb.name.toString().trim())){
            retString += value + ' ';
            value = "";   
         } else if (objReeb.name != lastReebName){
            value = objReeb.name;
            lastReebName = value;
         }         
      }
   }
   
   return(retString);
   SCRIPT_END:;
}

// Function to navigate to ME56 and read the list screen data
function readListData(){
   onscreen 'RM06BZ00.1000'   // ME56 Transaction
      enter('/8');
      
   onscreen 'RM06BL00.0120'   
      var listidx=5;   
      var listString1 = readListString(listidx,3);    
      var listString2 = readListString(listidx+1,3);    
      
      set('V[z_me56_matl]',listString1.substring(0,18).trim());
      set('V[z_me56_desc]',listString1.substring(18,59).trim());
      set('V[z_me56_deldate]',listString2.substring(27,37).trim());
      set('V[z_me56_plant]',listString2.substring(52,56).trim());
      enter('/n');
}

// User Interface
clearscreen();
pushbutton([0,0], "ME56 - Read List Data", "/nME56", {"process":readListData});      
inputfield([1,0], "Material", [1,16], {"size":18, "name":"z_me56_matl", "readonly":true});   
inputfield([2,0], "Description", [2,16], {"size":40, "name":"z_me56_desc", "readonly":true});
inputfield([3,0], "Deliv. date", [3,16], {"size":10, "name":"z_me56_deldate", "readonly":true});
inputfield([4,0], "Plant", [4,16], {"size":4, "name":"z_me56_plant", "readonly":true});


See attachments for code samples!

65
WS aka Web Scripts (Attended RPA for SAP) / Validate Time Format
« on: August 01, 2016, 05:36:13 PM »
Purpose:
To validate time in 'hh:mm:ss' format.


Liquid UI Code:

// SAPLSMTR_NAVIGATION.E0100.sjs

// Function to trim blank spaces at the end of the string
String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,'');}
                     
// Function to check if the string value is blank
function isBlank(jvar){
   if(typeof jvar == 'string') {
      jvar = jvar.trim();
   }
   if(typeof jvar == 'undefined') {
      jvar = '';
   }
   return(jvar == 'undefined' || jvar == undefined || jvar == null || jvar == "" || jvar == void 0);
}

// Function to check if time is in HH:MM:SS format
// The function takes in an array of times, and outputs a flag
// If time format is incorrect, resulting flag is set to 'false'
function check_time_format(usertime) {
   usertime = usertime.toString();
   var flag = true;

   //Format we need is HH:MM:SS
   for (var i=0; i<usertime.length; i++) {
      var third_pos = usertime.substring(2,3);
      var sixth_pos = usertime.substring(5,6);
      if (third_pos != ":" || sixth_pos != ":") {
         flag = false;
         break;
      }
      if (usertime.length != 8) {
         flag = false;
         break;
      }
      var hour = usertime.substring(0,2);
      hour = parseInt(hour,10);
      var min = usertime.substring(3,5);
      min = parseInt(min,10);
      var sec = usertime.substring(6,8);
      sec = parseInt(sec,10);

      if ((hour > 23) || (hour < 0)) {
         flag = false;
         break;
      }
      if ((min > 59) || (min < 0))  {
         flag = false;
         break;
      }
      if ((sec > 59) || (sec < 0))  {
         flag = false;
         break;
      }
   }
   return (flag);
}

// Function to validate the time format
function validateTime(){
   if(isBlank(z_time)){
      return('E: Please enter a value');
   }
   
   res = check_time_format(z_time);
   if(!res){
      return('E: Invalid Time Format');
   } else{
      return('S: Valid Time Format');
   }
}

// User Interface
clearscreen();
inputfield([1,0], "Enter time", [1,16], {"size":8, "name":"z_time"});
pushbutton([1,26], "@01@Validate Time", {"process":validateTime, "size":[1,15]});


See attachments for code samples!

66
WS aka Web Scripts (Attended RPA for SAP) / Unpad zeroes from string
« on: August 01, 2016, 03:48:42 PM »
Purpose:
To remove zeroes before or after a string based on parameters passed.


Liquid UI Code:

// SAPLSMTR_NAVIGATION.E0100.sjs

// Function to remove zeroes padded to the source based on the direction specified
function unPadZeroes(source,direction) {
   var output = "";
   var sourceLength = 0;
   var sourceOriginalLength = 0;
   source = source.toString();

    if(source) {
       sourceOriginalLength = source.length;   
      sourceLength = source.length;
    }
   
   switch (direction){
      case "LEFT":
         for (var loop = 0; loop < sourceOriginalLength; loop++) {         
            if(source[0]=='0'){
               source = source.substring(1,sourceLength);
               sourceLength = source.length;
            } else {
               break;   
            }
         }
         break;
      case "RIGHT":
         for (var loop = 0; loop < sourceOriginalLength; loop++) {         
            if(source[sourceLength-1]=='0'){
               source = source.substring(0,sourceLength-1);
               sourceLength = source.length;
            } else {
               break;   
            }
         }
         break;
   }
    return source;
}

// Function to remove zeroes to the left of the source
function removeZeroesLeft(){
   z_temp = unPadZeroes(z_value,"LEFT");
   set('V[z_unpadded_value]','&V[z_temp]');
   return;
}

// Function to remove zeroes to the right of the source
function removeZeroesRight(){
   z_temp = unPadZeroes(z_value,"RIGHT");
   set('V[z_unpadded_value]','&V[z_temp]');
   return;
}

// User Interface
clearscreen();
inputfield([1,0], "Enter Value", [1,16], {"size":10, "name":"z_value"});
inputfield([2,0], "New Value", [2,16], {"size":10, "name":"z_unpadded_value", "readonly":true});
pushbutton([4,0], "Remove Zeroes Left", {"process":removeZeroesLeft, "size":[1,18]});
pushbutton([4,20], "Remove Zeroes Right", {"process":removeZeroesRight, "size":[1,18]});


See attachments for code samples!

67
WS aka Web Scripts (Attended RPA for SAP) / Display Custom Pop-up
« on: July 29, 2016, 12:03:39 PM »
Purpose:
Display custom pop-up and wait for user interaction.


Liquid UI Code:

// SAPLSMTR_NAVIGATION.E0100.sjs
// User Interface
clearscreen();
pushbutton([1,1], 'Execute Pricing', '/o');

// RSM04000_ALV.E2000.sjs
// Function to execute VK11 when the user clicks 'Yes' on the pop-up
function executeVK11() {
   onscreen 'SAPLSMTR_NAVIGATION.0100'
      enter('/nvk11');
      
   onscreen 'SAPMV13A.0100'
      set('F[Condition type]','PR00');
      enter();

   onscreen 'SAPLV14A.0100'
      enter();
}

// Pop-up screen Interface
clearscreen();
title('Decision to Proceed');
text([2,2], 'Do you want to create pricing conditions?');
text([3,2], 'Press <Yes> to continue, Press <No> to stop');
del('P[Generate]');
del('P[End Session]');
text('P[Continue]','@01@Yes');
text('P[Cancel]','@02@No');

onUIEvents['Enter'] = {"fcode":"/12", "process":executeVK11}
onUIEvents['/12'] = {"fcode":"/12"};


See attachments for code samples!

68
WS aka Web Scripts (Attended RPA for SAP) / 'wsmessage' Command
« on: July 28, 2016, 04:35:48 PM »
Purpose:
The 'wsmessage' command is entered into the transaction field and is used to display various attributes relating to the current build of WS. It can also be used to encrypt the RFC password.

Parameter Options - _builddate, _guixtdll, _guixtsjs, _version, encrypt
SYNTAX-
/wsmessage(_builddate)                       - Displays the actual date the build was made.
/wsmessage(encrypt('password'),1)    - Ecrypts the RFC password for WS.
/wsmessage(_guixtdll)                           - Displays the full path, including the filename, to the currently active GuiXT engine.   
/wsmessage(_guixtsjs)                 - Displays the full path, including filename, to the SJS profile file being used.
/wsmessage(_version)                 - Displays the version number of the current GuiXT WS build.


See attachments!

69
Purpose:
Using '/ws_' command at runtime to perform several very useful tasks.

The ws_ commands can be executed directly from the transaction box.

SYNTAX-
/ws_vap    -Turns Visble Processing on or off at runtime.
/ws_WS    -Turns WS on or off at runtime.


/ws_vap
This command is used to turn on/off visible processing during runtime. The ws_vap command does not take any options.

Visible processing is useful as it enables users to follow the actual process of a script step by step.
The syntax is as follows:

/ws_vap=x

There are two values that can be entered as follows:

0    -Turns visible processing off at runtime.
1    -Turns visible processing on at runtime.


/ws_WS
The ws_WS command is used to turn the WS engine on and off at runtime. The ws_WS command does not take any options.

The syntax is as follows:

/ws_WS=x

There are two values that can be entered as follows:

0    -Turns the WS engine off at runtime.
1    -Turns the WS engine on at runtime.


See attachments!

70
Purpose:
Validate the user entry decimal format by checking with SAP decimal format.

Liquid UI Code:

// SAPLSMTR_NAVIGATION.E0100.sjs

// Read User Decimal Format Defaults
if(!READDEFAULTS){
   call('BAPI_USER_GET_DETAIL',{'IN.USERNAME':'&V[_user]','OUT.DEFAULTS':'userDefaults'});
   USERDECIMALFORMAT = userDefaults.substring(28,29);
   READDEFAULTS = true;
}

// Remove blank spaces
String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,'');}

// Function to check if the string value is blank
function isBlank(jvar){
   if(typeof jvar == 'string') {
      jvar = jvar.trim();
   }
   if(typeof jvar == 'undefined') {
      jvar = '';
   }
   return(jvar == 'undefined' || jvar == undefined || jvar == null || jvar == "" || jvar == void 0);
}

// Function converts the user decimal format in SAP to a general decimal format (xxxxxx.xx)
function decimalNotationFormat(numberFormat,number,nDec){
   var str = "";

   if(nDec == void 0)   // Default for number of decimal places
      nDec = 2;
      
   switch(numberFormat)
   {
   case 'X':
      {
         str = number.replace(/\,/g, '');      // Replace , with nothing
      }
      break;
   case 'Y':
      {
         str = number.replace(/\s+/g,'');      // Remove Blank Spaces
         str = str.replace(/\,/g, '.');         // Replace , with .
      }
      break;
   default:
      {
         str = number.replace(/\./g, '');      // Replace . with nothing
         str = str.replace(/\,/g, '.');         // Replace , with .
      }
      break;
   }
   return parseFloat(str.trim()).toFixed(3);
}

// Function converts the general decimal format to user decimal format in SAP
function userSAPDecimalFormat(nStr,nSeparator){
   var str = nStr.split('.');
    var offset = str[0].length % 3;

   if(nSeparator == ' ')
      str[0] = str[0].substring(0, offset) + str[0].substring(offset).replace(/([0-9]{3})/g, ".$1");
   if(nSeparator == 'X')
      str[0] = str[0].substring(0, offset) + str[0].substring(offset).replace(/([0-9]{3})/g, ",$1");
   if(nSeparator == 'Y')
      str[0] = str[0].substring(0, offset) + str[0].substring(offset).replace(/([0-9]{3})/g, " $1");
   
   if(offset == 0)
      str[0] = str[0].substring(1,str[0].length);

   if(nSeparator == 'Y' || nSeparator == ' ') {
      return str.join(',');
   } else {
      return str.join('.');
   }      
}   

// Function to check and convert user entry for decimal format
function changeUserFormat(){
   if(isBlank(z_val)){
      return('E: Please enter value');
   }
   z_val = decimalNotationFormat(USERDECIMALFORMAT,z_val.toString(),3);
   z_tmp = userSAPDecimalFormat(z_val,USERDECIMALFORMAT);
   set('V[z_val_userformat]','&V[z_tmp]');
}
 
// User Interface
clearscreen();
inputfield([1,1], "Enter Decimal Value", [1,22], {"name":"z_val", "size":15});
inputfield([2,1], "User Format", [2,22], {"name":"z_val_userformat", "size":15, "readonly":true});
pushbutton([1,40], "@01@User Decimal Format", {"process":changeUserFormat});


See attachments for code samples!

71
WS aka Web Scripts (Attended RPA for SAP) / Clear Liquid UI Table
« on: July 28, 2016, 12:26:58 PM »
Purpose:
Clear all or few of the columns of a Liquid UI table.


Liquid UI Code:

// SAPLSMTR_NAVIGATION.E0100.sjs

// Function to clear the Liquid UI table based on parameters
function clear_values(tablename, columnArray, rows){   
   for (var loop = 0; loop < rows; loop++){
      for (var col=0; col<columnArray.length; col++){   
         tablename[columnArray[col]][loop] = "";
      }
   }   
}

// Function to display Material/s on the Liquid UI table
function showMatlData(){
   // Sample Materials and Descriptions
   var matDataArr = [];
   for(i=1;i<=20;i++){
      matDataArr.push({key:'Material '+i+'',value:'Description '+i+''});
   }

   // Populating table with Material numbers
   for(i=0;i<matDataArr.length;i++){
      matl_table.z_matl[ i] = matDataArr[ i].key;
      matl_table.z_matl_desc[ i] = matDataArr[ i].value;
   }
}

// Function to only clear the Description column
function clearTableDesc(){
   if(typeof matl_table == 'object'){
      clear_values(matl_table, ["z_matl_desc"], 20);
   }   
}

// Function to clear all columns
function clearTable(){
   if(typeof matl_table == 'object'){
      clear_values(matl_table, ["z_matl","z_matl_desc"], 20);
   }   
}

// User Interface
clearscreen();
// Liquid UI table and columns
table([1,1],[20,50], {"name":"matl_table", "title":"Material Info", "rows":20});
column('Material', {"table":"matl_table", "name":"z_matl", "position":1, "size":15, "readonly":true});
column('Description', {"table":"matl_table", "name":"z_matl_desc", "position":2, "size":30, "readonly":true});
pushbutton([21,1], "@01@Retrieve Material Descriptions", {"process":showMatlData});
pushbutton([23,1], "@01@Clear Descriptions", {"process":clearTableDesc});
pushbutton([25,1], "@01@Clear Table", {"process":clearTable});


See attachments for code samples!

72
Purpose:
Calculate the processing statistics of transactions.

Liquid UI Code:

// SAPLSMTR_NAVIGATION.E0100.sjs

// Function to convert milliseconds to Sec/Min/Hrs/Days
function timeConversion(millisec) {
   var seconds = (millisec / 1000).toFixed(2);
   var minutes = (millisec / (1000 * 60)).toFixed(2);
   var hours = (millisec / (1000 * 60 * 60)).toFixed(2);
   var days = (millisec / (1000 * 60 * 60 * 24)).toFixed(2);

   if (seconds < 60) {
      return seconds + " Sec";
   } else if (minutes < 60) {
      return minutes + " Min";
   } else if (hours < 24) {
      return hours + " Hrs";
   } else {
      return days + " Days"
   }
}   

// Function to calculate Processing Statistics
function processingStatistics(){
   var nExecutedTransactions = 0;
   var s = new Date();
   
   onscreen 'SAPLSMTR_NAVIGATION.0100'
      enter('/nMM01');
      
   onscreen 'SAPLMGMM.0060'
      set('F[Industry sector]','M');
      set('F[Material Type]','FERT');
      enter('/5');   
      
   onscreen 'SAPLMGMM.0070'      
      enter('/19');            
         
   onscreen 'SAPLMGMM.0070'      
      set('cell[TABLE,0,1]','X');   
      enter();
      
   onscreen 'SAPLMGMM.4004'
      set('F[MAKT-MAKTX]', 'Test 1');
      set('F[MARA-MEINS]', 'EA');
      enter('/11');
      
   onscreen 'SAPLMGMM.0060'
      set('V[z_mm01_num]',_message.match(/\d+/));
      nExecutedTransactions++;
      enter('/nIW21');
      
   onscreen 'SAPLIQS0.0100'   
      set("F[Notification type]", "M1");
      enter();
      
   onscreen 'SAPLIQS0.7200'
      set("F[VIQMEL-QMTXT]", "test");
      set("F[Functional loc.]", "21-B02");
      set("F[Equipment]", "TEQ-21");
      enter('/11');
   
   onscreen 'SAPLIQS0.0100'   
      set('V[z_iw21_num]',_message.match(/\d+/));
      nExecutedTransactions++;
      enter('/nMMBE');

   onscreen 'RMMMBESTN.1000'   
      set('F[Material]','97104');
      enter('/8');
         
   onscreen 'RMMMBESTN.0300'   
      nExecutedTransactions++;
      enter('/n');
            
   onscreen 'SAPLSMTR_NAVIGATION.0100'
      var e = new Date();
      var timeElapsed = e - s;
      var perTranTime = timeElapsed / nExecutedTransactions;

      set('V[z_transactions]','&V[nExecutedTransactions]');
      timeElapsed = timeConversion(timeElapsed);
      perTranTime = timeConversion(perTranTime);
      set('V[z_executed_time]','&V[timeElapsed]');
      set('V[z_avg_time]','&V[perTranTime]');
      enter('?');
}

// User Interface
clearscreen();
pushbutton([1,0], "Process Statistics", {"process":processingStatistics});
inputfield([2,0], "Total Transactions", [2,25], {"size":2, "name":"z_transactions", "readonly":true});
inputfield([3,0], "Executed Time", [3,25], {"size":10, "name":"z_executed_time", "readonly":true});
inputfield([4,0], "Average Time/Transaction", [4,25], {"size":10, "name":"z_avg_time", "readonly":true});
inputfield([5,0], "Material Number", [5,25], {"size":10, "name":"z_mm01_num", "readonly":true});
inputfield([6,0], "Notification Number", [6,25], {"size":10, "name":"z_iw21_num", "readonly":true});


See attachments for code samples!

73
WS aka Web Scripts (Attended RPA for SAP) / Padding a String
« on: July 27, 2016, 04:16:06 PM »
Purpose:
To add characters before or after a string based on parameters passed.


Liquid UI Code:

// SAPLSMTR_NAVIGATION.E0100.sjs

// Remove blank spaces
String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,'');}

const PADDING_LEFT = 0;
const PADDING_RIGHT = 1;

// Function to add characters before or after the source based on the parameters
function padString(source,length,direction,character) {
   var loop;
   var output = "";
   var sourceLength = 0;
   if (typeof(source) != 'string'){
      source = source.toString();
   }

   set('V[z_source]',source.trim());
   if(z_source) {
      sourceLength = z_source.length;
   }
   
   switch(direction) {
   case PADDING_LEFT:
      for(loop = 0; loop < (length - sourceLength); loop++) {
         output += character;
      }
      output = output + z_source;

      break;
      
   case PADDING_RIGHT:
      for(loop = 0; loop < (length - sourceLength); loop++) {
         output += character;
      }
      output = z_source + output;
      break;
   }
   return output;
}

// Function to return the padded value based on the character value passed
function padValueWithChar(param){
   z_temp = padString(z_value,10,0,param.mychar);
   set('V[z_padded_value]','&V[z_temp]');
   return;
}

// User Interface
clearscreen();
inputfield([1,0], "Enter Value", [1,16], {"size":10, "name":"z_value"});
inputfield([2,0], "After Padding", [2,16], {"size":10, "name":"z_padded_value", "readonly":true});
pushbutton([3,0], "Pad Value", {"process":padValueWithChar, "using":{"mychar":"0"}});


See attachments for code samples!

74
Purpose:
Insert and retrieve values from an array using Key/Value pairs.

Liquid UI Code:

// SAPLSMTR_NAVIGATION.E0100.sjs

// Retrieve Material Descriptions
function showMatlDescs(){
   for(i=0;i<matDataArr.length;i++){
      matl_table.z_matl_desc[ i] = matDataArr[ i].value;
   }
   return;
}

// User Interface
clearscreen();
// Liquid UI table and columns
table([1,1],[20,50], {"name":"matl_table", "title":"Material Info", "rows":20});
column('Material', {"table":"T[Material Info]", "name":"z_matl", "readonly":true, "position":1, "size":15});
column('Description', {"table":"T[Material Info]", "name":"z_matl_desc", "position":2, "size":30});
pushbutton([21,1], "@01@Retrieve Material Descriptions", {"process":showMatlDescs});

// Sample Materials and Descriptions
var matDataArr = [];
for(i=1;i<=20;i++){
   matDataArr.push({key:'Material '+i+'',value:'Description '+i+''});
}

// Populating table with Material numbers
for(i=0;i<matDataArr.length;i++){
   matl_table.z_matl[ i] = matDataArr[ i].key;
}


See attachments for code samples!

75
WS aka Web Scripts (Attended RPA for SAP) / Key/Value Pair Validation
« on: July 25, 2016, 05:01:38 PM »
Purpose:
Perform data validation using key value pair logic.

Liquid UI Code:

// SAPLSMTR_NAVIGATION.E0100.sjs

// Data Validation Array in Key/value pairs
var requiredDataArr = [{key:'Material',value:z_material},
                  {key:'Vendor',value:z_vendor},
                  {key:'Division',value:z_division},
                  {key:'EAN Category',value:z_ean_cat},
                  {key:'Season',value:z_season}];   

// Function to trim blank spaces at the end of the string
String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,'');}
                     
// Function to check if the string value is blank
function isBlank(jvar){
   if(typeof jvar == 'string') {
      jvar = jvar.trim();
   }
   if(typeof jvar == 'undefined') {
      jvar = '';
   }
   return(jvar == 'undefined' || jvar == undefined || jvar == null || jvar == "" || jvar == void 0);
}

// Function is used to check if value is blank for a any key in the array
// If value is blank, then returns the key associated with the blank value
function isBlankKeyValue(arr){
   for(i=0;i<arr.length;i++){
      if(isBlank(arr[ i].value)){
         return arr[ i].key;
      }   
   }   
   return null;   
}

// Function to validate required fields                     
function validateRequiredData(){
   var validateReqData = isBlankKeyValue(requiredDataArr);
   if(!isBlank(validateReqData)){
      message('E: '+validateReqData+ ' is required field');
      goto SCRIPT_END;
   }      
   message('S: Validation successful');
   SCRIPT_END:;   
}

// User Interface
clearscreen();
inputfield([1,0], "Material", [1,25], {"size":10, "name":"z_material", "required":true});
inputfield([2,0], "Vendor", [2,25], {"size":10, "name":"z_vendor", "required":true});
inputfield([3,0], "Division", [3,25], {"size":2, "name":"z_division", "required":true});
inputfield([4,0], "EAN Category", [4,25], {"size":2, "name":"z_ean_cat", "required":true});
inputfield([5,0], "Season", [5,25], {"size":2, "name":"z_season", "required":true});
pushbutton([7,7],"@01@Read Data", "?", {"process":validateRequiredData});


See attachments for code samples!

Pages: 1 ... 3 4 [5] 6 7