Quantcast
Channel: SAP BusinessObjects Design Studio
Viewing all 662 articles
Browse latest View live

Design Studio 1.3 Joining Arrays of multiple Datasources + Looping Arrays + Filter Datasource by Member

$
0
0

In this example i'm giving you a quick overview of how joining arrays and looping through them could be done. This is demonstrated by an onselect Event of a Dropdown component which is dynamically filled in the onstartup Event.

 

 

First Go to Tools > Preferences open the Scripting Section on the left side of the screen and click on Templates.Now import the attached template file if it isn't integrated by default.

 


Now select the onstartup Event of your pagebook and fill in the script code below. Replace "DIMENSION" with the Dimension (technical name) you want to be filled in the Dropdown component. The script joins two arrays of different datasources and checks whether an element is already in the list or not.

 

 

var check = 0;
var kpis_ds1 = DS_1.getMembers("DIMENSION", 10);
kpis_ds1.forEach(function(kpi1, index) {
DROPDOWN_2.addItem(kpi1.internalKey, kpi1.text);
});
var kpis_ds2 = DS_2.getMembers("DIMENSION", 10);
kpis_ds2.forEach(function(kpi2, index) {       kpis_ds1.forEach(function(kpi1, index) {       if(kpi1==kpi2){             check=1;       }       });       if(check!=1){             DROPDOWN_2.addItem(kpi2.internalKey, kpi2.text);       }       check=0;
});

 

After this is done select the Dropdown Box, edit the onselect Event and fill in the following script.

 

 

var x = DS_1.getMembers("DIMENSION", 10);             //DS_1 Datasource

x.forEach(function(element, index) {
  if(element.text == DROPDOWN_2.getSelectedValue()){         DS_1.setFilter("DIMENSION", element);  }
});

 

That's it. You now have a dynamically filled Dropdown component which is filtering the choosen dimension of your datasource.

Have fun coding!


How to get "Top X" our of resultset

$
0
0

Purpose

You want to get top X from result set based on some measure.

 

Background

Design Studio does not support yet Top / Bottom X out of the box (BEx Conditions) and for non BW Data Sources sometimes you do not have access..

 

Demo as Animated GIF (click to animate)

20140912-150922_capture.gif

 

Idea

The idea is based on two functions in design studio:

 

1) getMembers()

2) getDataCell()

 

In short, we can ask the detasource for all members.

Then by loop on all members (of course you should not have a query of millions data entries..) and ask for a data cell. the data cell will be returned always (if read mode is booked values) or will be empty (read mode all).

with simple comparison you can filter out the top5 as in example.

 

Bottom5 can be achieved in similar way, just the checks must be changed.

 

Script

 

var allMembers = DS_1.getMembers("0BC_PERS1", 9999);
// initialization of all variables
var top1 = 0.0;
var top2 = 0.0;
var top3 = 0.0;
var top4 = 0.0;
var top5 = 0.0;
var top1CellInternalKey = "";
var top2CellInternalKey = "";
var top3CellInternalKey = "";
var top4CellInternalKey = "";
var top5CellInternalKey = "";
var top1CellMemberDescription = "";
var top2CellMemberDescription = "";
var top3CellMemberDescription = "";
var top4CellMemberDescription = "";
var top5CellMemberDescription = "";
allMembers.forEach(function(member, index) {  var memberKey = member.internalKey;  var memberText = member.text;    var dataCell = DS_1.getData("4FW8C4WXM3HULQ4M1YPFT79EF", {  "0BC_PERS1": memberKey  });    if(dataCell.formattedValue != "") {  var value = dataCell.value;  // if bigger, move all  if(value > top1) {  top5 = top4;  top4 = top3;  top3 = top2;  top2 = top1;  top1 = value;  top5CellInternalKey = top4CellInternalKey;  top4CellInternalKey = top3CellInternalKey;  top3CellInternalKey = top2CellInternalKey;  top2CellInternalKey = top1CellInternalKey;  top1CellInternalKey = memberKey;  top5CellMemberDescription = top4CellMemberDescription;  top4CellMemberDescription = top3CellMemberDescription;  top3CellMemberDescription = top2CellMemberDescription;  top2CellMemberDescription = top1CellMemberDescription;  top1CellMemberDescription = memberText;  }  // if bigger, move all  else if(value > top2) {  top5 = top4;  top4 = top3;  top3 = top2;  top2 = value;  top5CellInternalKey = top4CellInternalKey;  top4CellInternalKey = top3CellInternalKey;  top3CellInternalKey = top2CellInternalKey;  top2CellInternalKey = memberKey;  top5CellMemberDescription = top4CellMemberDescription;  top4CellMemberDescription = top3CellMemberDescription;  top3CellMemberDescription = top2CellMemberDescription;  top2CellMemberDescription = memberText;  }  // if bigger, move all  else if(value > top3) {  top5 = top4;  top4 = top3;  top3 = value;  top5CellInternalKey = top4CellInternalKey;  top4CellInternalKey = top3CellInternalKey;  top3CellInternalKey = memberKey;  top5CellMemberDescription = top4CellMemberDescription;  top4CellMemberDescription = top3CellMemberDescription;  top3CellMemberDescription = memberText;  }  // if bigger, move all  else if(value > top4) {  top5 = top4;  top4 = value;  top5CellInternalKey = top4CellInternalKey;  top4CellInternalKey = memberKey;  top5CellMemberDescription = top4CellMemberDescription;  top4CellMemberDescription = memberText;  }  // if bigger, move all  else if(value > top5) {  top5 = value;  top5CellInternalKey = memberKey;  top5CellMemberDescription = memberText;  }  }
});
LISTBOX_1.removeAllItems();
if(top1 > 0.0) {  dataCell = DS_1.getData("4FW8C4WXM3HULQ4M1YPFT79EF", {    "0BC_PERS1": top1CellInternalKey  });    LISTBOX_1.addItem(top1CellInternalKey, top1CellMemberDescription + ": " + dataCell.formattedValue + " ( float: " + Convert.floatToString(top1) + ") ");
}
if(top2 > 0.0) {  dataCell = DS_1.getData("4FW8C4WXM3HULQ4M1YPFT79EF", {    "0BC_PERS1": top2CellInternalKey  });    LISTBOX_1.addItem(top2CellInternalKey, top2CellMemberDescription + ": " + dataCell.formattedValue + " ( float: " + Convert.floatToString(top2) + ") ");
}
if(top3 > 0.0) {  dataCell = DS_1.getData("4FW8C4WXM3HULQ4M1YPFT79EF", {    "0BC_PERS1": top3CellInternalKey  });    LISTBOX_1.addItem(top3CellInternalKey, top3CellMemberDescription + ": " + dataCell.formattedValue + " ( float: " + Convert.floatToString(top3) + ") ");
}
if(top4 > 0.0) {  dataCell = DS_1.getData("4FW8C4WXM3HULQ4M1YPFT79EF", {    "0BC_PERS1": top4CellInternalKey  });    LISTBOX_1.addItem(top4CellInternalKey, top4CellMemberDescription + ": " + dataCell.formattedValue + " ( float: " + Convert.floatToString(top4) + ") ");
}
if(top5 > 0.0) {  dataCell = DS_1.getData("4FW8C4WXM3HULQ4M1YPFT79EF", {    "0BC_PERS1": top5CellInternalKey  });    LISTBOX_1.addItem(top5CellInternalKey, top5CellMemberDescription + ": " + dataCell.formattedValue + " ( float: " + Convert.floatToString(top5) + ") ");
}

Result

in my case I just push all known details to listbox.


Application

You can download the application from:

DesignStudioBiAppRepository/SCN_TOP5_SCTIPT at master · KarolKalisz/DesignStudioBiAppRepository · GitHub


Summary

I know that this is not the "best possible code", but it will work in DS 1.3 SP1 (tested there).

 

have fun.

Design Studio SDK - Get Top/Bottom N rankings with a little less code

$
0
0

The more I thought about Karol Kalisz's creative BIAL example (How to get "Top X" our of resultset) to calculate Top/Bottom 5 rankings, the more annoyed I got that there's not an easier way.    In hindsight, my approach might only be slightly more scalable, but at the cost of SDK voodoo.  I figured I'd try my hand at a component that's just a .ZTL set of methods and see what happens all the same.  Here are the results!

 

To clarify "a little less code" is after writing more code for the sake of less later, if you do a lot of ranking scenarios.

 

The component is called 'Collection' and has one String property called 'items'.  In reality, it's just a storage medium for a JSON structure.

 

So going by Karol's BIAL, I knew I'd need labels and values, so my idea of a structure was an Array of structured objects with labels and values:

 

[     {label : "Apples", value : 10},     {label : "Oranges", value : 5},     {label : "Bananas", value : 20},     {label : "Kiwis", value : 2}
]

This should be enough to keep track of changes as I sort.  What I ended up with was just basically a bunch of ZTL methods to do what we cannot do in BIAL:

 

class com.sample.utilities.Collection extends Component {  void setItems(/*labels*/ String labels, /*values*/ String values) {*  var items = [];  var l = labels.split(",");  var v = values.split(",");  while(l.length<v.length) l.push("");  while(v.length<l.length) v.push("0");  for(var i=0;i<l.length;i++){  items.push({  label : l[i],  value : v[i]  })  }  this.items = JSON.stringify(items);  *}  String getLabels() {*  var s = this.items;  var items = eval(s);  var a = [];  for(var i=0;i<items.length;i++){  a.push(items[i].label);  }  return a.join(",");  *}  String getValues() {*  var s = this.items;  var items = eval(s);  var a = [];  for(var i=0;i<items.length;i++){  a.push(items[i].value);  }  return a.join(",");  *}  void sortByLabel() {*  var s = this.items;  var a = eval(s);  a.sort(function(a,b){  return a.label>b.label;  });  this.items = JSON.stringify(a);  *}  void sortByLabelDescending() {*  var s = this.items;  var a = eval(s);  a.sort(function(a,b){  return (b.label>a.label);  });  this.items = JSON.stringify(a);  *}  void sortByValue() {*  var s = this.items;  var a = eval(s);  a.sort(function(a,b){  var newA = parseFloat(a.value);  var newB = parseFloat(b.value);  return newA-newB;  });  this.items = JSON.stringify(a);  *}  void sortByValueDescending() {*  var s = this.items;  var a = eval(s);  a.sort(function(a,b){  var newA = parseFloat(a.value);  var newB = parseFloat(b.value);  return newB-newA;  });  this.items = JSON.stringify(a);  *}  void sortByValue() {*  var s = this.items;  var a = eval(s);  a.sort(function(a,b){  var newA = parseFloat(a.value);  var newB = parseFloat(b.value);  return newA-newB;  });  this.items = JSON.stringify(a);  *}  int getLength() {*  var s = this.items;  var a = [];  if(s!="") a = eval(s);  return a.length;  *}  String getLabel( /* index */ int index) {*  var s = this.items;  var a = eval(s);  var r = "Blank";  if(a.length>index){  r = a[index].label;  }  return r;  *}  String getValueAsString( /* index */ int index) {*  var s = this.items;  var a = eval(s);  var r = "Blank";  if(a.length>index){  r = a[index].value;  }  return r;  *}  float getValue( /* index */ int index) {*  var s = this.items;  var a = eval(s);  var r = 0.0;  if(a.length>index){  r = a[index].value;  }  return r;  *}
}

As you can see, we can set items and sort by either label or value, ascending or descending.  So what would the BIAL look like in context?

 

We can stage up some dummy data with a BIAL command like this:

 

COLLECTION_1.setItems(  "Apples,Oranges,Bananas,Kiwi",  "10,100,45,4"
);

Or, we can do a test with a data source:

 

bial.png

 

(Syntax highlighting in this blog kept messing up, so here's a screenshot of the code)

 

And finally, I have a button that will sort the collection either ascending or descending:

 

sortbial.png

I'm still annoyed that I can't do a simple for loop in BIAL, but whatever - For each additional ranking it's only one extra line of code.

 

Here's the end result of the exercise:

 

sorted.png

 

And a sample with the dummy unit test without ugly green blocks :  Note the "Blank" entry because there are less items than 5 so it even does some graceful failing - This is an example of Bottom 5 because reverse is unchecked.

 

sorted_testdata.png

Full source will be available next time I update my Utility Pack.  Will update this entry when that happens but 95% of the work happens in the .ZTL file.  This was the first time I bothered doing a lot of the logic in the ZTL and I must say it's not as bad after you know where the Java signature stops and the JavaScript begins

 

Enjoy!

Dynamic selection in Listbox - using Arrays in Design Studio 1.3

$
0
0

More often than not, we get dashboard and report requirements having two or more cascading filters wherein the list of values of one dimension depends on the value chosen in the other. Recently, I came across one requirement – to have a two-level cascading filter with City and Customer and to have the first 10 Customers of the chosen city, selected by default - and hence plotted on a 10-series-chart.

 

Shown below are the two multi-select listboxes.

listbox_img1.png  listbox_img2.png

 

              

In Design Studio, since there is no direct method to retain the first 10 Customers as default selection for a dynamically changing list, I had to think of a workaround – The Arrays feature in DS 1.3 was the perfect solution !

 

The list of cities in the first listbox is static and the customer list in the second (LISTBOX_2) is dynamic – the customer list is filtered by the city selection made in the first. This is the code segment I used, to select the first 10 customers by default.

 

/*Load the first 10 customers in an array variable*/

var arr=DS_1.getMembers("ZR_CUSTOMER", 10);

 

/*Define a string variable*/

var str="";

 

/* Use a forEach loop on the array variable to concatenate the 10 customers, in str*/

  1. arr.forEach(function(element, index)

{

            str=str+element.internalKey+',';

};

 

/*Use split function to split the string into individual values */

LISTBOX_2.setSelectedValues(str.split(','));


The forEach function, requiring two parameters, element and index, simply iterates through all the elements in the array.

 

Note that if you want only the first 3 customers in the array, then use 3 instead of 10.

var arr=DS_1.getMembers("ZR_CUSTOMER", 3);

 

An empty string variable str is used to append the first 10 customers using comma as the delimiter. For every iteration of the forEach loop, the str variable is appended with the internal key of the customer.

 

At the end of 10th iteration the str variable will be

str=customer1,customer2,customer3,.......customer9,customer10

 

Then the string is split into individual elements using str.splitfunction and is used to setSelected Values for LISTBOX_2.

 

Arrays are still primitive in Design Studio 1.3, but they can be capitalized really well through workarounds. This is just one example of how they can be used to easily achieve an often asked functionality.

Scrollable Panel in Design Studio (to show bigger content)

$
0
0

Purpose

I have seen many questions on "scrollable content in design studio", also this requirement, Design Studio - automate table width dependingly to the number of dimensions.

 

Basics

A Panel in Design Studio is visualized by DIV element, it shows by default the content as overlay, no scrolls are available. This can be changed by CSS:

 

the class responsible for this setting is "div.zenborder". you can define new classes, overwritting this one.

 

div.zenborder div.scroll-x {  /* allow X scroll */  overflow-x: scroll !important;  /* do not allow Y scroll */  overflow-y: hidden !important;
}
div.zenborder div.scroll-y {  /* do not allow X scroll */  overflow-x: hidden !important;  /* allow Y scroll */  overflow-y: scroll !important;
}
div.zenborder div.scroll-xy {  /* allow X scroll */  overflow-x: scroll !important;  /* allow Y scroll */  overflow-y: scroll !important;
}
div.zenborder div.hidden {  /* do not allow X scroll */  overflow-x: hidden !important;  /* do not allow Y scroll */  overflow-y: hidden !important;
}

Then, as next poing, you jsut need to assign the new class to the css class propery on the corresponding panel:

 

Capture.PNG

 

or you can make this via script:

 

PANEL_1.setCSSClass("scroll-x");

now, the panel will get scrollbar on X axis:

20140915-190522_capture.gif

Here is the example application:

 

 

I hope this help some of you in your Ux requirements.

Design Studio on HANA - ASUG Webcast

$
0
0

This was an ASUG webcast today with SAP's David Stocker.  Part 1 is Analysis Office on HANA Scenarios - ASUG Webcast

 

The usual SAP legal disclaimer applies that things in the future are subject to change

 

New roadmaps are coming at Las Vegas SAP TechEd && d-code

 

1figdsroadmap.png

Figure 1: Source: SAP

 

Design and runtime enhancements include navigation panel, enhanced scripting, customize crosstabs, Excel-based printing and exporting, enhanced set of components, BEx Query Exceptions support, background query loading, and enhanced charting and visualization

 

With partner and customer SDK, you create custom charts, visualizations and extensions (e.g. commentary)

 

Additional data sources supported include relational .UNX support with .UNX query panel

 

Coming in Design Studio 1.4 is RRI, drag and drop and more shown in the middle of Figure 1

2hana.png

Figure 2: Source: SAP

 

Most Design Studio customers use are using BI platform.

 

When deploy using HANA, no BICS is involved; instead it is pushing off to Information Access Service (aka INA)

 

SAP does not recommend HANA native deployment yet as it is still new, young, INA is new

 

It refreshes on backend on data sources can be parallel

3dsbiphana.png

Figure 3: Source: SAP

 

Missing: Calculated Measures and Exceptions

4expectedlimitationshana1.4.png

Figure 4: Source: SAP

 

Figure 4 covers expected limitations with Design Studio 1.4 HANA deployment.

 

There is no Variable Value help in 1.4.  It should be present in 1.5

 

Export means export to Excel/CSV

 

Question & Answer

Q:  Is Design Studio still on track to be able to use RSBBS jump functionality is the near or far future? (right mouse click, context menu, go to...)

A:  1.4 - enabling context menu - a component - add to document, define jump targets in BIP/BW

________________________________________________________________

Q:  BW Workspaces, Is there any schedule/planning to support non cumulative key figures and IP cubes?

A:  At moment no, space is open

________________________________________________________________

Q:  How does the security work?

A:  It uses the related BW or HANA backend security

________________________________________________________________

 

Q:  Design Studio or Analysis Office, Is there any considerable report performance growth with HANA ? any used cases with/without HANA !

A:  For Design Studio, he pointed out parallel executiion of queries on HANA

________________________________________________________________

Q:  is Table Design going to be only on Native HANA or would it also be available on SAP BW?

A:  Table Design will be available on Analysis 2.0 against BW (some prerequisites apply)

________________________________________________________________

 

Q:  Analysis on office via BICS is limited to the safety belt or cell restriction . Via UNX its not . Will the BICS safety belt be removed for analysis for office. Also will the COM add in restriction be removed .

A:  remove with registry setting

________________________________________________________________

 

Q:  Is bursting possible from analysis office on native HANA?

A:  No, this is not possible

________________________________________________________________

Q:  Do we have any plan integrating Analysis MS Office with Informatica ILM (Information Lifecycle Management) which is Archive DB.

A:  no

________________________________________________________________

Q:  Web Application Designer is able to publish to Portal.  Will Design Studio ever do this?

A:  Design Studio has an iview for the portal today

________________________________________________________________

Q:  Yes, I was asking about Design Studio.

A:  RRI is planned for 1.4

________________________________________________________________

 

 

Q:  Can it publish to a Portal KM folder?

A:  No

________________________________________________________________

 

Q:  Maybe I missed it, is support for drag and drop support for navigation components coming soon for DS 1.4 or later?

A:  Yes that is in the DS 1.4 roadmap slide

________________________________________________________________

 

Q:  Design Studio or Analysis Office, If I have IP(integrated planning)query with planning function, currently its possible to execute manually one by one . However If I have couple of planning sequences(combined) how can we execute all at once ?

A:  Analysis Office can execute via VBA macro; DS is also via script

________________________________________________________________

 

Q:  (Drag and drop at runtime, not design time, to be clear)

A:  Fragments  - draggable, new component, split container, familiar with Lumira > like viz pane from Lumira at runtime

________________________________________________________________

 

Q:  will we able to change measure to dimensions inside analysis for office similar to Web Intelligence

A:  no

________________________________________________________________

Q:  To use Design Studio for BW based customers, what is your recommendation? - Should we use BI platform or directly connect BW? What is the Adv & Disadv over this? Please note we have BWA.

A:  Performance is an issue on BIP; look at deploy at BW but lose the mobility that comes with BIP

________________________________________________________________

 

Related:

Upcoming Design Studio September Events - ASUG has you covered

 

Consider attending SAP TechEd && d-code .  Join ASUG for the ASUG SAP TechEd Pre-conference HANDS-ON: SAP BusinessObjects BI 4.1, SAP BW and SAP BW on SAP HANA – All in One Day, October 20th.  This includes exercises for Analysis Office and SAP BusinessObjects Design Studio. Register today

 

Also see:

Stay Ahead : Attend TechEd && d-code – Win Big SAP BI BusinessObjects HANA Hands-on Sessions

 

Upcoming ASUG webcasts (a subset):

 

Join SAP at the end of October for Reporting & Analytics 2014 INTERACTIVE conference - register here

Design Studio SDK - BIAL for...next loop (and my first GitHub co-author attempt)

$
0
0

In the continued spirit of collaborating with Karol Kalisz, I wanted to see if I could add some additional utility to his new Design Studio SDK: Array Util Component.  This was born out of a need to do things you'd want to do with arrays such as How to get "Top X" our of resultset, for example.

 

Next up is that I wanted to get back a for loop in BIAL.  We have a forEach loop but for loops are not yet allowed.  Karol also added me as a co-author to his GitHub repository (KarolKalisz/DesignStudioSdkPack · GitHub) so I figured I'd see how easy or hard it is to use GitHub as intended as a code check-in and collaboration tool versus just a sharing code site.

 

So, I've enhanced DesignStudioSdkPack/contribution.ztl at master · KarolKalisz/DesignStudioSdkPack · GitHub with a new method called 'eaches' -- This also is an example of how you can markup your ZTL code with some JavaDoc information for your BIAL scripters to know what things do.

 

The code:

 

/**  Generates an array of integers for use in BIAL forEach statement in order to emulate a traditional for loop.  <example>  Fill a list box with 10 values:  <code>ARRAY_1.eachesAsString(0, 9, 1).forEach(function(element, index) {<br>  LISTBOX_1.addItem(element, "Item " + (element + "") );<br>  });</code>  This would be equivalent to a loop in JavaScript:  <code>  for(var element = 0;element<=9;element++){<br>  Your code here.<br>  }  </code>  </example>  */  Array eaches(/*Starting int*/ int start, /* Ending int */ int finish, /* Interval increment */int interval) {*  var a = [];  for(var i=start;i<=finish;i+=interval){  a.push(i);  }  return a;  *}

That's it!  What's it do?  The code documentation is shown above, but it's a bit easier to read during BIAL scripting time:

 

eaches.png

As we can see here, a little effort in documenting will help out your BIAL scripters know what the method does, so as we see in this tooltip, it does (or should do) what I mentioned, which is a for loop.  Let's click the Button and see what the results are at runtime:

 

eaches2.png

Looks like it's working! 

 

As far as my experience with pulling down Karol's repository, that's easy.  I suggest using 'GitHub for Windows' unless you are a big PowerShell fan, the GUI version is very easy to use.  Here's the main interface, with some of my own repos aas well as Karol's:

 

eaches3.png

I right-clicked his repository, and cloned it to a location on my hard drive.  Next, I switched to my Eclipse SDK and went to File -> Import... and browsed to the location and chose the subfolder containing the project I wanted to import.  In this case, it was 'org.kalisz.karol.scn.pack'.  I unchecked 'Copy projects into workspace' since I wanted it to stick with the Git repo clone location.  Below is an example of what an Eclipse project looks like when it senses there is a Git repo associated with it.

 

eaches4.png

 

I then made modifications mentioned at the beginning of the blog to the contribution.ztl file.

 

Once I was done coding and testing on my local repo, I wanted to commit the changes back to Github.  After fumbling around, I found the context menu path to do so:

 

eaches5.png

I was then prompted to describe my change, which I said "Added 'eaches' method to Karol's Array component." and then clicked 'Commit and Push'.

 

When switching back to my GitHub for windows, I could see the changes in the history, as well on on the web.  Success!

 

eaches6.png

 

I'm sure for GitHub veterans, this is child's play but for me this was easier than I expected.  There's a bunch of other stuff I'm sure GitHub is good at doing indicated in the context menu screenshot, but this was good for now

Bookmarking and Personalization

$
0
0

Simulation of the XCelsius Local Scenario Button in Design Studio:

When some of our clients wanted to switch to Design Studio, we had to recreate their  XCelsius dashboards in Design Studio. One feature we really missed was the Local Scenario button in XCelsius. Thankfully, SAP provides Bookmarks and Personalization in DS 1.3.

This is how we used the two new features to simulate the functionality of the Local Scenario button. In XCelsius, this button has options to Save, Load, Delete & Set Default. In Design Studio, Save, Load and Delete can be achieved using the Bookmarking feature and Set Default can be achieved using Personalization. The image below shows the code for each.

XCel to DS.png

 

 

One value addition to this is to save bookmarks with the name of the item(s) selected by the user in a related selector(s). This will help the user relate the bookmark to the scenario. This will come in handy when there are multiple bookmarks saved and the scenario relates to user selected values in multiple selectors. Also, since the bookmark is saved automatically with that name, the user is not required to type the value of the selection or some other name while saving the bookmark.

 

The code below shows how the bookmark is saved with a name based on user selection in the two selectors.

if(DS_2.getFilterText("ZSALES_REGION")=="")

  {

     var a=DS_2.getFilterText("ZSALES_DISTRICT");

     var bm1=Bookmark.saveBookmark(a);

     LISTBOX_1.addItem(bm1,a);   

  }

else

  {

     var b=DS_3.getFilterText("ZSALES_REGION")+"/"+DS_2.getFilterText("ZSALES_DISTRICT");

     var bm2=Bookmark.saveBookmark(b);

     LISTBOX_1.addItem(bm2,b);

    }


Save BK.png


Design Studio - RSADMIN Parameters

$
0
0

In a BW system, the RSADMIN table is used as a configuration table for many processes and functionalities. This table has parameters that define some system configurations, behavior and display of result sets. For instance, when there is division by zero in a BEx Query, the result is displayed as the  symbol ‘X’. This symbol is defined in the RSADMIN table.Similarly, RSADMIN parameters define many other options, like the max no of cells in a result set, message to display for lack of authorization etc.

 

BEx Output – DIV by zero shown as ‘X’


As of Design Studio 1.3, SAP provides options to customize the values of a few RSADMIN parameters, at the Business Objects level. This is done at the Business Objects layer through “Analysis Application Service” APS parameters.  Customizing RSADMIN parameters can help developers and end users by displaying more meaningful text in case of errors in calculation, units or authorizations.

 

Steps to edit RSADMIN parameters


Step 1:

Login to “SAP Business Objects CMC” with an account that has administrator rights.

 

Step 2:

Select the “Servers” option under “Organize”.

 

 

Step 3:

Select “Servers List” to view all the APS servers in the system.

 

 

Step 4:

Select the APS server that hosts the “Analysis Application Service” (or) the one that is configured for Design Studio.

 


Step 5:

Right click on the Design Studio APS and select “Properties”.

 

Step 6:

In “Properties”, search for “Analysis Application Service” and update each RSADMIN value as required.

 

 

Step 7:

Click on “Save and Close” to complete the configuration. Update this across all APS servers configured to process Design Studio requests.

 

Once this is complete, Design Studio applications will show custom values configured in APS servers, when executed in platform mode.


              


Design Time Vs Run Time views of DIV by zero

 

Similarly, for Mixed Units

              

 

Design Time Vs Run Time views of Mixed Units

Happy Learning !

                     

Performance Monitoring In Design Studio

$
0
0

I was recently building an application on Design Studio 1.3, when I faced quite a common problem – the application was taking too long to load. Performance is almost always affected by the time taken to access the datasource and the first step to optimizing the application is to know how fast or slow it currently is. Here are some simple ways to do just that.


Profiling 

The first thing I did to track query loading time was to enable Profiling. This gives a detailed analysis of how long each step takes to load. On execution, the two major steps are

  • Time for data to be fetched from the remote database used (after disabling cache)
  • Java rendering time. (This is when all the components get rendered)

 

Application runtime is the sum of the two.

 

To profile an application, first execute the application from Design Studio, on the BI platform or the NetWeaver platform. At the end of the URL, add ‘&PROFILING=X’ (note that it is case sensitive).

Profiling Link1.JPG

A dialog box opens up with the statistics. It shows total duration (in milliseconds) that the application took to load, Java rendering time and the Remote time.

 

Profiling Check DS1.JPG


Further details about the Java rendering time for each component can be found in the Rendering Statistics tab.

Java Rendering.png



To test the correctness of profiling results, I built applications using BW on HANA and SAP HANA and profiled them. The data size used in both applications was around 30,000 rows.

 

Profiling on BW on HANA:

BW Profiling.JPG



Profiling on HANA:

HANA Profiling.JPG


We can see that applications built on HANA database execute faster(remote loading of 0 ms), than those built on BW on HANA (7719 ms). This is as expected. BW on HANA is a faster alternative to BW on oracle or SQL database for the same known reasons – in memory and columnar storage.

 

Note that the ‘0 ms’ while executing a HANA application does not mean 0 exactly. The lowest time measured on Windows operating systems is 15.6 sec. So for any time period even slightly lower than that, profiling will show 0 ms.

 

Checking accuracy of Profiling

We’ve got our load times from profiling, but we need to make sure that the values displayed are accurate. There are ways to check the accuracy of the numbers by making use of performance analysis tools. We looked at RSRT for NetWeaver connections.

 

Comparing Profiling and RSRT

Before executing the DS application, cache has to be disabled. Otherwise profiling the application will show time taken to bring data from cache only and not the actual database.

Profiling Check RSRT.JPG

Profiling Check DS1.JPG


From the similar values, we can see that Profiling gives a pretty accurate measure of application runtime and data fetch time.


BO AUDITING:

While connecting to a universe, running BO auditing reports will give us time taken for the application to run. BO auditing reports can be accessed / built on top of the auditing universe. As soon as the application is run, details get logged in the auditing universe. The application must be run on the BI platform for it to be logged. Crystal / WebI reports can be built on top of this universe to get the required duration for which the application ran. More on this in upcoming blogs.

SDK development - I want to drag drop in SDK component

$
0
0

Purpose

I hear many questions about drag & drop. I know that there are plans in the product roadmap to introduce the drag and drop functionality, but in the meantime I tried to figure out if this would be possible in a generic way on SDK basis. And the answer is yes!

 

How to do that?

Basically I use SAPIU5 for SDK components, so the question was how to bind drag & drop on UI5 basis. I have found some common implementations in web on how to drag drop DIV elements on the screen. From those I understood that it is easy by attaching events on dom objects. Luckily SAPUI5 has functions for that -

 

oDrop.onAfterRendering = function () {
...
}

here we can access already the dom object and use jQuery to place some additional events. Now, how to pass all the values between drag & drop events. Again some search on web, I have found many points, and one which works... I use a library "jquery.ndd.js (web site here)" which handles better the events. I do not know if this is the best way, but I stopped search once I had something which works.

 

Now, I attached this library in contribution.xml:

 

<jsInclude>res/dda/jquery.ndd.js</jsInclude>

 

and then using the onAfterRendering method I could attach the events. This is my method.

 

Adding Corresponding Events

 

Object which handles "DROP":

 

oDrop.onAfterRendering = function () {  var jqThis = this.$();  jqThis.bind('dragover', function(evt) {   oDrop.addStyleClass("scn-pack-DragDropArea-DropEffect");       evt.preventDefault();    })    .bind('dragleave',function(evt) {   oDrop.removeStyleClass("scn-pack-DragDropArea-DropEffect");          evt.preventDefault();    })    .bind('dragenter',function(evt) {       evt.preventDefault();    })    /** process drop event **/    .bind('drop',function(evt) {   var id = evt.dataTransfer.getData('id');       var key = evt.dataTransfer.getData('key');       var context = evt.dataTransfer.getData('context');       that.setDropId(id);       that.setDropKey(key);       that.setDropContext(context);       that.setDropAfterKey(oDrop.dropAfterKey);       that.setDropIndex(oDrop.dropIndex);             that.fireDesignStudioPropertiesChanged(["dropId"]);       that.fireDesignStudioPropertiesChanged(["dropKey"]);       that.fireDesignStudioPropertiesChanged(["dropContext"]);             that.fireDesignStudioPropertiesChanged(["dropAfterKey"]);       that.fireDesignStudioPropertiesChanged(["dropIndex"]);         that.fireDesignStudioEvent("onDrop");                 evt.stopPropagation();             return false;        });  };

Object which handles "DRAG":

 

oDrag.onAfterRendering = function () {  var jqThis = this.$();  jqThis.attr("draggable", "true");  jqThis.bind('dragstart', function(evt) {  evt.dataTransfer.setData('id', oImage.internalKey);  evt.dataTransfer.setData('key', that.getDragKey());  evt.dataTransfer.setData('context', that.getDragContext());  });
};

The Heart of Drop

The "evt.dataTransfer" property is available by the jQuery extension - I could not get this run w/o the extension. The biggest implementation is in drop event, there all possible properties can be collected and the drop event can be triggered.

 

I thought, as this is a generic idea, I will pass always two parameters "context" and "key" to be able to handle different object types.

What is currently not in my implementation is to show any fancy icons on drop, and block the drop if the contexts are different... But this is room for improvement later.

 

What Next?

Now, I try to finalize my generic DragDropArea - perhaps in 2 hours there will be something in a downloadable package as preview (just to check what the community think about it)

 

I am wondering how this can be used in different contexts...

Animating Design Studio Components using CSS

$
0
0

CSS Animations

High performing animations have become increasingly important, as interactive projects get more aggressive and smart devices have burst into the scene. Widely used JQuery has not been able to handle the onslaught, because it simply wasn’t designed for it. The most widely-acclaimed solution is CSS Animations (and Transitions). With CSS3, we can create animations which can replace flash animations, animated images, and JavaScript in existing web pages.

How are CSS Animations and Transitions done?

An animation lets an element gradually change from one style to another. You can change as many properties you want, as many times as you want. You can specify when the change will happen, in percentages, or you can use the keywords "from" and "to" (which represent 0% and 100%). 0% represents the start of the animation, 100% is when the animation is complete.


What is CSS Key frames Rule?

The @key frames rule is where the animation is created. Specify a CSS style inside the @key frames rule and the animation will gradually change from the current style to the new style.

Animation in SAP Design Studio

 

Let’s take a simple example of a textbox that changes colors and moves along a rectangular transition. The steps to be followed -

1. Create a CSS file with code as shown below

2. The class name for the textbox is, ‘sample’

3. Add the CSS in the Application

4. Add a text box to the center of the canvas(outline)

5. Include the class name ‘sample’ in the textbox

6. Execute to view the transition and animation



CSS Animation Code

.sample {    width: 100px;    height: 100px;    background: red;    position: relative;    /* Chrome, Safari, Opera */    -webkit-animation-name: myfirst;    -webkit-animation-duration: 5s;
-webkit-animation-timing-function: linear;    -webkit-animation-delay: 2s;
-webkit-animation-iteration-count: infinite;    -webkit-animation-direction: alternate;    -webkit-animation-play-state: running;    /* Standard syntax */    animation-name: myfirst;    animation-duration: 5s;    animation-timing-function: linear;    animation-delay: 2s;    animation-iteration-count: infinite;    animation-direction: alternate;    animation-play-state: running;
}
/* Chrome, Safari, Opera */
@-webkit-keyframes myfirst {    0%  {background:red; left:0px; top:0px;}    25%  {background:yellow; left:200px; top:0px;}    50%  {background:blue; left:200px; top:200px;}    75%  {background:green; left:0px; top:200px;}    100% {background:red; left:0px; top:0px;}
}
/* Standard syntax */
@keyframes myfirst {    0%  {background:red; left:0px; top:0px;}    25%  {background:yellow; left:200px; top:0px;}    50%  {background:blue; left:200px; top:200px;}    75%  {background:green; left:0px; top:200px;}    100% {background:red; left:0px; top:0px;}
}

Advantages and Disadvantages of CSS animations

 

  • CSS3 transitions are natively handled by the browser. They will always be faster than a comparable JQuery animation.
  • CSS3 code is petite. Also, you don’t have to create any specific stylesheet for it. You can work on your standard stylesheet.
  • JQuery animation is undoubtedly more difficult with several lines of code, whereas in CSS3, there is a good chance the functionality can be achieved with one property.
  • Rotating elements in 2D or 3D is possible in CSS only
  • Do note that not all browsers support CSS3 animations/transitions. In case you need to support older browsers, JavaScript is the right choice.
  • The most significant advantage is that it works seamlessly on the iPad, iPhone, Android as well as in Safari mac, due to hardware acceleration. JQuery animations are not as smooth, on mobile devices.


Learn about Arrays in Design Studio 1.3

$
0
0

Arrays in Design Studio 1.3

 

With the release of Design Studio 1.3, a host of new features were brought in by SAP. One of the most useful is the concept of Arrays. Though the versatility of this feature is quite limited in this release, SAP has nevertheless offered certain aspects of Arrays that developers can play around with.

 

Considering the rather concise information available in the designer guide, it seemed useful to provide a detailed overview of this feature. So, here goes !

There are 7 different types of arrays available – subtypes of the object “Array”. These include:

 

  • Dimension Array:

This subtype can contain a list of different dimensions belonging to a data source. A dimension array can be created by referencing the “getDimensions()” method of a data source – dimensions belonging to rows, columns, free characteristics or all dimensions available in the data source can be obtained with this method.

1.png

 

  • Hierarchy Array:

This subtype can contain a list of hierarchies. While there is no way for a user to create a hierarchy array manually, it can be created using the “getHierarchies()” method of a data source. This returns a list of different hierarchies available for the dimension that has been passed as parameter to the method.

2.png

 

  • Member Array:

This subtype can contain a list of members belonging to a dimension. It can be created using the “getMembers()” method of a data Source. The method returns a list of members of a dimension as an array. The dimension for which the members are required must be passed as a parameter to the method.

  3.png

  • Bookmark Array:

This subtype can contain a list of all bookmarks for an application. Such a type of Array can be created using the “getAllBookmarks()” method of the “Bookmarks” object. When the method is used, it returns all the available bookmarks for that particular application.

  4.png

 

  • Variable Array:

This subtype can contain a list of variables. It can be created using the “getVariables()” method of a data source. This method returns all the available variables of the data source for which the method is being called.

5.png

 

  • String Array:

This subtype can contain a list of strings. Unlike the previously mentioned types of arrays, a String array can be created manually as well. This is shown in the screenshot below:

6.png

Apart from user customizable string arrays, the “getSelectedValues()” and “getSelectedTexts()” methods of a Multi-Select enabled List Box can also return values in the form of a String Array. Using the “Split()” method will also return a String Array.

 

  • Integer Array:

This subtype can contain a list of integers. This type of an array can also be created manually by users.

  7.png

 

  • Float Array:

This subtype can contain a list of decimal point numbers or floats. This type of an array can also be created manually by users.

  8.png

 

Manipulating elements of an Array

Individual elements of an array can be accessed using the “forEach” loop. The basic syntax for this :

  9.png

The “forEach” loop iterates over each element of an array and executes the statements contained within the body of the loop. In the above syntax:

  • element” refers to the individual elements contained in the array, one at a time.
  • index” refers to the index/position of that particular element within the array.

Each element object has its own set of methods to access attributes of that element, depending on the array type. For instance, when handling a MemberArray, the external keys and internal keys of the elements can be accessed through methods of the “element” object. A list of the different methods available for each type of array has been given below:

 

Array Type

Methods belonging to “element” object

DimensionArray

  1. name– Returns the technical name of the dimension
  2. text– Returns the text (description/display name) of the dimension

HierarchyArray

  1. name– Returns the technical name of the hierarchy
  2. text– Returns the text (description/display name) of the hierarchy

MemberArray

  1. externalKey– Returns the representation of the member as an external key
  2. externalNonCompoundedKey– Returns the representation of the member as an external non-compounded key
  3. internalKey– Returns the representations of the member as an internal key
  4. internalNonCompoundedKey– Returns the representation of the member as an internal non-compounded key
  5. text– Returns the representation of the member as a text (display name)

BookmarkArray

  1. name– Returns the name of the bookmark
  2. text– Returns the text (description/display name) of the bookmark.

VariableArray

  1. inputEnabled– Returns true of the variable is enabled, and false if otherwise
  2. name– Returns the representation of the variable as its technical name
  3. text– Returns the representation of the variable as its display name

StringArray

  1. indexOf– Returns the positions of occurrence of a string being searched for in the array.
  2. length– Number of characters in the array
  3. split– Splits the string according to a given separator
  4. substring– Returns a new string which is a substring of the given string

(It should be noted that the “element” object does not have any methods for an Integer or a Float Array)

Examples of Arrays in use

The program below takes a String array, eliminates the word “WORLD” and returns the remaining elements of the StringArray as one concatenated string, in an application alert window.

10.png

The result of this program is an alert window shown below.

11.png

 

 

Dimension Arrays in Use:

Given below is an example of dimension arrays in use. Consider the dimensions of the data source arranged in the manner shown in the screenshot below:

12.png

The script below exhibits the different ways in which the “getDimensions()” function can be used:

var Dim_Array_Rows = DS_1.getDimensions(Axis.ROWS);

var Dim_Array_Cols = DS_1.getDimensions(Axis.COLUMNS);

var Dim_Array_Free = DS_1.getDimensions(Axis.FREE);

var Dim_Array_All = DS_1.getDimensions();

 

var Rows = "";

var Cols = "";

var Free = "";

var Overall = "";

 

Dim_Array_Rows.forEach(function(element, index) {

Rows = Rows + element.name +" ("+element.text+");";

});

 

Dim_Array_Cols.forEach(function(element, index) {

Cols = Cols + element.name+" ("+element.text+");";

});

 

Dim_Array_Free.forEach(function(element, index) {

Free = Free + element.name+" ("+element.text+");";

});

 

Dim_Array_All.forEach(function(element, index) {

Overall = Overall + element.name+" ("+element.text+");";

});

 

  1. APPLICATION.alert("Dimensions in Row:\n"+Rows+"\n\nDimensions in Cols:\n"+Cols+"\n\nDimensions in Free Characteristics:\n"+Free+"\n\nOverall:\n"+Overall);

 

The script shown in the above window consolidates a list of all the dimensions belonging to the data source, and displays them on an alert window as shown in the output below:

13.png

 

 

Hierarchy Arrays in Use:

Given below is an example of hierarchy arrays in use. Observe the different hierarchies available for the dimension “ZREGION” in the structure of the query shown in the screenshot below:

14.png

The script below simulates a situation where in the hierarchies available in a particular dimension (“ZREGION” in this case) are obtained and displayed on an alert dialogue as soon as the user clicks a button present on the screen:

var Dim_Hierarchy = DS_1.getHierarchies("ZREGION");

 

var Hierarchy = "";

 

Dim_Hierarchy.forEach(function(element, index) {

Hierarchy = Hierarchy + element.name + " ("+element.text+");";

});

 

  1. APPLICATION.alert("Hierarchies Available:\n"+Hierarchy);

The output, if hierarchies are available on the given dimension (which is the case here), should resemble the screenshot shown below:

  15.png

 

(Source: Learn about Arrays in Design Studio 1.3 - Visual BI)

How to Use Extended Sdk Collection to handle "properties"

$
0
0

In order to use fill in the Design Studio SDK: Leader Board Component I had to extend the Design Studio SDK: Collection Util Component by addition of extra generic parameters which can be passed to the collection and used as properties.

 

Now, you can use a new method which is returning an array with additional properties:

 

Scripting Functions

 

ScriptsShort Description

org.scn.pack.KeyLabelValueExtendedArray getAsKeyLabelValueExtendedArray (

  /**max members*/ optional int maxMembers)

returns the array with key, label, value + param1, param2, param3 which can be used as place holders for properties

 

element.param1

element.param2

element.param3

 

eg.

 

var keysAndlabelsAsArray = COLLECTION_1.getAsKeyLabelValueExtendedArray(5);
// fill into the looser board
keysAndlabelsAsArray.forEach(function(element, index) {  LOOSERBOARD.addElement(element.key, element.label + " ("+element.key+")", element.key + ".jpg", element.value, "" + element.param1);
});

How to Fill it in?

The set* and add* methods are extended by optional parameters,

 

ScriptsShort Description

void setItems (

  /*keys*/ String keys,

  /*labels*/ String labels,

  /*values*/ String values,

  /*separator*/ optional String separator,

  /*optional param 1 array*/ optional String param1s,

  /*optional param 2 array*/ optional String param2s,

  /*optional param 3 array*/ optional String param3s)

Sets items of the array by 2 strings: for keys, labels, values. Additionally sets also 3 optional arrays for parameters 1-3.

void addItem (

  /*key*/ String key,

  /*label*/ String label,

  /*value*/ float value,

  /*optional param 1*/ optional String param1,

  /*optional param 2*/ optional String param2,

  /*optional param 3*/ optional String param3)

Adds a value to new or existing array. Additionally sets also 3 optional values for parameters 1-3.


Connecting to other elements

Now, by this you can make more comprehensive loops and save more properties in the collection (which are also sorted):


COLLECTION_1.removeAllItems();
allMembers.forEach(function(member, index) {  var memberKey = member.internalKey;  var memberText = member.text;    var dataCell = DS_1.getData("4FW8C4WXM3HULQ4M1YPFT79EF", {  "0BC_PERS1": memberKey  });    if(dataCell.formattedValue != "") {  var value = dataCell.value;  var formattedValue = dataCell.formattedValue;  COLLECTION_1.addItem(memberKey, memberText, value, formattedValue);  }
});
// leaders
COLLECTION_1.sortByValueDescending();
var keysAndlabelsAsArray = COLLECTION_1.getAsKeyLabelValueExtendedArray(5);

In the example above, also "formattedValue" is now part of the array and can be used later in this script:

 

LEADERBOARD.removeAllElements();
keysAndlabelsAsArray.forEach(function(element, index) {  LEADERBOARD.addElement(element.key, element.label + " ("+element.key+")", element.key + ".jpg", element.value, "" + element.param1);
});

I hope this helps to handle more complex top/bottom scenarios now.

 

Example Application

A live application is available in GitHub, of course you have to change the system and query to some compatible query.

 

leadloos.PNG

 

GitHub Access

An Application with example can be downloaded at the BIAPP Repository:

Design Studio Pow Wow at ASUG BusinessObjects Conference

$
0
0

This is a brief summary of today's ASUG session with SAP.

2wheredidDScomefrom.png

Figure 1: Source: SAP

 

What if scenarios in XCelsius – is it acceptable to everyone and should SAP create in Design Studio?

 

Large complex dashboards became difficult to maintain in XCelsius

 

SAP received feedback and customers were still using WAD

3whymerge.png

Figure 2: Source: SAP

 

Figure 2 explains why the tools are merging.  "Tool zoo" - it was not the first time we heard this term today.

4dschallenges.png

Figure 3: Source: SAP

 

Design Studio has more potential architecture to it

 

SAP has seen comments on SCN about Design Studio

 

Many are not familiar with the Eclipse based environment

5perception.png

Figure 4: Source: SAP

 

Design Studio Scripting is BIAL; it is not a dynamic language, for usability

 

Design Studio in Figure 4 shows an odd curve where you have to write JavaScript

 

Design Studio is a young growing product

 

For gaps, consider looking at SDK

 

There are barriers to SDK - first you need find it, know about it, install it – need to make consumption of SDK components simpler

6perceptiondiff2.png

 

Figure 5: Source: SAP

 

It is easier to get started with XCelsius; hit the wall quick about what you can do

 

Design Studio uses IDE paradigm; this is not so scary if you have used before

 

People who have BI skills and development skills is small

 

SAP could implement CSS editor with Design Studio for live editing; or is what they have enough?

7survey.png

Figure 6: Source: SAP

 

SAP is looking to cover the gap list.

8xcelsiusgap.png

Figure 7: Source: SAP

 

SAP said they need to fix right to left first, then the components

 

Script free components is on the backlog

 

Spreadsheet affordance is planned for data source SDK data source 1.4 SDK

 

Language for what-if today in Xcelsius is in Excel, parsed to action script, convert to language, run it

 

SAP could do this for Excel but that means translation for runtime

 

JavaScript is great language but not a great language for math

 

Design Studio 1.4 will be GA in November

  • - Fragments – last version included bookmarks
  • - Fragments a development related to Lumira Viz – allows designer to bookmark separately
  • - Users can personalize dashboards
  • - Realtime (we saw a demo during this session)
  • - Main features – drag and drop / split pane, Fiori support, simplified finance, RRI – define Design Studio app want it to be – in BIP or BW  - which Design Studio app is the target

 

More as we hear it here.


New Design Studio Roardmap available

$
0
0

Hi all,

 

a new version (23.09.201) of the Design Studio Roadmap is available. You find it on the roadmaps pages:

http://service.sap.com/saproadmaps> Analytics > Design Studio


Direct Link is: https://websmp106.sap-ag.de/~sapidb/011000358700000390622012D.pdf

In this document you will learn about what will come in 1.4 and the future releases. But keep in mind to read the Disclaimer :-)

 

My personal "Top 5" innovations in 1.4 according to that presentation:

  • Drag and drop in navigation panel & navigation panel usability
  • Context menu in crosstab
  • Script API extensions & global functions
  • Multi language support
  • Online composition of apps & bookmarking


Dirk

Design Studio Cookbook for Dashboard Users - ASUG BusinessObjects Conference

$
0
0

This was an SAP session at the ASUG BusinessObjects User Conference by SAP’s Ian Mayor.  The room was standing-room only, like many of the sessions at this conference.

1ian rule.png

Figure 1: Source: SAP

 

An example in Figure 1 to insert multiple queries you need to use Excel formulas like HLOOKUP, VLOOKUP for XCelsius

 

He said this was easy to do in Design Studio where you can change the query on the fly

 

However it is easy to manage layout, formatting,  and make it “look pretty” including font size, colors – XCelsius

 

Style sheets and scripting make things more complex in Design Studio

 

There are not as many components in Design Studio than XCelsius

2keyarch.png

Figure 2: Source: SAP

 

Figure 2 explains some key differences but even better is the figure in Figure 3.

3pipeline.png

Figure 3: Source: SAP

 

Figure 3 shows the data pipeline

 

When accessing data through the universe it is like Web Intelligence as it uses micro cubes as a data source, whereas if using the BEx query it uses the Query as a data source

4cssstylesheets.png

Figure 4: Source: SAP

 

There was a slide that “style sheets are your friends”.

 

Create a standard style sheet file, standard, type title, if design standards change, change master file

 

There is no CSS editor, there are lots of good editors for free on the web (he showed enjoycss.com)

 

He suggested learning developer tools in browser

5fig.png

Figure 5: Source: SAP

 

The message for Figure 5 was “don’t fear scripting”.

 

The CTRL-SPACE wizard helps.

6fig.png

Figure 6: Source: SAP

 

Figure 6 shows how Design Studio scripting can be simpler than an XCelsius formula using Lookups

 

CSS tips (shown through a demo):

 

Use enjoycss.com

In Chrome, when testing CSS, disable cache in developer tools so you can see the CSS refreshed

7fig.png

Figure 7: Source: SAP

 

There was a brief discussion on this with a suggestion to leverage the SDK.  To learn more I recommend attending SAP TechEd && d-code session EA 211 SAP BusinessObjects Design Studio SDK with former SCN member of the month Michael Howles

 

Question & Answer

Q: Why drop XCelsius, a product that has been around 12 years?

A: Encountered architectural issues with Flash and Excel model

 

Online Resources:

BI Tutorials: http://sap.com/learnbi

Online Documentation: http://help.sap.com/boad

 

Related:

Stay Ahead : Attend TechEd && d-code – Win Big SAP BI BusinessObjects HANA Hands-on Sessions

Join SAP at the end of October forReporting & Analytics 2014 INTERACTIVEconference - registerhere

How to restore custom filters after bookmark load

$
0
0

The Situation

when you load a bookmark, your filters get modified. This is caused by the way how filters interact with variables and multiple data sources (last variable values wins after bookmark load). Example for this scenario - Bookmarks not work when more than one filter panel is used in an application

 

The Proposal

if you face such scenario, you can do following:

  • save your filter per data source somewhere - eg. hidden text component
  • save the bookmark

 

and on load:

  • load the bookmark (which also contains the hidden component with the filter values
  • apply the filter values explicitelly after the bookmark is loaded

 

Script for Save


// assure your filters are acutal
TEXT_FILTER.setText(DS_1.getFilterExt("0BC_PERS1"));
// save bookmark
var bookmark = Bookmark.saveBookmark();
// add on drop down
DROPDOWN_1.addItem(bookmark, DS_1.getFilterExt("0BC_PERS1"));

 

Script for Load

 

// load selected bookmark
var bookmarkId = DROPDOWN_1.getSelectedValue();
Bookmark.loadBookmark(bookmarkId);
// now, apply the saved filter from the hidden text
DS_1.setFilterExt("0BC_PERS1", TEXT_FILTER.getText());

General Information

you can use also such hidden fields to store yourselt any other information in the bookmark, as bookmark is saving everything what is in the application. More in Insides on Bookmarking blog.


Example App


An Application with example can be downloaded at the BIAPP Repository (name: SCN_STORE_RESTSTORE_FILTERS) :

 

I hope this helps.

Design Studio SDK - Creating an online SDK Repository

$
0
0

Usage cases:

 

You've created some SDK extension components that you now want to:

 

  1. deploy and maintain within your team
  2. or as an SDK addon vendor maybe to your customers
  3. or perhaps share with an online community (such as SCN)

 

And you'd like to have the ability to point everyone to one place and have a streamlined way to manage updates without distributing .ZIP files piecemeal.

 

I'll be using my Design Studio Utility Pack for use case #3 above, while obviously this could apply for any of the 3.

 

The approach:

 

This wasn't really spelled out to me anywhere, but based on the steps already spelled out in the Design Studio 1.3 SDK Guide around creating a feature bundle, which is a standard Eclipse-type project, I assumed web-based repository delivery isn't too hard in 2014.  Since I'd never done one, I didn't know what that web-based delivery term was called, but after stumbling around Google for awhile, I eventually figured out that I was trying to make is called an 'Update Site Project'.

 

So OK, let's try!

 

  1. With my Eclipse SDK loaded, I began with File -> New -> Project... -> Plug-in Development -> Update Site Project:
    site1.png
  2. I gave it a suitable name, and clicked Finish:
    site2.png
  3. So let's pause here and look at what was created in the Package Explorer.  A site.xml file is created:
    site3.png
  4. Hmm, ok.  This looks similar to a Feature bundle screen with the 'New Category' and 'Add Feature...' button... I'll take a guess that the category is 'com.sap.ip.bi.zen.sdk' as it is with a feature bundle, and I'll add the feature from my feature project (the one that makes the .ZIP file described in the SDK Guide)
    site4.png
  5. Ok, now what?  There's a 'Build' and 'Build All' button, so I clicked the 'Build All' button (presumably would build any and all features, if I were to have more than one)...  After a brief moment, the feature name has changed slightly, and now I have new files in the left panel of my package explorer:
    site5.png
  6. I am not a huge Java expert but I do know that .jar files are Java Archive files so OK, this made some JAR files for me.  (Also what you would see if you manually unzip a feature bundle .ZIP)... Ok what do I do with these files?  I don't know...  Let's upload them and see what happens and see how hard or easy this is.  Here's the same files in a normal Explorer window, to show you what I'm going to upload to my web server.
    site6.png
  7. And below is the resulting folder I made containing the uploaded files in my webhost, same directory structure:
    site7.png
  8. Now what?  I don't know, but I'm assuming that when you add a repository site to Eclipse, it looks for site.xml and takes it from there.  Surely it's not that simple though?  Let's try Tools -> Install Extension to Design Studio...
    site8.png
  9. Woah.  It figured out that there's a feature there!  Let's install it and see if it works!
    site9.png
  10. We click though the normal addon prompts and let Design Studio restart.  And sure enough, the components are there!
    site10.png

This was a lot of guesswork but I was pleasantly surprised that it 'just worked'.  So what are some of the benefits and considerations?

 

Benefits:

  • Single point of distribution.  No .ZIP file to keep up with.
  • Updates!  I tested this out after-the-fact, but if you upload a new version of the Update Site, you can instruct your users to check for updates by going to Help -> About -> Installation Details -> Select your addon -> 'Update...'   (Or if you want a faster way, toggle to debug mode Ctl+Alt+Shift+D and then simply go Help -> Check for Updates and this also seems to work)

 

Considerations:

  • Unless you are deploying your site within your Intranet, you need to remember a lot of users are probably behind a corporate firewall, so they may or may not have access to your website.  This would mainly be a consideration for an SDK vendor or Internet-based community content (such as this example.)

 

This example for my Utility Pack is actually usable if you'd like to see it for yourself!  If you'd like to try and have already installed a version of it from a .ZIP file, it *should* update correctly, but if you have problems switching, just uninstall the old version from the Help menu.

 

  1. Tools -> Install Extension to Design Studio...
  2. Provide URL http://www.mikehowles.com/designstudioutilitypack1.3
  3. Click OK and run through the prompts and restart.

 

You're done!  You can now check for updates and anything new I add will be reflected on this update site going forward.

 

If you have issues installing with this method, you may be one of those firewalled users mentioned.  This won't work for you unless you can work with your network guys.

 

Enjoy!

Integrated Planning with SAP Design Studio

$
0
0

BW Integrated Planning with SAP Design Studio : Sequence

 

Integrated Planning with SAP Design Studio : Sequence

 

 

 

One of the most exciting features in SAP Design Studio 1.3 is the SAP BI Integrated Planning (IP). Here is an account of my deep-diving into the feature with the help of sales data.

 

What exactly is IP? Integrated Planning is a planning tool, which is a part of SAP BI that allows the user to plan and write back the planned data to the InfoProvider. This has few algorithms within itself which helps the user to plan or forecast. For this case we are using the copy[1] function. This function creates a new entry which when added/subtracted from the existing value leaves us with the new user-input value.

 

Step 1:

 

Prerequisites for creating a planning application in SAP Design Studio:

 

  • Input enabled query or a planning query which can be built only over a real-time cube
  • A planning function or a planning sequence can be created over the real-time cube in RSPLAN t-code
  • An aggregation has to be created over the cube which can be consumed to build an input enabled query. (Here[2] are the steps to create a real-time cube and aggregation)

Real-time BW cube with planning function

 

Real-time cube with a planning function and aggregation

 

 

 

Step 2:

Now create a query in Query Designer on the aggregation created and enable input for the required fields under the Planning tab. Check if the input is enabled by checking it either in Web Analyzer or RSRT.

Input enabled query in RSRT

 

Input enabled query in RSRT

 

 

 

Input enabled query in RSRT

 

Input enabled query in RSRT

 

 

 

Step 3:

Now consume the query in SAP Design Studio. Add a planning function to the application.

Planning function in SAP Design Studio

 

Planning function in SAP Design Studio

 

 

 

On the event start up, enter:

 

DS_1.configureInputReadiness(true);

 

The user needs to enable planning in the cross tab so as to input values. This can be done only using a crosstab.

and it can be done by enabling planning in the crosstab. This enables the user to input to the crosstab.
Planning in SAP Design Studio

 

Planning in SAP Design Studio

 

 

 

To save the entered value back to the InfoProvider, we can add a script to the button:

 

Planning.save();

 

On clicking this the entered data will be saved on to the InfoProvider.

 

Step 4:

SAP Design Studio also allows few more On Click events.

Planning events in SAP Design Studio

 

SAP Design Studio Planning – On Click Events

 

 

 

Recalculate:

Planning.recalculate();

The above script enables the user to enter a value and recalculate it without saving the data to the InfoProvider.

 

Reset:

Planning.reset();

The above script resets the value to the last unsaved data.

 

Client Reset:

Planning.clientReset();

The above script resets the value to the last recalculated data.

 

Checking for changes:

hasUnsavedChanges() and hasClientChanges():

The above scripts can be used in conjunction with “if” statements to check whether there are any unsaved or client-changed entries.

 

To check unsaved changes:

 

if ((Planning.hasUnsavedChanges() == true)) {

APPLICATION.alert(“You have not saved your changes”);

} else {

APPLICATION.alert(“Your changes have been saved”) ;

}

Check not recalculated client Changes :

if ((Planning.hasClientChanges() == true)) {

APPLICATION.alert(“There are recalculated entries”);

} else {

APPLICATION.alert(“There are no recalculated entries “) ;

}

 

We can now check if the data has loaded to the cube by adding the cube as another connection and consuming it in a crosstab.

 

Before saving:

Integrated Planning in SAP Design Studio before saving

 

Integrated Planning in SAP Design Studio before saving

 

 

 

Notice the zero in the first row. The first table is the input enabled table and the next one is the data consumed from the InfoProvider.

 

After Saving:

Integrated Planning in SAP Design Studio After Saving

 

Integrated Planning in SAP Design Studio after saving

 

 

 

It is also possible to create a planning sequence which allows creating a group of planning functions and sort it in the required order and can be consumed in SAP Design Studio which we will try out later. This is the sequential procedure to try out Integrated Planning with SAP Design Studio.

 

References:

[1] Copy function in BI Integrated Planning

[2] Step by Step Guide to Learn Integrated Planning

 

Source :

Integrated Planning with SAP Design Studio

Viewing all 662 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>