Skip to Content

Hi there,

I’ve been wanting to write this blog since May last year, but both time and various issues have forced me to postpone it a number of times. But finally we are here!

I’ve worked on a number of Screen Personas implementations and one of the things that i find a lot of projects are lacking in Screen Personas and also in general UX projects such as SAPUI5 or Fiori is the measure of success.

There are various ways of measuring success such as

  • Success rate (How many completed the task successfully)
  • Number of objects created (Are we creating more than before the UX project)
  • Measure time spent in transaction
  • Number of errors
  • Amount of support calls

To more intagible ones such as

  • Satisfaction
  • Happiness

I want to show you how to measure the time spent in transactions more precisely on a larger scale than just sitting next to a person with a stopwatch. Equally important to measure after is measuring before your implementation, so you have a baseline.

What I will show you today is a Screen Personas script that works in SAPGUI for Windows, so you will be able to measure your users even before they start with Personas. Because let’s be honest, it’s literally impossible to persuade a group of users to use the webgui for an extended amount of time without a proper carrot and telling them you need a baseline for success simply isn’t cutting it.

So for this little piece to work, we have to import a couple of function modules and one structure:

  • One for getting a timestamp (As the Date javascript object isn’t supported in SAPGUI for Windows)
  • One for actually logging the measurement.
  • Structure for exporting the timestamp

We will be using Screen Personas’ own measurement analytics which Sebastian Steinhauer wrote a good blog about last year. The problem here was that just didn’t work inside SAPGUI for Windows. First of all because of the Date object and secondly because for some reason the logging isn’t functioning either. I have spoken to SAP about this and latest i’ve heard is that they are trying to fix this by May 2017 in SP05. (SAP disclaimer is in order here 😉

I’ve added all the source code to Github  You can use Lars Hvam’s excellent tool ABAPGIT to get it into your SAP system.

Once that’s out of the way, then we are on to the fun stuff.

For the measurement tools to work in SAPGUI For Windows, you still need to create a flavor, you don’t change anything in the flavor except the execution of measurement analytics. In my example i will be using SU01.

So head on over to SU01 in your system and go to the change screen of a user. Create a new flavor and create a new script called “Start”.

Import the following code:

//First we get some info to add to the measurement table
var tcode = session.info.transaction;
var flavorId = session.info.flavorId;

//We call the function module to get the timestamp, this is because SAPGUI doesn't support the Date object
var rfc = session.createRFC("ZPERSONAS_ANALYTICS_GET_TIMEST");
rfc.requestResults(JSON.stringify(["ES_TIMESTAMP"]));
rfc.send();
var timestampStruc = JSON.parse(rfc.getResult("ES_TIMESTAMP"));

//We store the info in the session to be used in a later script
session.utils.put("tcode", ""+tcode);
session.utils.put("flavorId", flavorId);
session.utils.put("time.start", ""+timestampStruc.TIMESTAMP);

 

Now add another script called “Stop”

Add the following code to that:

//First we get the timestamp for when we end the transaction
var rfc2 = session.createRFC("ZPERSONAS_ANALYTICS_GET_TIMEST");
rfc2.requestResults(JSON.stringify(["ES_TIMESTAMP"]));
rfc2.send();
var timestampStruc2 = JSON.parse(rfc2.getResult("ES_TIMESTAMP"));

var timestop = timestampStruc2.TIMESTAMP;
var timestart = parseFloat(session.utils.get("time.start"));
var tcode = session.utils.get("tcode");
var flavorId = session.utils.get("flavorId");

//Get the timedifference between the start and stop.
var timeelapsed = timestop - timestart;

// Name information, which is required 
var firstDataName   = 'currentApplication'; 
var secondDataName  = 'currentScreen'; 
var thirdDataName   = 'currentFlavor'; 

// Get required information 
var firstDataValue  = session.info.transaction; 
var secondDataValue = session.info.screenNumber; 
var thirdDataValue  = session.info.flavorId; 

// Combine appropriate name and information into data 
var nameValueSeparator = ':'; 
var firstData = firstDataName.concat(nameValueSeparator, firstDataValue); 
var secondData = secondDataName.concat(nameValueSeparator, secondDataValue); 
var thirdData = thirdDataName.concat(nameValueSeparator, thirdDataValue); 

// Combine all data into one string 
var dataSeparator = ','; 
var measurement = JSON.stringify({tcode : tcode, flavor : flavorId, timestart : timestart, timestop : timestop, timeelapsed : timeelapsed});
var measurementData = 'tcode:' +tcode +',flavor:' +flavorId +',timestart:' +timestart +',timestop:' +timestop +',timeelapsed:' +timeelapsed;

// Call RFC 
var oRFC = session.createRFC("Z_PERSONAS_GUI_MEASURE"); 
oRFC.setParameter("IV_MSPNT_ID", 'TIMEINTRANSACTIONGUI');  // setting the measuring point parameter 
oRFC.setParameter("IV_MS_DATA", measurementData); 
oRFC.send(); 
session.findById("wnd[0]/tbar[0]/btn[11]").press();

 

That’s all the scripts we need. Now go into edit mode on the flavor and set the start script into the OnLoad event.

Secondly we need to replace the save button with a new scriptbutton with the same icon, this is also due to a limitation in SAPGUI for Windows.

Add the stop script to the onclick event

 

Alright that’s all in the flavor. Now head to transaction /personas/admin. Click the GoTo –> Whitelists –> FM Whitelist

Add the following Function modules to the list

ZPERSONAS_ANALYTICS_GET_TIMEST
Z_PERSONAS_GUI_MEASURE

Save your entries and go back to the /personas/admin main screen.

Click the GoTo –> Analytics –> Measurement Analysis

Click the button. Create a new measurement point called TIMEINTRANSCTIONGUI.

Now that’s all folks! Easy Piecy.

Now when you go in and edit a user in SU01, the timer will start as soon as you enter the transaction and stop and log the time once the user saves his work, meaning a successful process.

To view the results you go to the /personas/admin transaction and  click GoTo –> Analytics –> Measurement Analysis.

Add TIMEINTRANSCTIONGUI in the measurement point input field and press search. You will see all the successfully logged measurements and you can filter the table and export to Excel to make some analytics over there.

This last bit is optional if you want a bit funky looking stuff for your measurements table inside Screen Personas.

Go to the /personas/admin transaction and  click GoTo –> Analytics –> Measurement Analysis.

Add TIMEINTRANSCTIONGUI in the measurement point input field and press search.

Create a new flavor and add a HTML viewer element to the flavor. Next add a new script to the flavor and call it “Display_analytics” paste the following code in

//Get the table
var selectedTable = session.findById("wnd[0]/usr/cntlGRID_CONTAINER/shellcont/shell");
//Get the Column IDs
var columns = selectedTable.columns;
//Variable where table contents will be copied
var contents = [];
if (selectedTable.rowCount > 0) {
    //Set the visible row to 0
    selectedTable.firstVisibleRow = 0;
    //Get the Max visible row number
    var topRow = selectedTable.visibleRowCount - 1;
    //Loop through all the rows
    for (var rowIndex = 0; rowIndex < selectedTable.rowCount; rowIndex++) {
        var row = {};
        if (rowIndex > topRow) {
            // Set the first visible row to the next set of rows. If the next set goes beyond the maximum rows,
            // adjust it so that the set's last row is the table's last row.
            if (topRow + selectedTable.visibleRowCount > selectedTable.rowCount) {
                selectedTable.firstVisibleRow = selectedTable.rowCount - selectedTable.visibleRowCount;
            } else {
                selectedTable.firstVisibleRow = topRow + 1;
            }
            topRow += selectedTable.visibleRowCount;
        }
        // Populate the row information.
        for (var i = 0; i < columns.length; i++) {
            var colName = columns.elementAt(i).name;
            row[colName] = selectedTable.getCellValue(rowIndex, colName);
        }
        // Break after the first blank row - the values usually contain all underscores like "____" for a 4 character column.
        if (!row[columns.elementAt(3).name].replace(/_/g, "")) {
            break;
        }
        contents.push(row);
    }
}

for (var i = 0; i < contents.length; i++){
	var sum = 0;
	for (var c = 0; c < contents.length; c++){
		sum = sum + parseFloat(contents[c].TIMEELAPSED);
	}
	var Average = sum / contents.length;
	console.log(Average);
	contents[i].AVERAGE = Average;
	contents[i].DATETIME = contents[i].DATE +" " + contents[i].TIME;
}

var chartHTML = '<html> <head>'; 
chartHTML += '<script id="sap-ui-bootstrap"'
chartHTML += 'type="text/javascript"'
chartHTML +='src="/sap/public/bc/ui5_ui5/1/resources/sap-ui-cachebuster/sap-ui-core.js"'
chartHTML +='data-sap-ui-theme="sap_goldreflection"'
chartHTML +='data-sap-ui-libs="sap.ui.core,sap.ui.commons,sap.viz">'
chartHTML +='</script>';


chartHTML +='<script>';
// some business data

chartHTML += 'var oModel = new sap.ui.model.json.JSONModel({businessData:' + JSON.stringify(contents) + '});';

// A Dataset defines how the model data is mapped to the chart
chartHTML += ' var oDataset = new sap.viz.ui5.data.FlattenedDataset({\
   dimensions : [ \
       {\
            axis : 1, \
           name : "Date", \
            value : "{DATETIME}"\
       } \
   ],\
   measures : [ \
       {\
            name : "Time",  \
            value : "{TIMEELAPSED}"    \
      },\
	  {\
            name : "Average",  \
            value : "{AVERAGE}"    \
      }\
   ],\  data : {\
       path : "/businessData"\
  }\
});';
// create a Donut chart 
/*chartHTML += ' var oBarChart = new sap.viz.ui5.Combination({\
  width : "100%",\
  height : "200px",\
  plotArea : {\
	 dataLabel: {\
         visible: true \
      }\
  },\
  title : {\
       visible : true,\
       text : "Measurement Point graph"\
  },\
	valueAxis: { \
         title: { \
			 visible: true\
			} \
		}, \
    categoryAxis: { \
         title: { \
             visible: true \
		} \
    },\
 dataset : oDataset\
  });';
*/
	
chartHTML += ' var oVizFrameCol = new sap.viz.ui5.controls.VizFrame({ \
			height : "400px", \
			width : "100%", \
			vizType : "combination", \
		}); \
	oVizFrameCol.setVizProperties({ \
				title : { \
				visible :"true", \
				text : "Measurement Point chart" \
				} \
		}); \
		oVizFrameCol.setDataset(oDataset); \
		oVizFrameCol.setModel(oModel);\
		var feedPrimaryValuesc = new sap.viz.ui5.controls.common.feeds.FeedItem({ \
			"uid" : "valueAxis", \
			"type" : "Measure", \
			"values" : ["Time", "Average"] \
		}); \
		var feedAxisLabelsc = new sap.viz.ui5.controls.common.feeds.FeedItem({ \
			"uid" : "axisLabels", \
			"type" : "Dimension", \
			"values" : ["Date"] \
		}); \
		oVizFrameCol.addFeed(feedPrimaryValuesc); \
		oVizFrameCol.addFeed(feedAxisLabelsc); \
		var oPopoverc = new sap.viz.ui5.controls.Popover({}); \
		oPopoverc.connect(oVizFrameCol.getVizUid()); \
		oVizFrameCol.setVizProperties({\
                    plotArea: { \
                        dataLabel: { \
                            visible: true \
                        } \
                    } \
                }); \
		oVizFrameCol.placeAt("content"); '; 


// attach the model to the chart and display it
/*chartHTML += ' oBarChart.setModel(oModel);\
  oBarChart.placeAt("content");';
  */

chartHTML += '</script>';
chartHTML += '</head>';
chartHTML += '<body class="sapUiBody" supportedthemes="sap_corbu" role="application">';
chartHTML += '<div id="content"></div>'
chartHTML += '</body></html>';

session.findById("wnd[0]/usr/htmlViewerPersonas_147381051051473").content = chartHTML;


 

Go the the very last line of the script and use the Object selector to select your HTML viewer. Substitute the ID of my HTML viewer with yours otherwise this won’t work.

Lastly just in case, doublechek the line that says:

chartHTML +=’src=”/sap/public/bc/ui5_ui5/1/resources/sap-ui-cachebuster/sap-ui-core.js”‘

You want to make sure you are pointing to the right SAPUI5 source file.

Now go back to edit mode of the flavor and add a new script button and call it “Load Graphics”. Add the script to the click event.

You will end up with something like this:

You can filter the table and then press the load graphics again to show the details you want. This shows you all the entries with an average cut across it.

If you want to make this into more of a time series graph, please add the script to the comments of this blog as i would love to see that 😉

That’s all from me for this time, i really hope you will use this as i believe it can be an essential part of measuring the success of your Screen Personas project as well as really persuading doubters that this excellent tool is worth while.

 

Lastly i want to thank a few people for helping me out on this endeavour

Dominik Ofenloch from the Screen Personas Development Team for giving me a sample of the code to add the measurements inside SAPGUI.

Sebastian Steinhauer for the original blog, which inspired me to do this.

To report this post you need to login first.

1 Comment

You must be Logged on to comment or reply to a post.

Leave a Reply