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:
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.
This Analytic Application demonstrates:
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
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.
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.
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).
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.
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).
|
|
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.
| 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. |
| In our analytic application the amber image is "clickable" and also publishes the data by calling the appropriate API |
| 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 on
|
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();
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
28 | |
27 | |
14 | |
13 | |
12 | |
11 | |
10 | |
7 | |
7 | |
6 |