Business Objects SDK

Business Objects – Get Webi (Web Intelligence) Prompts Information using InfoStore from CMS Repository

Posted on

Finally found a better way to get the prompts for webi, previously I was using IDocumentInstance to get the prompt list, but to get the document instance iself can take around 30+ seconds :|

The code snippet below will show how to get the prompt list by using InfoStore to query the CMS repository, this will only take around 4 seconds :D 

public List GetWebIntelligencePrompts(int docId, EnterpriseSession session)
{
List reportParameterList = new List();

string query = string.Format(“SELECT SI_ID, SI_NAME, SI_KIND, SI_PROCESSINFO.SI_HAS_PROMPTS, SI_WEBI_DOC_PROPERTIES FROM CI_INFOOBJECTS WHERE SI_ID = {0}”, docId);
using (InfoStore iStore = (InfoStore)session.GetService(“InfoStore”))
{
using (InfoObjects objList = iStore.Query(query))
{
if (objList != null && objList.Count > 0)
{
InfoObject infoObj = objList[1];// InfoObjects collection is 1-based, not 0-based index

Webi webi = infoObj as Webi;
if (webi != null && webi.HasPrompts)
{
// Not sure what’s in the GetEnumerator() implementation, but using foreach below will cause an exception
//foreach (WebiDocPrompt prompt in webi.WebiDocPrompts)
//{
// reportParameterList.Add(new ReportParameter(prompt.PromptQuestion, ParameterType.Single));
//}

WebiDocPrompts prompts = webi.WebiDocPrompts;
for (int iPrompt = 0; iPrompt < prompts.Count; iPrompt++) { reportParameterList.Add(prompts[iPrompt].PromptQuestion); } } } } } return reportParameterList; } [/sourcecode] I'm not sure what's in the GetEnumerator() implementation of the WebiDocPrompts, but using foreach for the collection will cause an exception below, so just use regular for statement instead ;) System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

at BusinessObjects.Enterprise.Desktop.ISWebiDocPrompts.GetEnumerator()
at BusinessObjects.Enterprise.Desktop.WebiDocPrompts.GetEnumerator()

Really glad that finally found out a faster way now, hope this helps you as well ;)

Advertisements

Business Objects – Get Crystal Report 2008 Prompts using InfoStore from CMS Repository

Posted on Updated on

I’m working on a POC where I created a crystal report 2008 report with some prompts then deployed the report into BO server.

I need to get the list of prompts (parameters) before generating the report and fortunately turns out that the prompt information is available in the CMS Repository, so by using the code snippet below, we can get the list of parameter names for a particular crystal report deployed in the BO server (CMS).

public static List<string> GetCrystalReportPrompts(int reportId, EnterpriseSession session)
{
    List<string> reportParameterList = new List<string>();

    string query = string.Format("SELECT SI_ID, SI_NAME, SI_PROCESSINFO.SI_PROMPTS FROM CI_INFOOBJECTS WHERE SI_ID = {0}", reportId);
    using (InfoStore iStore = (InfoStore)session.GetService("InfoStore"))
    {
        using (InfoObjects objList = iStore.Query(query))
        {
            if (objList != null)
            {
                InfoObject infoObj = objList[1];// InfoObjects collection is 1-based, not 0-based index

                #region Use Processing Info to get the prompts
                //ProcessingInfo procInfo = infoObj.ProcessingInfo;
                //Property promptsProperty = procInfo.Properties["SI_PROMPTS"];
                //noParameters = (int)promptsProperty.Properties["SI_NUM_PROMPTS"].Value;

                //foreach (Property prop in promptsProperty.Properties)
                //{
                //    if (prop.Name == "SI_NUM_PROMPTS") // Ignore the number of prompt property
                //        continue;

                //    string promptName = prop.Properties["SI_NAME"].Value.ToString();
                //    reportParameterList.Add(promptName);
                //}
                #endregion

                #region Cast to Report object to get the prompts (cleaner so we don't have to know the logic inside)
                Report rpt = infoObj as Report;
                if (rpt != null)
                {
                    foreach (CrystalDecisions.Enterprise.Desktop.ReportParameter parameter in rpt.ReportParameters)
                    {
                        reportParameterList.Add(new ReportParameter(parameter.ParameterName, ParameterType.Single));
                    }
                }
                #endregion
            }
        }
    }

    return reportParameterList;
}

**Updates: The code snippet above provides getting the parameters by casting the InfoObject into CrystalDecisions.Enterprise.Desktop.Report, which is cleaner IMHO ;)

Unfortunately that we are not able to access the prompts / parameters using the same way for webi (web intelligence) report, the same properties are not available for webi :|

Business Objects – Accessing InfoObjects – Item 0 was not found in the collection

Posted on Updated on

An interesting exception I got when try to access the first index of the InfoObjects collection

System.Runtime.InteropServices.COMException: Item 0 was not found in the collection.

at CrystalDecisions.Enterprise.ISInfoObjects.get_Item(Object Index)
at CrystalDecisions.Enterprise.InfoObjects.get_Item(Object index)

[Test]
public void adhoc_get_report_parameters()
{
    string query = "SELECT SI_ID, SI_NAME, SI_PROCESSINFO.SI_PROMPTS FROM CI_INFOOBJECTS WHERE SI_KIND = 'CrystalReport' and SI_NAME = 'TestCRUniverse'";
    using (InfoStore iStore = (InfoStore)_session.GetService("InfoStore"))
    {
        using (InfoObjects objList = iStore.Query(query))
        {
            if (objList != null)
            {
                Assert.That(objList.Count, Is.EqualTo(1));
                InfoObject infoObj = objList[0];// This will cause the exception
                InfoObject infoObj = objList[1];// This will work               
            }
        }
    }
}

Found the reason at : BusinessObjects Enterprise .Net SDK Developer Guide

Topic: To load a report from BusinessObjects Enterprise into RAS using the OpenDocument method of ReportAppFactory  
Step#10: Note – The InfoObjects indexed class is 1-based, not 0-based.

Business Objects – .Net SDK Windows AD Authentication with Single Sign On (User name and password can be left empty)

Posted on

When I first saw the code below in the BO SDK documentation for authentication, I assumed that I always need both the user name and password for Windows AD authentication.

EnterpriseSession sess = sessionMgr.Logon(username, password, cms, authentication)

But it was to my surprise, it turns out that if we don’t supply the user name and password for Windows AD authentication AND the single sign on is configured, it will be smart enough to be able to retrieve the enterprise session based on the current user :)

Sweet, it just saves me some efforts, thanks to the BO architects who have thought of this kind of thing in the SDK :)