Showing posts with label scripting. Show all posts
Showing posts with label scripting. Show all posts

Sunday, February 28, 2010

VBC Compatibility Mode

The Query method of a VBC Business Service in Siebel versions later than 7.5 has an Inputs property set whose structure can be difficult to navigate. Take a look at the XML representation from Siebel Bookshelf:

<siebel-xmlext-query-req>
  <buscomp id="1">Contact</buscomp>  
  <remote-source>http://throth/servlet/VBCContacts</remote-source>  
  <max-rows>6</max-rows>  
  <search-string>=([Phone] IS NOT NULL) AND ([AccountId] = "1-6")</search-string>  
  <search-spec>  
    <node node-type="Binary Operator">AND     
      <node node-type="Unary Operator">IS NOT NULL       
        <node node-type="Identifier">Phone</node>         
      </node>        
      <node node-type="Binary Operator">=         
        <node node-type="Identifier">AccountId</node>         
        <node value-type="TEXT" node-type="Constant">1-6</node>      
      </node>    
    </node>  
  </search-spec>  
  <sort-spec>  
    <sort field="Location">ASCENDING</sort>     
    <sort field="Name">DESCENDING</sort>   
  </sort-spec>
</Siebel-xmlext-query-req>
I've found that the search-string node of the property set isn't particularly useful unless your back-end data source has a column structure that matches your VBC. In the example above, you can quickly see how difficulty it could be for a Siebel developer to write a script to parse a property set containing a search-spec node with any complexity.

In Siebel versions prior to 7.5, the Inputs property set was much simpler. Below, see an eScript snippet that unloads a search specification in the query method of a VBC Business Service using the older format of input:
var child = Inputs.GetChild(0);
var sPolicyNumber = child.GetProperty("Policy Number");
var sLastName = child.GetProperty("Date of Birth");
var sFirstName = child.GetProperty("First Name");
Where query specifications are entered into a form applet as field, the old format lets you easily retrieve input values and manipulate them in eScript variables.

For Query input in the earlier, simpler format, add the following Business Component User Property to your VBC:
Name: VBC Compatibility Mode
Value: Siebel 7.0.4

Monday, September 7, 2009

Setting the SSA Primary Field

When I started configuring Siebel, I was mostly self-taught, which means that I usually settled for the first way I found of accomplishing my goal. Setting the primary record on a multi-value group through script is one example.

My method: query for the record I needed in the child buscomp, obtain the row id, and then use that row id to update the primary id field of the parent. For example, if I needed to set the primary position on the Account buscomp, I would begin by looking up the position id, then I would use a SetFieldValue statement to set the Primary Position Id with the id I had retrieved.

Wrong approach! That is the dangerous way. A scripting error will potentially corrupt your database in the same way direct sql could, by breaking its referential integrity. Directly setting a primary id field is not supported by Oracle.

The feature I didn't understand, which makes the process much easier and safer, is a system field called SSA Primary. You may have noticed this field in MVG Applet configurations. It's a system field, much like Created or Id, but it is different in two important ways:
  1. The SSA Primary field does not correspond directly to a database column.
  2. The SSA Primary field is editable.
Like other system fields, it is not listed in the Fields object in Tools, and you don't have to explicitly activate it in scripting.

Using the SSA Primary field, here is the correct way to use script to set the primary on an MVG, as recommended by Oracle:
  1. Get the MVG business component using the BusComp.GetMVGBusComp method.
  2. Use BusComp.SetSearchSpec and BusComp.ExecuteQuery methods to locate the correct record on the MVG business component.
  3. Set the SSA Primary field with the statement BusComp.SetFieldValue("SSA Primary Field", "Y"), substituting the actual business component variable name.
  4. Use BusComp.WriteRecord on the parent business component. This is because the Primary Id field is on the parent.
Some versions of Siebel Tools will give a semantic warning when you check the syntax after you try to set the SSA Primary field. This is a Siebel bug, and this warning can be safely ignored.

Update - Fixed a typo caught by commenter Duarte: Above instructions previously contained BusComp.SetFieldValue("SSA Primary", "Y") instead of BusComp.SetFieldValue("SSA Primary Field", "Y"). Thanks Duarte!

Friday, May 1, 2009

Get Rid of Dead Code

How many Siebel developers believe that the best way to remove lines of code from an existing script is to put some comment characters in front of the un-needed code, preventing it from executing. Many developers will copy an existing line of code to change an operation or add a condition, "commenting" the original version instead of deleting it. -- Added 5/3

Good coding practice tells us to diligently and carefully comment and annotate changes to scripts, right? Lets take a step back for a moment and think it through. I'm not certain that the commented lines of script are very helpful, at least in most cases.

First of all, commented script rarely helps to trace the historical changes made in a script. If the commented changes are dated, as they often are, you might find the date helpful. But script comments don't lend themselves to historical analysis nearly as well as versioning. Comparing a previous version of a script with the current version, in a source control repository for example, is much easier than trying to decipher the versions from comments in the script itself. Especially considering that the comments from several changes are often mixed in together.

Secondly, commented script doesn't help much in understanding how the current version of the script works. Lets face it: when you examine a script, you are not looking at the code that is commented. You skip the comments and focus on the code that is still active. If the developer happened to leave some actual words among all the dead code, you might stop to read it, but you certainly won't spend much analysis to find out how the script used to work.

Thirdly, and perhaps most importantly, dead code can cause significant overhead on the Siebel server. Every development team that habitually comments unused blocks of script will soon find that an entire event handler has been commented. In fact, it is common to find Siebel repositories with multiple event handlers entirely commented out. Also common are scripted event handlers where no script is present at all. Event handlers are marked as scripted even if the script contains no executable code except the application-provided stub:

function WebApplet_PreCanInvokeMethod (MethodName,
&CanInvoke)
{
return (ContinueOperation);
}

These event handlers cause a measurable increase in CPU load, especially when the event is frequently encountered. The empty scripts also become a maintenance issue, increasing the time required to compile an srf.

So, get rid of all that dead code. If a scripted event handler is empty, completely delete the script record in the Tools list applet. If you are removing individual lines of script, make sure you fully document your changes in design documents, and use a source control system to keep previous versions of the script. But keep the script itself clean. A clean repository will be easier to maintain and provide less overhead on your Siebel server.