Saturday, May 25, 2013

BusinessObjects: Public Folder doesn't open in Launch Pad

When you try to open the Public Folder in Launch Pad and it doesn't expand

BusinessObjects 4.0 LaunchPad

I didn't find a real solution for that problem on the internet, so I want to share how to solve it here. In my case it happened on a BO 4.0 platform but may be valid for other versions as well.

When I tried to open the Public Folder in Launch Pad, I just saw the waiting symbol, but it didn't open.


It was a long way to find out that that problem is related to the language settings of the installation. One quick workaround for the problem would be to change the language settings of your browser by adding the language of your BO installation in your settings and rank it to the highest position.


In my case I had to add the English language to my Language Preferences as you can see in the screenshot.

But of course that's just a quick workaround, that can be done from the client.

To solve the problem I had to look into the language directory of the BO installation. I found there two files for crystalreports: one for german (DE) and one for english (EN). I had to delete the german one to have consistent language files in the directory. After restarting tomcat the public folder should show up.


Saturday, March 23, 2013

WebI: Report Filter not working

If you use a report filter in Web Intelligence and no data is shown, although it matches the filter condition

SAP BusinessObjects WebIntelligence - all versions

The problem might be that your text contains invisible special characters like new line. These characters are not working with report filters, you don't get any data in that case.

I remove those special characters in the database layer/semantic layer and replace them with a space (' ') - character. For Oracle Databases your SQL statement could look like this:


REPLACE (
             REPLACE (REPLACE (description, CHR (10), ' '),
                      CHR (13),
                      ' '),
             '   ',
             ' ')
             AS description

Wednesday, March 13, 2013

WebI: Show all months whether they have data

Sometimes you want to display all values of a dimension in your report, even when there is no data inside

SAP BusinessObjects WebIntelligence - all versions

In WebI you can of course only show the data, that you retrieve from your query. That means, when you want to display your measures based on months in a diagram, you will see only the months on your x-axis you get from your query.



Because that doesn't look very nice, I use the following very simple method to always show all 12 months of a year.

I create a new query in the query panel with two simple dimensions inside: YEAR, MONTH.




Afterwards you can merge those dimensions from the Query 'Date' with the YEAR and MONTH dimensions from your original query. When you use the merged dimension in your report, it will always show all 12 monnths.


Wednesday, February 27, 2013

Crystal Reports 2008: Dimension returns only "Selektion X" descriptions

Why a SAP BW dimension shows only Selektion X - placeholder descriptions instead of the correct dimension values.

SAP BusinessObjects 3.1, Crystal Reports 2008, BusinessObjects Integration Kit for SAP, BEX Query

It took me days to solve the following problem, so I want to share a solution if someone else has the same issue.

In my case the problem occurred, when I wanted to access with Crystal Reports 2008 via the BusinessObjects Integration Kit for SAP a BEX Query using a SAP BW MDX Query-Connection. When I used the query objects in my report, instead of the actual dimension member descriptions, I just got the placeholder-descriptions “Selektion 1”, “Selektion 2”, etc. When I opened the same query in SAP, it showed the correct values.

When I looked at the connection string Crystal Reports was using, I saw the parameter “LANG: DE” therein, which means, that it tried to query a german version of the dimension values. As there was only an english version defined, it returned those “Selektion X” descriptions.

I could not find out how to change that language-parameter directly. But finally I found the configuration file "DefaultMapping.properties“ in the folder “PVLMapping” of the Integration Kit for SAP. There you can define a mapping between system language codes to SAP language codes. I mapped the german language codes to english SAP language codes (de=EN, etc.), which changed the LANG-parameter in the connection string to “LANG:EN” and made the correct dimension decscriptions appear.

Friday, January 25, 2013

Set Line Color in Web Intelligence 4.0 Chart

How to individually specify the color of data series in a Web Intelligence 4.0 chart.

SAP BusinessObjects 4.0 FP3

In FP3 SAP added an urgently needed feature to Web Intelligence 4.0 charts. It is now possible to change the color of the lines not just according to a predefined color schema. To my mind that new feature is well hidden in the Web Intelligence 4.0 user interface.



You don't find it in the property window of the chart. Instead you have to select the data series in the chart legend or the line itself. Then you can change the color by chosing the background color in the Format-tab.



Monday, October 1, 2012

Change Universe in SAP BusinessObjects 3.1

"Some objects are no longer available in the universe. See your BusinessObjects administrator. (Error: WIS00001)(Error: INF)"

SAP BusinessObjects 3.1

When you want to replace the universe, which is used in a Web Intelligence report by a new universe, you might get the error message "Some objects are no longer available in the universe. See your BusinessObjects administrator. (Error: WIS00001)(Error: INF)" even when all the dimensions and measures definitely exist in the new universe.
The reason is, that sometimes Web Intelligence doesn't use the object names to reference dimensions and measures of a universe, but it's own internal object ids. These object ids are not visible for the user, but when creating a new object in the universe, a new object id is created automatically.
To overcome the error in Web Intelligence after changing the universe, the only solution I have found is not to recreate the objects in the new universe, but to use the existing universe with the existing object ids and replace the SQL query in the properties. This way the object ids remain and the Web Intelligence report can reference the objects correctly.

Friday, August 3, 2012

Slowly Changing DWH (facts+dimensions)

How to enable a DWH for slowly changing facts
Datawarehouse Architecture, Oracle Database, SQL Server, SAP BusinessObjects

In the classic Kimball DWH we have fact tables and dimension tables, which can have different types of historization. Usually this approach satisfies most of the customer needs. Hence I was quite suprised when I had the requirement in a project to track all changes of dimensions as well as of fact tables (SCD Type 2). These were for example estimated values, which get updated frequently. If we can really call them facts is just a theoretical question at the end, the fact is that the customer needs the possibility to view reports, how they were in a given point in time with appropriate dimension and fact values. Of course, most of the time the customer wants to see the most current values, but from time to time also previous reports are needed.
I want to break the design explanation into 3 points, which were necessary to fulfill these requirements:

Change Detection
No question, the most convinient way to detect changes is CDC, which means that you only get the changed data rows. But this is not always an option and sometimes it's also necessary to synchronise the DWH with the source system when you are missing some changes in the DWH, for example after structural changes in the source system. For small dimension tables comparing the source table with the DWH table is not a big deal. But when we need to compare fact tables containing millions of rows, this might be a performance issue.
After some testing, I found the by far fastest approach to compare to tables here: On Injecting and Comparing
As we also need updated values, I added an analytical function to partition the result set by the key columns.


select Key1,Key2,Attribute1,Attribute2,
       case when count = 2 and tbl1 = 1 
            then 'U'
            when count = 1 and tbl1 = 1
            then 'I'
            when count = 1 and tbl1 = 0 
            then 'D'
            else 'O' 
       end flag
  from (select Key1,Key2,Attribute1,D,
               min(count1) tbl1,         
             count(*) over (partition by Key1,Key2 order by null) count
          from (select Key1,Key2,Attribute1,Attribute2, 
                       count(tbl1) count1
                       ,count(tbl2) count2
                  from (select Key1,Key2,Attribute1,D, 
                               1 tbl1, 
                               to_number(null) tbl2 
                          from source_table                     
                        union all
                        select Key1,Key2,Attribute1,D, 
                               to_number(null) tbl1, 
                               2 tbl2 
                          from DWH_Table                     
                       )
                 group by Key1,Key2,Attribute1,Attribute2
                 having count(tbl1) != count(tbl2)
               )
               group by Key1,Key2,Attribute1,Attribute2 
       )

The performance of this query is incredible compared to other solutions.
The Query returns inserted, deleted and updated rows (as well as the old values if you need them), which is the source for an usual ETL process, that inserts the SCD2 data into the DWH (e.g. How to load a Slowly Changing Dimension Type 2 with one SQL Merge statement in Oracle).
Please check out a more detailled explanation here: Change Detection

Data Model
At the beginning this point was the trickiest one. Building a DWH with surrogate keys etc. as we know it was getting really complicated here. To get the right surrogate key of an dimension value in the fact table, we actually have to cut the fact data into pieces every time a fact changes. When a fact table is referencing plenty of dimension, we get a really huge fact table after some time, a complex ETL process and due to the large fact table probably a poor performance. Each time we register a change in one of a referenced dimension table, a new fact row with the new surrogate key of the dimension table must be inserted in our fact table. When you imagine that dimensions can also reference other dimensions, it's not a funny thing to implement an efficient ETL-process for that requirement.
Here I have to thank this blog entry: Slowly Changing Facts, which brought me to the useful Kimball Design Tip #74. Even when this is not exactly what I was looking for, it's good to know that there is also a theoretical answer for the problem of slowly changing facts.
We decided at the end to use the business keys to reference to the dimension values. Of course this would give you multiple correspondending rows in your join, so you have to assure in your reporting tool, that all your tables contain a filter condition with a date, the user can specify in a prompt or however it's called in your relational reporting tool. For example in SAP Business Objects I used that expression:


WHERE TO_DATE(NVL(TRIM(@Prompt('Query Date','A',,MONO,FREE)),'31/12/9998 12:00:00'),'mm/dd/yyyy HH:MI:SS AM') BETWEEN VALID_FROM AND VALID_TO


If the user doesn't enter a value or a enters a space, the 'Query Date' is replaced by a date like '31/12/9998', which returns the current state of the data. If the user enters any date in the past, the query returns exactly the data from that point in time.

Performance Optimization
Usually the customer wants to see the most current state of the report, which should show up in a few seconds, while viewing a previous report state can take several minutes.
This requirement could perfectly fulfilled using query rewrite-enabled materialized views (in SQL Server language: indexed views). For more information about query rewrite, there are plenty of useful internet sources available (e.g. Query Rewrite).
To get a query rewrite enabled materialized view, the query must return deterministic results. That's why we need a constant value to get the results of the most current date. As in most SCD2 implementations a date from year '9999' in the 'valid_to' column represents the current datarow.
We add the following filter condition to each table of the report query in our materialized view.

WHERE TO_DATE(NVL(TRIM(''),'31/12/9998 12:00:00'),'mm/dd/yyyy HH:MI:SS AM') BETWEEN VALID_FROM AND VALID_TO

When the report user enters an empty string '' into the prompt dialog, the query gets automatically rewritten and the precalculated materialized view is used instead of the detail tables. Using this technique, the most current report version is shown instantly. Only when a previous report is needed and the user enters a past date into the prompt dialog, the detail tables must be queried and the report might takes a bit longer to show up.

Note that some prerequisits must be fulfilled to enable query rewrite in materialized views, the most important points are:
Create the materialized view with 'QUERY REWRITE' Option: 'ENABLE QUERY REWRITE'

  • Set query_rewrite_integrity, e.g. alter system set query_rewrite_integrity=stale_tolerated scope=spfile;
  • Set query_rewrite_enabled, e.g. alter system SET query_rewrite_enabled=FORCE scope=spfile;