Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Noel_Munday
Product and Topic Expert
Product and Topic Expert

User story

You are the administrator of an SAP Analytics Cloud tenant and you notice a growing number of PRIVATE VERSIONS in the system. You see the need for some housekeeping tasks to potentially purge old private versions which are no longer in use but you are faced with a few challenges:

  1. Although you have the technical capability in SAP Analytics Cloud to manage these versions you don't necessarily have the business knowledge/data ownership to make the decision whether the version may be deleted
  2. A governance process will be required to ensure that approval is obtained first from an authorised user before deleting data
  3. The end user(s) themselves may not even be fully aware of the number of private versions that they have created, how large their data volumes are or how old the data is. Simply asking for permission to purge old data may first lead to a discussion about what data is under review.
  4. There is a risk that a private version that a user worked on should have been published and they have neglected to do so.

The following Analytic Application demonstrates how using the version management API's can assist end users in mass deleting their own private versions.

NOTE: This application can be extended to include the CREATION DATE of versions and by calculating the age of the version could trigger email- and other notifications to the end users. You can also make use of the collaboration tools for commentary and discussions to manage versions effectively.

With the correct authorisations you can navigate to "PRIVATE VERSIONS STATISTICS AND ANALYSIS" from the menu option "SYSTEM" --> "PERFORMANCE".

One of the dashboard items on this page lists the versions found in the system together with various attributes of the version and a column named "VERSION STATUS". An "ACTIVE" version exists when it is loaded into HANA memory (considered HOT data) and is being actively edited by users. An "INACTIVE" version is automatically unloaded from HANA memory and stored on disk during a daily end-of-day process.

Although these versions do not occupy HANA memory they do take up disk space and their size is indicated by the number of rows they contain.

 

Analytic Application

This Analytic Application demonstrates:

  1. A method to show end users when they have unpublished public version data while they are making changes to the public version
  2. A method for end users to view a list of their private versions and the ability to perform a "mass deletion"

You can download the application from github using this link.

Version management SAP help documentation can be found here:
SAP Help documentation - Version management
and a couple of blogs to answer FAQ:
https://blogs.sap.com/2022/10/14/sap-analytics-cloud-private-versions-statistics-and-analysis/
https://blogs.sap.com/2022/07/06/faq-version-management-with-sap-analytics-cloud-part-i-basics/#10

 

Private version management

To setup an example we use VERSION MANAGEMENT and select the "ACTUAL" version as a source in order to copy the data to ten private versions. We can visualise the data in a table by displaying them side-by-side.

The story is designed to display an icon in the top right-hand corner of the tabstrip as a visual indicator to the user that a private version(s) exist. The user can manage these versions by navigating to the HOUSEKEEPING tab of the tabstrip.

The icon is uploaded as an image and the method ".getPrivateVersions()" is used to return an array of the private versions in the model. The length of the array is then checked in order to determine if the icon should be displayed or not.

 

// Return a list of private versions and if the list is not empty
// display the private version icon to the user

PrivateVersions = Table_1.getPlanning().getPrivateVersions();

if (PrivateVersions.length > 0) {

	IconPvtVer.setVisible(true);

} else {

	IconPvtVer.setVisible(false);

}

// The variable "PrivateVersions" is of type PLANNINGPRIVATEVERSION
// and is set as an array

 


As soon as the user navigates to the HOUSEKEEPING tab (1) a script is triggered by the "onSelection" event which populates the first listbox (2) with all the private version ID's which belong to the user and the total number of versions is displayed in the textbox below the listbox.

The first listbox (2) is a multi-selection listbox so the user can select any combination of rows and whichever rows are selected are displayed in the second listbox (3) as a confirmation of the selection.

The user can then press the DELETE button (4) to "mass delete" all the versions that they have selected.

 

// Obtain a list of private versions in the system

PrivateVersions = Table_1.getPlanning().getPrivateVersions();

// Clear the listbox of any prior values

ListBox_1.removeAllItems();

// Populate the listbox with the private versions ID's

for (i = 0; i < PrivateVersions.length; i++) {

  ListBox_1.addItem(PrivateVersions[i].getDisplayId(), PrivateVersions[i].getDisplayId());

}

// Set the text at the bottom of the listbox to indicate the number of rows added

Text_2.applyText("Total number of version(s) = " + ConvertUtils.numberToString(i));

 


As the items in the first listbox are selected the second listbox is populated with the selection using the "onSelection" event of listbox1.

 

// When the user executes multi-selection in the first listbox
// remove the items in the second listbox and populate it with
// the new selection from the user

ListBox_2.removeAllItems();

strSelectedVersions = ListBox_1.getSelectedKeys();

for (i = 0; i < strSelectedVersions.length; i++) {

	ListBox_2.addItem(strSelectedVersions[i]);

}

 


The delete button on listbox2 activates a popup screen which will be used to ask for confirmation.

 

// This button allows the user to delete private versions but
// before they do open a popup window to ask for confirmation first

Popup_1.open();

 

To prevent accidental deletions a popup confirmation screen is first displayed with the default button set to "CANCEL". However, on confirmation by the user all the selected versions are deleted and the listboxes and planning screen icon are reset.

 

// If the confirmation button in the popup is selected then
// show the "busy indicator" as the system loops through the users
// version selection and deletes each one

if (buttonId === "btOK") {

	if (strSelectedVersions.length > 0) {

	Popup_1.showBusyIndicator("Deleting...");

	for (i = 0; i < strSelectedVersions.length; i++) {
	   Table_1.getPlanning().getPrivateVersion(strSelectedVersions[i]).deleteVersion();

	}

    // Remove the string array items which are used to populate the selection listbox
    // It is not enough to set the array values to "" as the length of the array is used
	// to determine the deletion loop. The array itself must have each item removed.

    for (i = 0; i < strSelectedVersions.length; i++) {

	   strSelectedVersions.pop();

	}		

	Popup_1.hideBusyIndicator();

	}

}

// Before closing the popup window refresh the two housekeeping listboxes with the 
// version lists after the deletion has occurred

ListBox_2.removeAllItems();

PrivateVersions = Table_1.getPlanning().getPrivateVersions();

ListBox_1.removeAllItems();


for (i = 0; i < PrivateVersions.length; i++) {

  ListBox_1.addItem(PrivateVersions[i].getDisplayId(), PrivateVersions[i].getDisplayId());

}

Text_2.applyText("Total number of version(s) = " + ConvertUtils.numberToString(i));

Popup_1.close();

 


The effect of the mass deletion can be seen when the user selects the "PLANNING" tab once again. In the right-top corner of the screen we see the PRIVATE VERSION icon (1) indicating that there are still private versions in our model. The data block reflects both our public version ACTUAL and the remaining private versions (2) in the columns.

 

Unsaved public version data (Bonus material as it's loosely related)

Introduction

The following paragraph explains the use of a "publish data" icon on the face of the story as an enhancement to using the PUBLISH DATA menu option.

The benefit of the icon is that it is a visual indicator on the face of the story drawing the users attention to the fact that there is unpublished data and it is slightly more convenient to simply press the icon to publish than using the menu option.

It relates to managing PRIVATE VERSIONS in the sense that unpublished data of a PUBLIC VERSION is considered a special case of a private version.

 

Application

This application opens with a canvas which contains a tabstrip with two tabs (1), one for PLANNING and one for HOUSEKEEPING.

A USER EDITING icon (2) has been added which turns green when all data is published and amber if there is any unpublished data on the public version.

A very simple planning data model serves as a datasource to an input table which has been prepared with sample data captured against public version "ACTUAL" (3).

Noel_Munday_0-1708678578264.png

As soon as data is manually edited in the table the USER EDITING icon (1) turns to amber indicating to the user that there is unpublished data and the normal system response displays an asterisk (*) character after the version header (2) and highlights on cells that have been recently modified.

Noel_Munday_1-1708678578265.png

Selecting "VERSION MANAGEMENT", under the TOOLS menu option, we can see that the data from the "ACTUAL" version (1) has been copied to a PRIVATE VERSION indicated by "EDIT MODE" (2).

Noel_Munday_2-1708678578262.png

 

Noel_Munday_3-1708678578266.png

 

If the user never publishes the changes they will remain in the "EDIT MODE" version of the data which is considered a PRIVATE VERSION and never integrated back into the originating public version.

Noel_Munday_4-1708678578267.png

 

The conventional way to publish (save) this data back to the public version is to use the menu option where the "PUBLISH DATA" button will be active.
Noel_Munday_5-1708678578268.png

 

In our analytic application the amber image is "clickable" and also publishes the data by calling the appropriate API
Noel_Munday_6-1708678578269.png

 

After publishing the data the image reverts to it's green status so the user is always aware if there is any unpublished data in the version they are working onNoel_Munday_7-1708678578270.png

 

To enable this functionality we upload two icon images which are identical except for the background colour and we position them on top of each other in the canvas design. We then check the status of the version using and API, which returns a boolean result, and use this to toggle which icon should be visible.

In this example I've hardcoded the public version to "ACTUAL" and this will need to be extended in a live system to be dynamic.

 

// Check to see if the public version is dirty and if so select

// the appropriate icon to display to the user

if (Table_1.getPlanning().getPublicVersion("Actual").isDirty()) {
	IconEditDirty.setVisible(true);
	IconEditClear.setVisible(false);
} else
	{ 
      IconEditClear.setVisible(true);
      IconEditDirty.setVisible(false);
	}

 

Only the icon with the background colour of amber has an "onClick" event activated with the publish API.

 

// Allow the user to click the icon for unpublished data in order to
// publish it. This is for convenience as opposed to selecting the menu option.

Table_1.getPlanning().getPublicVersion("Actual").publish();

 

 

3 Comments