Thursday, July 31, 2008

Index

Although the best performance improvement can be seen when a column has an index created on it. However, care must be taken while deciding whether to create an index or not. Below are some of the tips to decide,
When To Create an Index
When you have large table
When the table is mainly used for queries
When you generally query the table for one or few distinct values
When large number of NULLs are in the column
When Not To Create An Index
When you have small table
When users make DML (Data Manipulation Language) changes to the table frequently
When your query results contain substantial portions of the data the table actually stores
When table is updated frequently

Wednesday, July 16, 2008

Profile Attributtes

Profile Attributes I stumbled upon them in siebel when I was working on my first assignment involving Siebel EAI. Till that time I had only used and heard of Global Variables which you could use throught out your script.But as the requirement said only if user clicked a button in View A and then performed some particular action in View B trigger a workflow.As views involved had different BC's it was not possible to have done through global variables. Then my senior colluege introduced me to a new entity in siebel called 'Profile Attributes'. They are important because they have a unique property. They are available throughout the application. The best term that comes to my mind to describe them is 'Session Variables'. Those who have worked a little bit on development of Web Application will understand exactly what I am saying and for those who hasn't worked on them I will explain.

As you know from siebel 7 onwards it has Web Architecture. So, as soon as you login into siebel through your browser a session is started which last till time you log out or you close your browser window or according to the length set through session parameter at server level.Now discussing in details that how server maintains this session and what goes on behind the scene is out of scope of this article but what you need to know is that Siebel server recognises every unique user through session id that is given to you when you login to siebel and it remains valid until you session closes due to above mentioned reasons. So, Profile Attributes are variables that can hold any value during the session of the user. There are two methods available to in siebel escript that help you to work with Profile Attributes.
GetProfileAttr
SetProfileAttr
GetProfileAttr method is used to retrieve the value of a particular profile attribute. The syntax is
TheApplication().GetProfileAttr("ProfileAttrName")
SetProfileAttr method is used to set the value of Profile Attribute. If the Profile Attribute that you mention is not already existing it creates a new Profile Attribute. The syntax is
TheApplication().SetProfileAttr("ProfileAttrName",Value)
So, to accomplish the our requirement we Set a profile attribute when clicked the button on view A and then when he went to View B and did the particular action we wanted we retrieved the value of the profile attribute and if all the conditions were met we executed the workflow and everybody developed happily ever after :)
But, there is a twist in the story and it was not a happy ending after all which highlights the fragile nature of Profile Attributes. Now, in a particular situation this solution won't work. If user clicked button on View A and then logged off which meant profile attribute is destroyed hence the functionality failed. So, as you all must have guessed this solution was scrapped :(
So, the moral of the story is use Profile Attributes with caution and only if you are sure that if the session is destroyed you functionality wouldn't fail.

Siebel CRM How to Restrict a Field to Only Accept Certain Characters

We have a multilingual application and we have Unicode enabled database but still we would like to restrict user from entering certain characters.
We want to prevent user from entering numbers in alpha-numeric fields.Solution:Use charCodeAt function given by Siebel but not documented properly by Siebel. Here I am giving a Pseudo code to explain how it can be used.if (FieldName == "First Name") {for (var i=0;i less than field length ;i++) {var ASCII_code = fieldvalue.charCodeAt(i)if(ASCII_code is not valid code)Error("Not Valid Code");}} charCodeAt() returns the ASCII code of the character that is supplied to it. ASCII code comparison is way faster than the number function that are used to compare strings so we can also use this function where we want to compare two strings by just modifying the above given Pseudo code.Hope this helps! If yes, Please put your comments below.

Next Record & Delete Record use with Caution

Number of times we have written code in which we have to traverse number of records in a loop and n number of times we have missed one important statement that results in our code to stuck in infinite loop. Yes, I am talking about the statement Object.NextRecord()This statment is generally used at the end of the loop so that after all the processing is complete we move on to the next record in the record set and perform processing on the next record. I am giving a Psuedo code to explain that.while(not end of recordset){perform operation recordset.NextRecord()}But here I am going to to tell you about a situation where doing a NextRecord(). will result in problems. Yes, I we are deleting the records in the loop then we don't need to use the NextRecord() function.Reason for that is using DeleteRecord() results in pointer to moved to next record automatically and if we use NextRecord then it will result in skipping of the last record we are trying to delete. Pseudo to explain thiswhile(not end of RecordSet){do processingrecordset.DeleteRecord();// recordset.NextRecord(); // no need to use next record as delete will automatically move the pointer to next line}

Picklists/Pickmaps

Often we forget one thing or other while making a Picklist. Here is some trobleshooting guideline for the same, hope you all would enjoy this
A Pickmap determines which Fields from the pick BusComp will be copied to the BusComp in which the Field with a Picklist is defined.
- When there is a static Picklist and no defined Pickmap, the user will not see a list of values to make his selection.
- When there is a dynamic Picklist and no defined Pickmap, nothing will be copied from the source BusComp.
- When the Pickmap is defined, but does not contain a mapping to a foreign key column on the base table, no reference will be saved to the base record and the update is lost.
- For Fields, that do not have a Picklist attribute defined, there should be no Pickmaps either.
- If a Pickmap is a copy Pickmap, then the value of the Field in the Picklist business component will be automatically copied into the Field of the parent business component specified by the Field property.
A Pickmap specifies instructions for copying Fields when a Picklist is used by a Field, for example to identify which Field must be populated with Picklist values when a Picklist item is chosen. Missing Pickmaps will result in Field values not being populated from the Picklist and an error could occur in the application.

Cascade Delete Property

Here is another good one. Tip for Cascade Delete Property on New Link Definitions and believe me its very useful. Here it goes

- The property should be set to “Delete”, if the child record has no other relationships through other links. This happens often when using a _XM table for the child BusComp. Without the parent record, the child _XM record is not necessary and should be deleted.
- Set the value to “Clear”, if the link defines a 1:M relationship, but the value could be related to another record through another link (e.g. an activity record, which can be associated to a contact as well as to an account).
Ensure that the FK reference on the activity record is cleared, indicating that there is no longer an account associated to the activity before deleting the related account. the activity should not be deleted, as it still has a relationship to a valid contact.
- The property should be left as “None”, if the link uses an intersection table (M:M).
- Set the Inter Child Delete propert to “TRUE” for a M:M link as long as a child intersection record should be deleted when a parent record is deleted.

Use Default Sensitivity and CaseInsensitive

A TRUE or FALSE value.
For fields of type DTYPE_ID
Queries are case-sensitive if
Use Default Sensitivity is TRUE and
CaseInsensitive setting in the CFG file is FALSE.
Queries are case-insensitive if
Use Default Sensitivity is TRUE and
CaseInsensitive setting is TRUE.
For Id fields not exposed in the business component (such as the ID field in Opportunity), the User Default Security property cannot be set.

Immediate Post Changes

Calculated fields are not automatically refreshed when a related field value changes; they are refreshed only after committing the record. To have them refresh immediately after the fields have been changed the Immediate Post Changes property of the field needs to be set to TRUE.

Property Description
A TRUE or FALSE value.
Field data is posted to the server when the focus moves off of the field and then the data is refreshed. Setting this property to TRUE causes an immediate roundtrip to the server.
When set to True the browser script PreSetFieldValue event is bypassed.
Typically used for constrained drop-down lists and calculated fields

How can a MVF be configured to be a required field?

Currently, the standard Siebel application does not provide the ability to make a multi value field “required”.
The solution currently available right now is to write Visual Basic (VB) code to enforce the business requirement.
The Sample VB code to make the Street Address Multi Value Field to be a
required field would be:
Function BusComp_PreWriteRecord As Integer
DIM streetAddress AS String
streetAddress = “”
Me.ActivateField(”Street Address”)
streetAddress = Me.getFieldValue(”Street Address”)
If NOT len(streetAddress) > 0 then
MsgBox “Please Enter Street Address”
BusComp_PreWriteRecord = CancelOperation
exit Function
end if
BusComp_PreWriteRecord = ContinueOperation
End Function

Sort Specification

If two or more applets which are based on same Business Component have require different sort specifications, copying the business component is not required in order to apply the sort specifications individually. The following example snippet in the Applet Load event helps to implement required sort specification with the same business component

Personalization Administration: Applet visibility controlPersonalization Administration could be used to provide additional visibility controls for Ap

Personalization Administration could be used to provide additional visibility controls for Applets and Views.
It is widely known that one could hide an applet in the view from a user with particular Primary Responsibility by using following expression in Administration - Personalization > Applets view using conditional Expression for a given Applet name:
GetProfileAttr(”Primary Responsibility Name”) = <”Responsibility Name”>
There are other supported Profile Attributes, which are lesser know and hardly documented. One of these is ‘GetProfileAttrAsList’.
The following expression could be used in order to compare a value with the user’s responsibilities list and not just the Primary Responsibility.
InList(”ERM Manager”, GetProfileAttrAsList(”User Responsibilities”))
Note that “ERM Manager” is the value for the responsibility you are comparing to.
You can also find some additional postings on Support web regarding these by using “GetProfileAttrList” as the search key word.
Typical application for this information is when configuring Customized/personalized Home Pages for different level of users(Sales Rep, Team Lead, VP/Executives etc).

Call to NextRecord after a call to DeleteRecord

DeleteRecord moves the record pointer automatically to the next record in the record set. The record pointer will move twice if a call to NextRecord is made after a call to DeleteRecord. The consequence is that just every 2nd record will be deleted because a record will be skipped.
So we need to be more cautious while designing such scripts.