Thursday, August 27, 2009

Error while running blank query on an applet !!

Today while working on one of the issue in UAT env, when I navigated to Assets screen to see list of all assets, ran a blank query, I got the following error :

There were more rows than could be returned. Please refine your query to bring back fewer rows(SBL-DAT-00500).

In the very first sight, it seems query is bringing a large number of records which Siebel can't handle. hmmm... okayy, lets try running a query which will bring less records so I put a query on "Type" field on the applet and ran the query and it worked fine. That means there is some limitation in Siebel while fetching the records and if the number of records goes beyond that limit it gives up. So, one might ask what is that upper limit??

Upper limit for number of records that Siebel can pull from a single query is equal to the value set for "MaxCursorSize" parameter available in your siebel.cfg file. Here below can be the values :

a) 0 : If this parameter set to 0 (zero), that means Siebel can fetch 10,000 records in a single query. This is the recommended value.

b) -1 : it indicates infinite number of records, results in low performance and not recommended by Siebel.

c) >0 : any number greater than 0 will fetch that many records in one query.

So, what happens is if you run a query on UI and you try to scroll the records and crosses the limit what has been set by "MaxCursorSize" parameter, you will get the above mentioned error. Moreover, the parameter is applied for each and every query that Siebel runs with the exception that it might override by "Maximum Cursor Override" property at the business component level.

I checked for the value of "MaxCursorSize" parameter in CFG and it was set to 0. Just to cross verify I also ran a query in the database and confirmed that number of records in S_ASSET records were more than 10,000 records. But, wait a minute, I didn't even scroll once on the Asset Screen and I just tried to navigate on the default view of the screen and still I received this error. This is something else is going on here, isn't it?

One more thing to notice here is that I realized that even I have more than 10,000 Accounts records in the application, but there is no issue when I navigate to All Accounts view. That means something special does exist with Asset business component which is causing this issue. And here below is the reason for it :

"Hierarchy Parent Field" property of business component was set to "Parent Asset Id" and due to this while running a blank query on the Assets UI, resulted in putting a "/*+ ALL_ROWS */" hint in the SQL that Siebel runs in the background. This is the difference I observed when I just removed the "Hierachy Parent Field" and compiled the SRF again and blank query worked fine this time. No issues. But this doesn't mean that this is the solution for the issue, you can't just remove this property to avoid this error because it get reflect in all the applet based on this business component. So here is the solution for this :

Use "Disable Buscomp Hierarchy", a user property available on the applet and set its value to True. Since it is applet based user property, only applies to the applet on which it is used.

Disable Buscomp Hierarchy = True

What it does is : it will just ignore the effect of "Hierarchy Parent Field" on the business component and run the query without "/*+ ALL_ROWS */" hint in the background to bring the records as per the normal process.

I put this user property on the All Assets List Applet and ran a blank query again, everything worked fine.

Hope it helps !!

Tuesday, August 25, 2009

Refreshing a record in Siebel applet - Possible ways !!

Sometimes it happens you clicks on a button on an applet which is supposed to do some modification on the current record but you get an error saying : The selected record has been modified by another user. This happens when the same record has been updated into the database (by another user or some other process like Workflow, EAI etc) and system is trying to update the old context of record on the UI. So the better way to get the updated copy of the record by refreshing it and then do any modifications. But the bottom line is you should not loose the context of the current record, so if you are thinking of using ClearToQuery() and ExecuteQuery(), it will not solve the purpose here.

There are few possible ways by which you can refresh a record on the UI, without loosing the context of the current record, depending upon the requirement you can take the decision which one to use.

1. RefreshRecord : Business Component Method

This is a method available on Business Component which are derived from CSSBCBase class. Here is how you can use it, if writing code in PreInvokeMethod of applet :
if (MethodName == "MyMethod")

This method will just refresh the highlighed record on the UI.

2. RefreshBusComp : Business Component Method

This is similar to RefreshRecord method available on Business Component which are derived from CSSBCBase class. The only difference is that it will refresh all the records in the current query context :

if (MethodName == "MyMethod")


3. FINS Teller UI Navigation : Business Service

Unlike RefreshRecord and RefreshBusComp, this business service can be used for refreshing any applet/buscomp, no matter which class it has been derived from. The method need to use is "RefreshCurrentApplet".
if(MethodName == "MyMethod")

TheApplication().GetService("FINS Teller UI Navigation").InvokeMethod("RefreshCurrentApplet", TheApplication().NewPropertySet(), TheApplication().NewPropertySet());



Friday, August 21, 2009

Automating Siebel SRF Full Compile process!!!

One of most boring and mechanical task for Siebel Administrators is to do a Full Compile of SRF from Siebel Tools connected to Server Siebel Repository and put it onto the Siebel Server whenever Development team ask to do so.

Here is atleast we can make a process in which Admin guy doesn't require to open Siebel Tools with Server database and do a Full Compile. This can be automated, just follow the below steps :

1. Copy paste the below lines of command into a text file and save it in .bat file lets say : FullCompile.bat

D:\Siebel\8.1\Tools_1\BIN\siebdev.exe /c D:\Siebel\8.1\Tools_1\bin\enu\siebel.cfg /d ServerDataSrc /u <_username> /p <_password> /bc "Siebel Repository" D:\Siebel\8.1\Client_1\OBJECTS\ENU\DailyFullCompileSRF.srf


2. You can change the location of Siebel Tools / Client directory in the above command, as per your requirement. Also the Username and Password.

3. Create a Windows Scheduled Task to run this .bat file on the daily basis. I have set the time for scheduled task as everyday 7AM morning, and I see the newly compiled SRF ready once I reach office :) . SRF name : DailyFullCompileSRF.srf.

I am not sure whether this works in Unix env via creating a cron job, if somebody has tried that please share your experience.


Wednesday, August 19, 2009

Siebel LOV data mystery in 8.x !!!

I was working on one requirement in which there was a need to have two LOV record with same Display Values but different Language-Independent Code (LIC). If you have came across this kind of requirement earlier then you must be knowing that we can create two LOV records with same Display Value / LIC via providing some different value in "Sub Type" field. This is due to that fact that we have two indexes (User Keys) defined on "S_LST_OF_VAL" table, i.e. S_LST_OF_VAL_U1 & S_LST_OF_VAL_U2.

So, I went to "Application -> Administration - Data -> List of Values" view and tried creating the LOV records. Here is data I needed :

And here is what I got when I tried saving the second record.
Found another LOV record with the same display value but different language independent code 'First'. (SBL-SVC-52160)

Surprise !!!! I have specify the different Sub Type and still I am getting this error.

Now it seems that you cannot create two LOV records with the same Display Value. I checked it into metalink and found the same that you cannot do this if you are working in 8.x. I remember we used to create these kind of LOV records in 7.7 and 7.8. And the reason what Siebel says behind this behaviour is that LookupValue() and LookupName() function will return unique value.

Anyways, but this is what my requirement and I need to have these LOV records created, and as per the analysis I did with the user key indexes of S_LST_OF_VAL table, we can have it in database. So here below is way you can create the two LOV records with same Display Value :

"Instead of Copying the LOV record, if you create each record by clicking "New" button and specify different Sub Type then Siebel allows you to create." (May be a loophole what metalink says but this is how I created the two records)

I don't know why is behaving this way and this is what I observed. Anyways I got what I want to achieve. And this is FYI, when I used LookupName() function in Calc Field, it was returning the value of first record. i.e. LookupName("Test", "SiebelMantra") = First.

Your comments are welcome in case you see problem earlier and used some different workarounds.


Wednesday, August 12, 2009

How to do a SetFieldValue on a ReadOnly field on an Applet?

yaa... I know this sounds something interesting so please now stop scratching your head, today I will tell a unique trick by which you can do a SetFieldValue on a field on an applet which is actually displayed as ReadOnly on the UI. Let me reiterate : We want to change the value of a field which is ReadOnly on the Applet, NOT on Business Component. Special Thanks to Amol, my colleague, for bringing this up.

First of all : "Why we need this trick?". Sometimes it happen that for testing purpose Developers/QA people need to set a value in Field but if that is ReadOnly on the applet, what we generally do is just fire a SQL query in the database to set its value and do whatever we want OR you can write a small piece of code in Business Service and simulate it to just solve the purpose temporarily. Here below is a trick by which you can do this without much of effort.

Here below is the screenshot which displayes we have field : "Description" readonly on the UI. And the requirement is set its value to "SiebelMantra".

Here is the solution :
Just copy paste the below text into Address bar :
javascript: alert(theApplication().ActiveBusObject().GetBusComp("Action").SetFieldValue("Description", "SiebelMantra"))

I don't think to explain what we have typed in Address bar, if you already aware how to write browser scripts in Siebel. You can use it further as per your need. Try it !!