Random Thoughts

Views on life

Posts Tagged ‘BusinessObjects’

Drill down in XCelsius/Dashboard Design

Posted by Hemanta Banerjee on February 9, 2011

One of the most frequent questions I get is around configuring drill down in XCelsius (Dashboard Design). XCelsius is primarily a dashboard development tool and it is not meant for analysis. Thus the typical usage of XCelsius does not require the standard type of adhoc drill down analysis that one would normally do within say web intelligence. However there are some instances where you would want a dashboard where the user can select some high level KPI and then have the ability to look into the details of that KPI. This can done using the drill down functionality in XCelsius. Keep in mind although it is called drill down the behaviour more consistent with master-detail type of report rather than a traditional drill down. The video below shows this in more detail.

Click here to download the video

Drilldown functionality in XCelsius (a.k.a Dashboard Design)


So how can you build something like this. It is actually quite simple as you can see in the video below.

Click here to download the video

How to enable drill down in a pie chart


Combining this with the live office functionality discussed in the last post should allow you to build really powerful and interactive dashboards. You can download a more complete example from here.


Posted in BusinessObjects, XCelsius | Tagged: , , , , | 6 Comments »

Building Live Dashboards using Live Office

Posted by Hemanta Banerjee on February 3, 2011

In my previous post Creating Live Dashboards using QWAAS I had shown how you can use QWAAS (query as a webservice) to build live dashboards. While QWAAS is very powerful it has 2 drawbacks

  1. It is only available as part of BusinessObjects Edge/Enterprise (BOE). Crystal reports server (CRS) users do not have access to it.
  2. Can be confusing for the end user

Live Office is a great utility that comes as part of CRS and BOE and allows embedding reports or report parts within Microsoft Office documents. It is compatible with excel, word and PPT and allows creating live refreshable documents directly within MS Office.

Click here to download video

Using Live office to create refreshable office documents


As shown in the video above the process of creating a live document is quite straightforward. Now we know that XCelsius works with excel documents and using live office we can create a live excel documents. So putting these together we can now create a live dashboard which uses an existing crystal reports to fetch data from the database.

Click here to download video

Using Live Office and Excel to create connected dashboards


Using this technique it becomes quite easy for end users to pickup existing reports that already contain the data needed by the dashboard and quickly create live dashboards.

To download HD videos of this post please vi

Posted in BusinessObjects, Dashboard Design, XCelsius | Tagged: , , | 6 Comments »

Creating live dashboards using QAAWS

Posted by Hemanta Banerjee on January 7, 2011

Happy new year to everyone. As the first post for the year I wanted to put something that was simple and common. In the last couple of months I have run into several scenarios of customers asking me the best mechanism to create live dashboards in XCelsius. As you know the only way to create live dashboards in XCelsius is by using Web Services. While you can create web services on your own the hard way, with the BOE platform there is a very nifty utility called Query As A Web Service (QAAWS) which allows you to create web services very easily from the universe.

QAAWS is a web service generator. It uses the query builder to essentially to build a query and publish the query to the platform and makes it available as a web service. Here is how you can use it.

Create the Query and Publish to the platform

1. Launch QAAWS and create a new query. Give it a name that is user friendly.


2. You can set additional parameters such as authentication mode and timeout at this stage. Usually we would keep them as default.


3. As you can see in the steps the next step is to select a universe. Based on your security setting you will be presented with a list of universes that you can use for building the query. The process of selecting the universe and building the query is the same as you would do when using WEBI.


In my example I have purposefully chosen a query which has a prompted filter. I can drive this prompt using a drop down box or other selectors from the dashboard.


As you can see my query has 1 input parameter and 4 output parameters. Now all I need to do it click on the publish button to publish the webservice to the platform.


The URL shown above is the URL for the webservice and I can use this in XCelsius to build my dashboard.

Using the Query in XCelsius

In the data connections dialog of XCelsius you can add a new live office connection. Here you need to enter the URL that we got from QAAWS.


We also need to bind the cells to both the input and output parameters. For the input parameter I have bound it to cell C3 of the spreadsheet as shown below.


The same way you need to bound the output to your spreadsheet. The only thing to keep in mind is that if your query will return multiple rows of data you would need to select a range of cells bigger than the maximum possible range as shown below.


For debugging purposes you can also get the number of rows returned by the query and bind it to a cell as shown below.


And after all of this voila you have a live dashboard…


Posted in Dashboard, QAAWS, WEBI, XCelsius | Tagged: , , | 6 Comments »

Migrating from development to production in BOE (Lifecycle manager)

Posted by Hemanta Banerjee on December 8, 2010

One of the cool new features in BOE XI 3.1 is the new lifecycle manager (LCM) module. Migrating reports and other objects from development to production has been a challenge in all of my previous implementations and I am happy that BusinessObjects provides some out of the box functionality to make this process really simple. When using LCM for migration you create jobs. Once a job is created it can be used several times to promote content from one deployment to another.

Please note that LCM is a separate installation and requires the following Services:

  1. Central Management Server: LCM job itself is an object which is saved in CMC.
  2. Adaptive Processing Server: The LCM job server is added to the Adaptive processing server
  3. Web Application Server: LCM is a web application
  4. Input FRS : This is a server you need available after installing, as jobs that you create in LCM are saved in the Input FRS and CMS repository.
Administrative Settings

Access to the LCM application is set by managing the security for the application in CMC as shown below.


Also before creating new jobs you need to add the source and target BOE systems in the LCM application using the administration options shown below.


Creating the LCM Job

To migrate objects, you have to first have to specify which content you want to promote. This is done in LCM tool with 3 main steps:

1. Create a Job: A job is collection of objects that can be moved from one BOE environment to another.

When you create a new job you must logon to the source system and an Input FRS should be running and enabled as the Job is saved as an Object in the CMS database and as a file in the Input FRS.


In the example above I am migrating objects from my BOE environment as the source to a BIAR file.

2. Add Objects: Add the required objects from the CMS repository that should be migrated. In this example I am migrating all the reports related to the sales and finance department.


3. Add the dependent objects : Objects such as universes, connections, images and other dependencies on which the primary objects depend on also have to be added to the job. LCM will automatically compute the dependents when you click on “Manage Dependencies”.


And now all the objects and their dependents are selected in the job as shown below.


Now my job is ready for the next step which is promotion. You can promote content when deployments are connected and also when they are isolated. When deployments are connected you can directly migrate to the destination. When they are isolated you use a LCMBIAR file to transport the content.

Promoting to target

But before promoting you need to set a bunch of options.


1. Map Connections: You need to map all the universe, QWAAS URL and Crystal report database connection mappings to the target.


2. Schedule: To set how often the job should run.


3. Security: You can specify to promote the security of the objects in the job as a best practice only promote security when changes have been made, typically with a significant revision of the application.

4. Test: As the last step you can test what would happen when promoting the job, without committing the objects to destination

To promote a job you can schedule it or you can run it manually. The figure below shows the 2 scenarios of connected and isolated environments.

Posted in Administration, BusinessObjects, LCM | Tagged: , , , , | 3 Comments »

Drill down and Drill across in WEBI

Posted by Hemanta Banerjee on November 27, 2010

While BusinessObjects provides a fairly simple way to drill down using hierarchies there are times where this is not good enough. For example if we take the Motors example, lets say when the user drills down from the showroom, they want to see a report that displays the demographic information and models for that particular showroom. This is usually hard to do just by using hierarchies and this is where hyperlink drill down is very useful.

But before we go to Hyperlink drill down (or as I call it drill across), let us quickly cover hierarchical drill down. The screenshot below shows 2 ways to define hierarchies in the universe.


The natural hierarchies which is automatically defined by the universe is based on the order or objects within a class. For example in my universe I have Year->Qtr->Month->Date as my time hierarchy. Now if I enable drill in my report I can drill down to specific dates as shown below.


I can also define a custom hierarchy as shown in the figure 1 where I have combined the showroom and the model into a single hierarchy such that when the user drill from the showroom they can see the models in the showroom.


Now coming to drill across. For example when I click on the revenue below I want to jump to another report that shows the sales by model in that country for the selected year as shown below.


Setting that up is fairly simple. I have to create 2 reports as shown below.


The 2nd report accepts the showroom country and year as prompts. Now I have to go to the summary report i.e. Showroom by year and setup the drill across. You can setup a hyperlink drill down by right click on the cell and selecting “New Hyperlink” as shown below.


When setting up the hyperlink you would need to associate the objects from the summary report to be sent as parameters to the prompts in the detailed report as shown above.

Posted in BusinessObjects, WEBI | Tagged: , , , , | 1 Comment »

BOE Universe: Generating list of values based on data

Posted by Hemanta Banerjee on November 19, 2010

Let us take a simple scenario. Let us say we have a countries dimension which has all the countries. If we want to use this dimension table to get a list of countries where we have customers, as well as use it to get a list of countries where we have offices we can create 2 aliases COUNTRY_OFFICE and COUNTRY_CUSTOMER and create objects from the aliases. No issues till now, except if we try to get a list of countries where we have offices. Since we have used the master country table it will list all the countries irrespective of whether we have office there or not.

Let us see how it works below.


In the example above I have a country table and I use it for both client and showroom country. Now if I query for showroom country i.e. countries where I have showrooms here is the query produced.


As you can see it lists all the countries in the countries table which is not what we wanted. In order to get the correct list of countries I have to join with the SHOWROOM table so that the countries list is restricted based on the SHOWROOM dimension table. This is done by specifying that whenever the Showroom Country object is used in a query, the Showroom table must also be inferred in the FROM clause of the SELECT statement. Providing that the Showroom_Country table is joined to the Showroom table the object is then guaranteed to only return countries in which showrooms exist.


Making this change ensures that we always get the correct set of countries when we query for showroom countries.


While this does not seem that critical it becomes very important especially when we want the user to select the showroom country in a prompt for example. We only want those countries to be in the prompt list where we have showrooms and making this change will ensure that we always get the correct list.

Posted in BusinessObjects, Universe, WEBI | Tagged: , | Leave a Comment »

Outer Joins in Universe (BusinessObjects)

Posted by Hemanta Banerjee on November 15, 2010

Lets take a simple scenario. I want to generate a report that shows the sales by showroom, and the report should display all the showrooms in the report. For the showroom with no sales it should display the region with a NULL value for sales.


The usual join (also called as inner join) will not work in this scenario. We need what is called as an outer join. If you want to know more about outer joins you can checkout the Wikipedia link here.

To enable outer join you need to first set the ANSI92 parameter to Yes. This will change the query from the simple join to an an inner join syntax with from clause as shown below.


You can also enable the FILTER_IN_FROM parameter. This pushes the where clause of the join inside the from which reduces the number of records in the join condition and will greatly improve performance.


Now we can setup our outer join. As shown below we can setup the right outer join betwen the fact table and the showroom dimension table.


The effect of this is that all showrooms irrespective of whether they had a sale or not will be returned by the query.


So in conclusion while it is easy to setup outer joins in the universe, one should be very careful when using outer joins as it can result in a cartesian product of all rows especially when using full outer join.

Posted in BusinessObjects, Universe | Tagged: , , , | 1 Comment »

Is it my time yet ?

Posted by Hemanta Banerjee on November 11, 2010

Over the last couple of weeks I have came across several posts in the BOB Board that revolve around time based analysis. Since the questions seem keep repeating it makes it an ideal candidate for a blog posting. Most of the analysis that I run into involve either analysis the most current data i.e. current day, current week, or current month. In fact most of the standard reports are probably built with that as the default selection parameter. And also in most of the cases this data is being compared with some other period like either last quarter or last year.

In my previous posts I have covered 2 very key topics

  • Period to date analysis – Examples would be YTD or MTD type of analysis which I have covered here
  • Prior Period Analysis – Covered here.

In this post I will cover how to make date selections easier for users, especially in scenarios where they want to analyse the most recent period. You might ask why all of this work when I can select dates using the filter criteria in WEBI. The answer is usability. As you can see below it is much simpler to select “Current Year” or “Last Week” from the prompt selection rather than having to go through a set of dates.


So how can we design something like this. It is quite simple actually. First off I define a derived table with the set of pre-defined date ranges that I want to make available for the users.


The code for the derived table is actually quite simple. For example in my case I have used the MAX function to determine the current date based on the dates in the dimension table.

Select 3 AS ITEM_INDEX, ‘Last Week’ as DATE_RANGE, dateadd(dd,-7, max(DATE)) as DATE_RANGE_MIN, max(DATE) as DATE_RANGE_MAX from DATES_TABLE
Select 4 AS ITEM_INDEX,’Current Month’ as DATE_RANGE, cast(CAST(datepart(yyyy,max(DATE)) as varchar(10)) + ‘-‘ + CAST(datepart(mm,max(DATE)) as varchar(10)) + ‘-01’ as DATETIME) as DATE_RANGE_MIN, max(DATE) as DATE_RANGE_MAX from DATES_TABLE
Select 5 AS ITEM_INDEX,’Current Year’ as DATE_RANGE, cast(CAST(datepart(yyyy,max(DATE)) as varchar(10)) + ‘-01-01’ as DATETIME) as DATE_RANGE_MIN, max(DATES_TABLE.DATE) as DATE_RANGE_MAX from DATES_TABLE
Select 6 AS ITEM_INDEX,’Current Qtr’ as DATE_RANGE, ‘DATE_RANGE_MIN’ =
        when datepart(qq,max(DATES_TABLE.DATE)) = 1 then cast(cast(datepart(yyyy,max(DATES_TABLE.DATE)) as varchar(10))+ ‘-01-01’ as datetime)
        when datepart(qq,max(DATES_TABLE.DATE)) = 2 then cast(cast(datepart(yyyy,max(DATES_TABLE.DATE)) as varchar(10))+ ‘-04-01’ as datetime)
        when datepart(qq,max(DATES_TABLE.DATE)) = 3 then cast(cast(datepart(yyyy,max(DATES_TABLE.DATE)) as varchar(10))+ ‘-07-01’ as datetime)
        When datepart(qq,max(DATES_TABLE.DATE)) = 4 then cast(cast(datepart(yyyy,max(DATES_TABLE.DATE)) as varchar(10))+ ‘-10-01’ as datetime)
        else cast(‘1900-01-01’ as datetime)

My code assumes that the dates dimension table is updated and contains only the valid dates. If that’s not the case then you would need to use either a system function like GetDate() to get the current date or use some form of control table for the current date information. This has been explained quite well by Dave in his blog.

This derived table has been joined to the fact table using a between clause as shown below.


I also need to define the contexts to resolve the loops created by the joins.


Now we are ready to add the "DATE_RANGE” column to the universe. In my specific example I have defined the object as a hidden object in the universe and defined a filter called DATE_RANGE with a @prompt as shown below. This is to make it easy to use. I do not want to clutter up the time hierarchy with unnecessary objects. However I want to give the flexibility to the users to easily pick a date range for their analysis.


DATE_RANGE.DATE_RANGE = case when @Prompt(‘Select Date Range for Analysis:’,’A’,’Date Range\Date Range’,mono,free) = ‘*’ then ‘All Days’ else @Prompt(‘Select Date Range for Analysis:’,’A’,’Date Range\Date Range’,mono,free) end

The prompt condition allows the user to either pick ‘*’ meaning all dates, or pick some other date range for analysis. Using the approach above ensures that during adhoc analysis the user has to drag the date range to the query filter and they will be prompted with a set of pre-defined filter conditions to restrict the data.


I have also gone ahead and defined another condition object called “Custom Date Range” that shows the calendar to the user and allows the user to pick any date range from a standard calendar. The custom date range prompts the user for a start and end date and filters the data based on the user selection.


DATES_TABLE.DATE >= @Prompt(‘Select Start date:’,’D’,’Period\Date’,Mono,free,not_persistent,{‘2001/01/01’}) AND DATES_TABLE.DATE <= @Prompt(‘Select End date:’,’D’,’Period\Date’,Mono,free,not_persistent)

So in summary using some of the techniques given here as well in the other posts around time slicing, you can implement quite sophisticated and flexible time based analysis. To access the other articles in the series click on the links below.

  • Period to date analysis – Examples would be YTD or MTD type of analysis which I have covered here
  • Prior Period Analysis – Covered here.

Posted in BusinessObjects, Prior Period, Time Sliced | Tagged: , , , , , | Leave a Comment »

Managing performance by using Aggregate tables in the universe

Posted by Hemanta Banerjee on November 9, 2010

In most large data warehouses one of the common strategies employed by DBA’s to speed up performance is to use aggregate tables. Generally aggregate tables contain information that has a coarser granularity than the detail data. For example in a retail datamart I might have information at the transaction level. However most of the analysis will be performed at the daily level by brand. Without aggregate tables the database will fetch the lowest level of data and will perform a group by at the day level for specific brands which can be a very expensive operation. Instead as part of the ETL process I can pre-aggregate the data at the daily level which would reduce the number of rows by a huge factor. The Sales_Receipts fact table would contain this detail data, but the records in that table might also be aggregated over various time periods to produce a set of aggregate tables (Sales_Daily, Sales_Monthly, and so on).

There are multiple ways of managing aggregates. One option is to create aggregate tables in the database as materialized views and let the query optimizer of the database handle the performance using seamless query rewrite. I will describe this in a separate post. In this post I will focus on using the aggregate awareness functionality of the universe.

My sample database tracks the sales of cars. My detailed fact table VW_SALE_MODEL is used to track the sales at the lowest level of detail i.e. client, showroom, model and color.


Using these I can create a family of aggregate fact tables. For example I have created a aggregate table called VW_SALE that aggregates the data at the client and showroom level. Similarly I can create additional aggregates at the year level.


Once I have create the aggregates I need to map them into the universe which is a 4 step process.

1. Add the aggregate tables and setup the joins with the dimension tables. I have not created standalone aggregate tables since I want to make sure that I can leverage the hierarchies defined in the dimension tables. This process is similar to adding any fact table in the universe.


2. Define the aggregated measures using the @aggregate_aware function. The @aggregate_aware function is used to setup aggregate awareness in the universe.

The syntax of the @Aggregate_Aware function is @Aggregate_Aware(sum(agg_table_1), sum(agg_table 2) …., sum(agg_table_n)) in the order of preference. For example agg_table1 should be the highest level aggregate, followed by agg_table 2 and so on. This is used by the universe to pick the best aggregate table to answer the query.


In my example I have stated that either try to get the sales total from the aggregate table or get it by calculating it using the detailed table.

3. Define the incompatibilities. For example in my structure the model and maker classes are not captured by the aggregate. Also the aggregate table only contains information about sales and not about the quantity sold. We need to define these incompatibilities so that when the user generates a query, the universe can quickly scan through the compatibility list to determine the best aggregate that can be used to answer the query.


When I define it as shown above all queries that include Model or Maker will go to the detailed table. All other queries will be satisfied by the aggregate table.

4. Resolve any loops. Since I have joined the dimension tables to both the fact I have created some loops in the universe which I need to resolve. I can do that by creating separate contexts for the aggregate fact and the detailed facts.

Now I am ready to using my aggregates. To illustrate let us go to WEBI and see the impact of our design. When I query for sales by showroom the entire query is answered by the aggregate table.


As soon as I add the maker to the query BO now retrieves the data from the detailed table instead.


The same approach can be used to capture additional aggregates such as Year level or Qtr level and BO will dynamically go from using the summary table to using the detailed table as the user is performing the drill down.

So in summary, aggregate tables are very powerful and necessary in most real implementations and BO provides a fairly simple way to model it within the universe.

Posted in Aggregate Awareness, BusinessObjects, Universe | Tagged: , , , | Leave a Comment »

WEBI – How to display “Others” in country field based on Rank

Posted by Hemanta Banerjee on November 8, 2010

One of the frequent questions I come across is – I want to view the top 5, however I want everything else that is not in the top 5 to be placed in 1 bucket called others. I ran into the same question on the BOB board today and since it was simple enough here comes the solution.

Getting the rank within WEBI is quite simple using the RANK function. The syntax for the function is RANK(measure name; dimension name; top|bottom). For example of I wanted to find out the rank by sales I could define RANK([Sales Revenue], [City], top).

In order to make my life easier I have defined variable called Rank as shown below.


I can use that in a report filter to get only the top 3 regions by Sales Revenue.


Now to display all other regions I will use the WEBI function NOFILTER. This will return the total sales across all the regions irrespective of the filter. Using the formula below I can get the sales for all the regions that are not in top 3.


By placing this in the footer of the table I can get the report to show the sales for others.


Posted in BusinessObjects, WEBI | Tagged: , , | 2 Comments »

%d bloggers like this: