List of all relations in BusinessObjects

Below is the list of all relations in BusinessObjects 4.1 SP7. The relations are useful if you need to find dependent objects in Query Builder. A relations have a type and a name. Here is how to use it.

The relation Webi-Universe is Parent-Child, so Webi is Parent and Universe is Child. If you want to find all Webi documents (parents) that use a specific universe (child), you need to use query:

WHERE PARENTS("SI_NAME='Webi-Universe'","SI_NAME='{the name of the universe}'")

If you want to find all universes (children) that are used by a specific Webi document (parent), you need to use the query:

WHERE CHILDREN("SI_NAME='Webi-Universe'","SI_NAME='{the name of the webi document}'")


Child-Parent ActionSet-Action
Child-Parent ActionUsage-Action
Parent-Child AlertNotification-User
Child-Parent Application-Action
Parent-Child Application-DependencyRule
Parent-Child Application-Relationship
Child-Parent Category-Document
Parent-Child CommonConnection-AOPresentation
Parent-Child CommonConnection-AOWorkbook
Parent-Child CommonConnection-Document
Parent-Child CommonConnection-MDAnalysis
Parent-Child CommonConnection-pQuery
Child-Parent Container-ActionUsage
Parent-Child CrystalReport-BusinessView
Child-Parent CustomRole-Object
Parent-Child DataConnection-Universe
Child-Parent DefaultObject-Application
Child-Parent Document.discussion
Parent-Child Document-BIVariant
Parent-Child Document-DSL.Universe
Parent-Child Document-Excel
Parent-Child Document-Follower
Parent-Child Document-PersistenceQuery
Parent-Child Document-UnFollower
Child-Parent DSL.DataSecurityProfile-SecuredConnections
Child-Parent DSL.SecurityProfile-Principal
Child-Parent DSL.Universe-BusinessSecurityOptions
Child-Parent DSL.Universe-BusinessSecurityProfile
Child-Parent DSL.Universe-DataSecurityOptions
Child-Parent DSL.Universe-DataSecurityProfile
Child-Parent DSL.Universe-SecuredConnections
Parent-Child EnterpriseData-Flash
Parent-Child EnterpriseNode-MON.ManagedEntityStatus
Parent-Child EnterpriseNode-Server
Parent-Child Event-AlertNotification
Parent-Child Event-Principal
Parent-Child Event-Principal-Exclusion
Parent-Child EventSource-AlertNotification
Parent-Child EventSource-Event
Parent-Child Folder-MON.ManagedEntityStatus
Child-Parent InfoObject-Shortcuts
Child-Parent Install-EnterpriseNode
Parent-Child Install-Service
Parent-Child Install-ServiceContainer
Parent-Child Manifest-ReplicableObject
Parent-Child MON.ManagedEntityStatus-MON.MonitoringEvent
Parent-Child MON.ManagedEntityStatus-MON.Subscription
Parent-Child PlatformSearchContainer-PlatformSearchObject
Child-Parent Plugin-Action
Parent-Child Profile-Principal
Parent-Child PublicationArtifacts-SourceDoc
Parent-Child Publication-ExcludedPrincipal
Parent-Child Publication-FC
Parent-Child Publication-Principal
Parent-Child Publication-PrincipalReRun
Parent-Child Publication-Profile
Parent-Child PublicationScopeBatch-Artifact
Parent-Child PublicationScopeBatchDoc-Artifact
Parent-Child QAAWS-WEBI
Child-Parent ReferringDoc-SharedDoc
Parent-Child RelationalConnection-CrystalReport
Parent-Child Relationship-Application
Child-Parent RemoteCluster-ConflictingObjects
Parent-Child ServerGroup-MON.ManagedEntityStatus
Child-Parent ServerGroup-Server
Parent-Child Server-MON.ManagedEntityStatus
Parent-Child ServiceCategory-MON.ManagedEntityStatus
Parent-Child ServiceCategory-Service
Parent-Child ServiceContainer-Server
Parent-Child Service-Server
Parent-Child Service-ServiceContainer
Parent-Child Service-ServiceDep
Parent-Child ServiceUsedBy-Service
Child-Parent Tenant-ServerGroup
Child-Parent Universe(Core)-Universe
Child-Parent Universe-UserGroup
Parent-Child UpgradeManagementTool-LogicalGroup
Parent-Child UpgradeManagementTool-Plugin
Parent-Child User-BIVariant
Parent-Child User-CommonConnection
Child-Parent User-Favorites
Parent-Child User-FavouriteMEStatus
Parent-Child UserGroup-Folder
Child-Parent UserGroup-User
Child-Parent User-Inbox
Parent-Child User-MON.ManagedEntityStatus
Parent-Child User-MON.Subscription
Child-Parent User-PersonalCategory
Parent-Child User-VisualDiffComparator
Parent-Child VISI.Lums-ManagedConnectionRel
Parent-Child VISI.Lums-UniverseRel
Parent-Child WebiFHSQL-DataConnection
Parent-Child Webi-Universe
Parent-Child XL.XcelsiusEnterprise-DataSource
Parent-Child XL.XcelsiusEnterprise-XL.Query

HTTP Status 500 Bad tag encountered: 78

HTTP Status 500 – com.wedgetail.idm.sso.ProtocolException: com.wedgetail.idm.spnego.server.SpnegoException: Bad tag encountered: 78


See SAP Note 1799488.

Single sign on does not work by default for LaunchPad on the server machine. This behavior is by design as the servers are unable to pass Vintela filter.

Use the following URL to access LaunchPad on the server: http://localhost:8080/BOE/BI/logonNoSso.jsp

You may want to modify the LaunchPad link properties in Start Menu to use logonNoSso.jsp.

How to Change Banner in LaunchPad

This is a quick and dirty solution to change the banner in LaunchPad.


Do not forget to backup the files before any change. See SAP note 1659690 for a better solution.

  • Stop Tomcat.
  • Replace the file C:\Program Files (x86)\SAP BusinessObjects\tomcat\webapps\BOE\WEB-INF\eclipse\plugins\webpath.InfoView\web\images\SAP_logo_reg.png with desired logo (preferred dimensions: 63 x 31 px).
  • Delete all folders under C:\Program Files (x86)\SAP BusinessObjects\tomcat\work\Catalina\localhost
  • Start Tomcat.
  • The users will need to delete temporary files in browser to see the change. In IE, Tools > Internet Options > General, Delete under Browsing history:


How to Delete Files Older Than 30 Days from Windows Command Line

forfiles -p F:\Logs -s -m *.log /D -30 /C "cmd /c del @path"

Refresh button text in Web Intelligence reading mode

The Refresh button in 4.1 looks quite anonymous. It is possible to get the "Refresh" text back.


You can edit file

C:\Program Files (x86)\SAP BusinessObjects\tomcat\webapps\BOE\WEB-INF\eclipse\plugins\webpath.AnalyticalReporting\web\webiDHTML\viewer\language\en\scripts\UIDefinition.js

and change the line

,{actionId:"refreshDPMenu", text:"}



The button has actually text but it is overriden with empty string.

You will also need to update this file in tomcat work folder.


(The users might need to clear temporary files in order to see the change)


PS. This is probably not the right way to do this but it seems to be the most straightforward.

Unx Documenter

There is a free tool for extracting UNX universe metadata available on It also allows comparing universes.




Calculation contexts issue with Sum, Where and If

Make a report based on eFashion universe with [Year], [City], and [Sales revenue].


Now we will try to calculate total Sales revenue for Austin in 2004 but in two steps.

Where and If

Define variables as:

[Sales Austin] =[Sales revenue] Where([City]="Austin")

[Sales Austin 2004] =Sum(If [Year]="2004" Then [Sales Austin])

The expected value for [Sales Austin 2004] is 561123.


1) The value calculated in the Sum line for Sales Austin for some reason is 2805617 (which is 5 x Sales Austin 2004 = 5 x 561123).

2) The value calculated in the table on the right is 13498366 (Which is the total of all values in the column Sales Austin i.e. 5 x (561123 + 1003071 + 1135479) = 13498366).


This was a result for BO3.1 SP7. In BO4.1 SP7, the result is slightly different, we will get #MULTIVALUE in the right table.

We can explicitly add [Year] to calculation context.

[Sales Austin 2004] =Sum((If [Year]="2004" Then [Sales Austin])ForEach([Year]))

This will fix the value in the right table, but not in the Sum line.

If we explicitly add [Year] and remove [City], then the result will become correct.

[Sales Austin 2004] =Sum((If [Year]="2004" Then [Sales Austin])ForEach([Year])ForAll([City]))


[Sales Austin 2004] =Sum((If [Year]="2004" Then [Sales Austin])In([Year]))

So the calculation context in the variable [Sales Austin 2004] is derived incorrectly. Since we have [City] in the expression, it should have been included by BO. The variable [Sales Austin] has Where([City]="Austin"), which removes [City] from context, so [City] should have been excluded. But for some reason, we have to specify this manually.


[Sales Austin] =If [City]="Austin" Then [Sales revenue]

[Sales Austin 2004] =Sum(If [Year]="2004" Then [Sales Austin])

This works fine unless we add sum to [Sales Austin]:

[Sales Austin] =Sum(If [City]="Austin" Then [Sales revenue])

[Sales Austin 2004] =Sum(If [Year]="2004" Then [Sales Austin])

In this case, the right table will show wrong value (13498366 in BO3 and #MULTIVALUE in BO4). We need to add [Year] to calculation context in [Sales Austin 2004].


[Sales Austin] =[Sales revenue] Where ([City]="Austin")

[Sales Austin 2004] =[Sales Austin] Where ([Year]="2004")

The result will be correct if we use variable value [Sales Austin 2004] in Sum line. If we add Sum, the result in Sum line will become wrong 2805617.

You might also find it interesting that the following two formulas return different result

=Sum([Sales revenue] Where ([Year]="2004" And [City]="Austin"))

=Sum([Sales revenue] Where ([Year]="2004")Where([City]="Austin"))

The first is correct but the second will return 1683370. (I am not sure what this number is.)

BusinessObjects BI Tomcat logs

BO BI 4 Tomcat generates some logs in the root folder such as SBOPWebapp_BIlaunchpad, SBOPWebapp_CMC, SBOPWebapp_Mobi_Server:


To move the logs to another folder, add Tomcat Java option

-Duser.home=C:\Program Files (x86)\SAP BusinessObjects\BO Logs

BO Logs

How to disable version check in Upgrade Management Tool

To avoid error

"Version check failed. The source system or source BIAR file must be of an older version. The destination system system must be of the current version. (UMT 20012)"

you can use (at own risk) the option



Web Intelligence RESTful Web Services SDK with Java

In this post you will find an example of how to use Web Intelligence RESTful Web Services SDK with Java. The code displays names of the variables for each web intelligence document.

To run the code, you will need json library that can be found for instance on

Example (

import org.json.JSONArray;
import org.json.JSONObject;

public class Program {
  public static void main(String[] args) throws Exception {
    // Establish connection
    Bo4Connection connection = new Bo4Connection("http://ANALYTIX:6405/biprws");
    connection.connect("Administrator", "1-Password", "secEnterprise");
    try {
      // Get list of documents
      String docs = connection.query("GET", "/documents", "application/json");
      JSONArray documents = new JSONObject(docs).getJSONObject("documents").getJSONArray("document");
      for (int i = 0; i < documents.length(); i++) {
        JSONObject document = documents.getJSONObject(i);
        int id = document.getInt("id");
	// Get information about the document
        String doc = connection.query("GET", "/documents/" + id, "application/json");
        JSONObject info = new JSONObject(doc).getJSONObject("document");
        String name = info.getString("name");
        String path = info.getString("path");
        System.out.println(path + "/" + name);
	// Get variables of the document
        String var = connection.query("GET", "/documents/" + id + "/variables", "application/json");
        JSONArray variables = new JSONObject(var).getJSONObject("variables").getJSONArray("variable");
        for (int j = 0; j < variables.length(); j++) {
	  // Print variable information
          JSONObject variable = variables.getJSONObject(j);
          String variableName = variable.getString("name");
    } finally {


The helper API is very simple and contains a constructor and 3 functions: connect(username, password, auth), disconnect(), and query(method, link, format).

The constructor's parameter is the link to web services.

Bo4Connection connection = new Bo4Connection("http://ANALYTIX:6405/biprws");

The call to web services is performed with function query. For instance, to get list of documents we send a GET request to /documents, and we want to get result in json format.

connection.query("GET", "/documents", "application/json");

To get the list of all possible request, please refer to RESTful Web Services SDK Developer Guides on

import java.nio.charset.StandardCharsets;
import org.json.JSONObject;

public class Bo4Connection {
  private String biprws;
  private String token;
  public Bo4Connection(String biprws) {
    this.biprws = biprws;
  public String query(String method, String link, String format) throws Exception {
    return query(method, biprws + "/raylight/v1" + link, format, token, null);
  public void connect(String username, String password, String auth) throws Exception {
    String link = biprws + "/logon/long/";    
    String method = "POST";
    String format = "application/json";
    String body = "<attrs xmlns=\"\">"
      + "<attr name=\"userName\" type=\"string\">" + username + "</attr>"
      + "<attr name=\"password\" type=\"string\">" + password + "</attr>"
      + "<attr name=\"auth\" type=\"string\">" + auth + "</attr>"
      + "</attrs>";
    JSONObject json = new JSONObject(query(method, link, format, null, body));
    token = json.getString("logonToken");
  public void disconnect() throws Exception {
    String link = biprws + "/logoff/";    
    String method = "POST";
    String format = "application/json";
    query(method, link, format, null, null);

  public static String query(String method, String link, String format, 
      String token, String content) throws Exception {
    HttpURLConnection conn = null;
    try {
      URL url = new URL(link);    
      conn = (HttpURLConnection) url.openConnection();
      conn.setRequestProperty("Accept", format);
      if (token != null) {
        String logonToken = "\"" + token + "\"";
        conn.setRequestProperty("X-SAP-LogonToken", logonToken);
      if (content != null) {
            "application/xml; charset=utf-8");
        OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
        out.write(content, 0, content.length());
      if (conn.getResponseCode() != 200) {
        throw new Exception("HTTP Error Code: " + conn.getResponseCode() 
          + " " + conn.getResponseMessage());
      BufferedReader br = new BufferedReader(
        new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
      StringBuilder result = new StringBuilder(); 
      String output;
      while ((output = br.readLine()) != null) {
      return result.toString();
    } finally {
      if (conn != null) {