Array Object in eScript
An array is a special class of object that holds several values rather than one. The values could range from simple data structures to complex ones. The later is called vectors.
Values stored in an array are refernced by index numbers assigned to that value. Each value in an array is called an element. Array indices can be either numbers or strings. Arrays can be single dimensional or multi-dimensional in nature.
e.g.,
var arrMyArr = new Array(); // Defines an array object
arrMyArr[0] = “Single Dimensional first value”;
arrMyArr[1][2] = “2-Dimensional Array referencing 2nd row and 3rd column”
Operations supported on Array objects in eScript:
1. Array join() Method:
Syntax: arrMyArr.join([separatorString]):- A string of characters to be placed between consecutive elements of the array; if not specified, a comma is used.
2. Array length property:
Syntax: arrMyArr.length :- Returns an integer value which equals the largest index of array, +1.
3. Array pop() Method:
Syntax: arrMyArr.pop() :- Similar to the pop method we have for stacks. It removes the last element from the array and returns it. If the array has no elements left, it returns “undefined”.
4. Array push() Method:
Syntax: arrMyArr.push(“Element”) :- Appends the element(s) passed onto the end. Returns the updated index of the last element.
5. Array reverse() Method:
Syntax: arrMyArr.reverse() :- Reverses the elements in the array so that last element becomes the first element.
6. Array sort() Method:
Syntax: arrMyArr.sort(“Function to compare and decide sort mechanism”)
7. Array splice() Method:
Syntax: arrMyArr.splice(StartIndex, NoOfElements) :- Returns another array of the elements removed from the main array.
Strongly Typed Variable Declaration
Excerpt: Siebel 8.0 supports strongly typed variable declaration. This new feature is available in the new ST engine.
Advantages of this form of declaration are
- Improved Performance (Effective utilization of memory)
- Improved Scalability
- Reduced Development time (The new ST engine is capable of pulling out data / object references from the metadata repository, thereby reducing the development time by reducing a developer’s time in lookup activities)
1. Example showing Strongly typed variable declaration:
The following screenshot shows an example of strongly typed vs loosely typed variable declaration:

Other supported Object types in eScript are:
Blob
BlobDescriptor
Buffer
BusComp
BusObject
CfgItem
Clib
CTIData
CTIService
Date
Exception
File
Math
PropertySet
RegExp
SELib
Service
WebApplet
The following screenshot(s) show the metadata shown to the user during eScript development:

Gets Metadata from repository


3. Avoids Implicit Conversion:
The new script engine warns the user in the early part of development if there are implicit conversions defined. Please see the screenshot:

- Implicit Conversion Error
Issues if Strongly typed declaration methodology is not followed:
- Late Binding: Variables are defined by the eScript Interpreter at run-time which implies errors would be caught at run-time only.
- Implicit conversions might result in unwanted results.
- Higher usage of memory by the Siebel script engine to process code.
Toggling with the Search Specification in Applet
I came across a blog posted by Mr. Mahendran on Search Specification with a critical scenario…
Please read the blog here… LINK
Old Siebel eScript T (typeless) Engine vs. New ECMA Version 4 ST (Strong Type) Engine
Introduction
Oracle has recently introduced a new eScript engine known as the Strong Type or ST engine. This engine is available in versions 7.7, 7.8 and 8.0. The ST engine is the default engine in Siebel 8.0 and customers are encouraged not to disable it.
Oracle cites these benefits for the new ST engine.
+ Improved performance
+ Improved scalability
+ New features only available with the ST engine
In order to better advise our customers we undertook an independent benchmark comparing the T engine with the new ST engine. Our benchmark included these tests
+ T engine
+ ST engine
+ ST engine with deduce types enabled/checked
+ ST engine with all variables given types
We ran a series of two tests. The second test was added after we did not see the results we expected and the results Oracle cites in their material from Oracle Open World 2006. The tests were:
+ A transaction mix that included math, string and Siebel objects.
+ A transaction mix that included just math and string operations but excluded Siebel objects
Results Findings
Three major discoveries were found on this benchmark. The first was that for the first mix of transactions we did not see very much response time improvement. While CPU on the object manager improved with the ST engine the overall transaction time did not improve very much due to this transaction mix spending the majority of time doing SQL I/O.
The implication from this is that end users may not see much improvement in response time from the new ST engine although their CPU certainly will improve.
The second and third discoveries were identified on the second mix of transactions where we removed the Siebel object scripts and all I/O from the transaction mix. The second finding was when it comes to CPU intensive tasks like mathematical operations and string operations that the new ST engine is about twice as fast as the old T engine.
The third and very much unexpected finding was that using the ST engine with strongly typed variables resulted in horrible performance! With strongly typed variables the performance of the ST engine was twice as slow as the T engine. After opening a service request with Siebel Technical Support it was determined that two change requests exist for this issue and it is considered a product defect.
It was later determined that variables of type String, Number and Boolean are slower when typed on var statements. Other data types such as PropertySet, BusObject, BusComp and Date were as fast or even faster when typed on var statements.
Adding types to var statements presents other problems too. Here are examples of var statements with and without types.
var myString;
var myString : String;
One very undesirable aspect of typing variables is that object compares for String, Boolean, Date and Numeric data types no longer works the way it used to with the old T engine. If you type your var statements you must change your object compares to use the valueOf() operator.
For example if you type your strings this won’t work:
var myString : String;
var yourString: String;
if (myString == yourString) //This won’t work anymore
And instead you must code:
if (myString.valueOf() == yourString.valueOf())
Changing most of your if statements is painful even with our PPS Tools Helper product.
In addition to the above issue with adding types to your var statements you will find a service request that tells you not to type Arrays.
Update – 4/4/2007
After conferring with Oracle Product Marketing we investigated the use of the corresponding primitive data types of chars, float and bool instead of the object types of String, Number and Boolean.
We were delighted with the results. Performance was as good or better than non typed yet will still had the advantages of typing our variables. Plus with the primitive data types we did not have to use the quirky valueOf() function on comparisons.
Conclusion
We love the new ST engine and recommend for it’s features alone.
Given the finding above with strongly typing your var statements our current recommendation about the ST engine is:
Use the new ST engine but be sure to use primitive data types of chars, float and bool instead of String, Number and Boolean. Don’t type Arrays until the stability issue that currently exists is fixed.
Customers with existing eScript code bases need not necessarily add types to their var statements. These customers should still see a big performance improvement.
Also be sure to carefully test your application with the new ST engine before deploying to production! An important product defect relating to passing function parameters by reference has only just been fixed with 7.8.2.5 and 8.0.
URL to another blog which hosts similar content…
CursorMode for Query
The CursorMode is not defined correctly for the BC.ExecuteQuery method. If you do not specify a CursorMode when calling the ExecuteQuery BC method, the method will use the default CursorMode, ForwardBackward. In the case where you traverse the record set using an initial ‘FirstRecord’ followed by repeated calls to ‘NextRecord’, use the CursorMode ForwardOnly. When using the ForwardOnly CursorMode, the system does not create a buffer/cache maintaining the entire record set, resulting in improved performance. If requirements dictate that script must step backwards through a record set with BusComp.PreviousRecord or by calling BusComp.FirstRecord after moving off the first record, then the scripter must use the ForwardBackward CursorMode. When manipulating the current UI context data set, it is necessary to set the query mode to ForwardBackward because the user will want to traverse the data in both directions for the applet displaying the data.
Consequence: Where a ForwardOnly cursor mode is used in a UI context or in one where reverse navigation is performed, a runtime error will occur when attempting to scroll backwards through the result set. Using a ForwardBackward cursor where one is not necessary will result in sub-optimal performance when fetching and navigating through record sets. In most cases, a ForwardOnly record set is preferable
“This” Object Reference
Instead of using TheApplication().ActiveXXX() method, it is recommended that you use the “this” object reference. This is essentially eScript shorthand for the current object of the event handler, rather than the active object. For example, in the BC event handlers, this refers to the BC of the event that the code is placed in. If it is absolutely necessary to use the Activexxx reference at run-time, you must consider the possibility that the script may be executed outside of the UI (e.g. through COM, CORBA or JDB).
Some acceptable uses of ActiveBusObject() include:
• Use in business services to retrieve the current UI context.
• Use on applet level code, although this.BusObject() works just as well.
Accessing Objects in eScript
The following table shows how to access the BC or BO objects depending on the object that the event handler or function is in:
Object: Applet/Control
Target Object Syntax
Current Applet this.
Current BusComp this.BusComp( )
Current BusObject this.BusObject( )
Object: BusComp
Target Object Syntax
Current BusComp this.
Current BusObject this.BusObject( )
PickList BusComp this.PickListBusComp(…)
Associate BusComp this.AssociateBusComp(…)
Parent BusComp this.ParentBusComp( )
MVG BusComp this.MVGBusComp(…)
eScript Best Practices
I came across a blog posted by Mr. Sridhar on eScript Best Practices. Its quite informative.
You can access the link here.
Thanks Sridhar for collating all the information on your blog.
Depth First Search of a Type in Property Set
Scenario: You want to search for a PropertySet in a Hierarchial Data set.
Usual approach: Read the Data set and find out the level of child and then use GetChild(i) function to go to that level.
e.g., var SiebMsg; //Hierarchial Data Set
The structure of the PropertySet SiebMsg looks something like this:
——————————
Start Process Thu Nov 01 22:24:57 2007
Siebel Message in CreateInPS()
PROVIDED PROPERTY SET
Type: Value:
CHILD PROPERTY SET 0
Type: XMLHierarchy Value:
CHILD PROPERTY SET 0
Type: SiebelMessage Value:
MessageId = 3-GFSQS
MessageType = Integration Object
IntObjectName = CC EAI WDS Voluntary Disconnect Request
IntObjectFormat = Siebel Hierarchical
CHILD PROPERTY SET 0
Type: ListOfCcEaiWdsVoluntaryDisconnectRequest Value:
CHILD PROPERTY SET 0
Type: OrderEntry-Orders Value:
CHILD PROPERTY SET 0
Type: Id Value: 3-87VW09
CHILD PROPERTY SET 1
Type: Account Value: 8046900013722350
CHILD PROPERTY SET 2
Type: CCCSGDisconnectDate Value: 04/25/2006 00:00:00
CHILD PROPERTY SET 3
Type: CCCSGOrderType Value: CH
CHILD PROPERTY SET 4
Type: CCCSGReasonCode Value: SB – Siebel
————————Done with PropertySet—————————
Note: This is just an example. Your Siebel Message could look something different with different data. Refer to your sample of data for more processing…
e.g., I need to create a PropertySet from the above Siebel Message which would contain all the child elements of element with Type = “OrderEntry-Orders” as given above.
Typical approach is the following:
If I call the above msg as my input ps then the following we do:
var OrderLvl = Inputs.GetChild(0).GetChild(0).GetChild(0).GetChild(0);
//You can observe the Child levels and their enumeration values “0″ beginning from element with Type = “” i.e. NULL.
Then you can do your processing to retrieve Child elements of “OrderEntry-Orders” type.
There is a problem with the above approach. What if the incoming data set order changes. Your code would fail since you have hard coded the level of OrderEntry-Orders which is served as a reference point for your future processing.
Instead use a method which would work irrespective of data order change in your input. The method does a depth first search of a required / searched type and returns the order.
The method is given below.
The above syntax where we declared and defined a variable to set the order level would look like:
var OrderLvl = findpsType(Inputs, “OrderEntry-Orders”); //This method will retrieve the OrderLvl value correctly even if the order level has changed.
findpsType(ps,type);
var psTemp = null;
var psType = ps.GetType();
if (psType == type) // found
psTemp = ps;
else // try each child until found…
for (
var i = 0,
n = ps.GetChildCount();
i < n && !(psTemp = zzz_psFindChild(ps.GetChild(i), type));
i++
);
return(psTemp);
Pulling MVG Field Value through Scripting
In Accounts > Opportunity, when you create a new opportunity, if Account’s primary contact’s first name and last name should pre-default in opportunity and last Name is a MVG field too then
the following script in Opportunity BC, BusComp_NewRecord can be used to achieve the necessary scenario.
function BusComp_NewRecord ()
{
var AccBO = TheApplication().GetBusObject(“Account”);
var OppBC = AccBO.GetBusComp(“Opportunity”);
var AccBC = AccBO.GetBusComp(“Account”);
var AccId= this.GetFieldValue(“Account Id”);
var ParentBC = this.ParentBusComp();
if (ParentBC != null)
{
if(ParentBC.Name() == “Account”)
{
with(AccBC)
{
ClearToQuery();
SetViewMode(GroupView);
ActivateField(“Account Id”);
ActivateField(“Primary Contact Id”);
SetSearchSpec(“Id”, AccId);
ExecuteQuery(ForwardOnly);
if (FirstRecord())
{
var Cont = AccBC.GetFieldValue(“Primary Contact Id”);
}
}
if (Cont != null)
{
var oMVGBC = this.GetMVGBusComp(“Key Contact Last Name”);
var oAssocBC = oMVGBC.GetAssocBusComp();
with(oAssocBC)
{
ClearToQuery();
SetSearchSpec(“Id”, Cont);
ExecuteQuery(ForwardOnly);
if (FirstRecord())
Associate(NewAfter);
}
oMVGBC.WriteRecord();
}
}
}
}