siebel编程
来源:互联网 发布:米奥软件 编辑:程序博客网 时间:2024/05/16 10:44
siebel编程
1.从哪里开始?
流程:
要求:在最需要的地方写最少的代码,且只写一次
(1)能配置的不要通过代码来开发;
(2)决定代码放在哪个对象上:
共用代码写在BS/应用程序级,建议使用BS,因为BS可以被工作流进程调用,但工作流进程不能调用自定义的应用程序级别的方法。
如果某个方法处理的是特定BC上的数据,那么写在这个BC上,这样可以避免在使用该BC的Applet上多次复制类似代码。
applet Server script的使用:查询、插入、更新和删除操作;访问本条记录之外其他记录的数据。
applet browser script的使用:与用户交互;与桌面应用程序交互;对当前记录的验证与处理。
(3)定代码放在哪个事件上:
对BS而言有两大类事件,分别是Pre-event类事件和reactive类事件。
Pre-event的使用:只是想执行某些验证,不会更改除了当前记录以外的任何记录的值,如PreQuery, PreSetFieldValue, PreWriteRecord等;
reactive的使用:记录更改后还想做进一步操作,如writeRecord;
对于applet而言,大部分applet浏览器端代码一般写在Applet_PreInvokeMethod事件中,在这个事件中开发人员可以捕获applet触发的方法,如用于和用户的桌面、用户、applet外观交互的代码。但不建议将所有方法的代码都写在Applet_PreInvokeMethod事件中,而是用来创建自定义方法,并调用这些自定义方法。
(4)添加错误处理模版。在撰写任何代码前先在合适的地方添加错误/异常处理策略,主要是添加错误处理模版应用于事件中。
(5)添加方法主体。将方法主体代码添加在错误处理框架中,这样你就能捕获任何运行时错误。
(6)测试。
2.编码命名规范:
(1)数据类型命名规范数据类型名 变量命名前缀Integer 整型 I String 字符形 SBoolean 布尔型 BFloat 浮点型 f
(2)不同作用域范围变量的修饰符
作用域 修饰符全局作用域(仅适用于Siebel VB) G_模块/实例范围 M_ 或者 i_函数或者局部作用域 不需要修饰符或者l_
3.一定要为代码添加必要的注释
4.将代码放在合适的事件中:
级别 事件 常用用途 应用程序级 BusComp_PreSetFieldValue 字段级别的验证 应用程序级 BusComp_PreWriteRecord 记录级别的验证 应用程序级 BusComp_PreQuery 代码用来控制SearchSpecs伴随事件 BusComp_SetFieldValue 字段触发的动作伴随事件 BusComp_WriteRecord 记录触发的动作
5.在频繁触发的事件处理器中使用快速代码
6.使用运行时BS还是编译后的BS
(1)运行时BS:不会编译到.srf文件中,代码保存在数据库中,可以随时更改它,由于运行时都是使用最新的BS定义,适合于编写逻辑经常变化的BS代码或需要在不发布新.srf文件的情况下发布BS。缺陷是任何具有访问商务服务管理员视图的人都可以看见代码,这可能会导致安全性问题。
(2)编译后的BS:在Siebel Tools中定义的,适用于需要更高安全性和不怎么更改的功能。需要编译,并且通过一个新的.srf来应用更改。优点是具有更高的安全性,且装载的速度更快。
7.使用合适的调试技巧
(1)使用alert(不会停止代码的执行)或RaiseErrorText(会停止代码的执行)方法来弹出消息框;
(2)使用Trace或者自定义方法将信息写入文件;
(3)使用Siebel的Debugger功能;
(4)使用对象管理器级别的日志功能(object manager level logging)。
8.从存储库中移除没有用的代码
(1)移除下面这些代码:被注释的代码;设置为inactive (禁用)的代码;从不调用的代码。
(2)移除空方法
9.在所有的代码中包括错误处理
Try 块:包括你要执行的逻辑;
Catch块:捕获错误;
Finally块:执行任何清理工作,比如销毁对象引用。
10.合适的使用RaiseError 和 RaiseErrorText
MsgBox只能用于Siebel 6.x或更早版本。
RaiseError 和 RaiseErrorText会产生一个服务器端代码异常,使代码的执行在此处终止。
所以,任何必须执行的代码必须放到调用这些方法的前面。
11.使用异常信息:
(1)异常包括两种信息:
错误描述。描述哪里错了。
堆栈跟踪信息。按照执行顺序列出的直到产生异常地方的方法名称。
(2)异常处理的目的:
捕获异常;
使程序更加稳定;
记录异常信息或者通知用户发生了什么事;
可能,重新抛出异常;
可能,设置返回代码。
(3)在eScript中,异常对象通过以下属性(方法)存储错误信息:
errText属性:exception.errText
当系统在运行时碰到一个错误,或者开发人员使用RaiseErrorText来引发一个异常时,该属性就会包含错误信息。
toString()方法:exception. toString()
从COM对象或者开发人员通过throw方法抛出的异常中异常信息。
12.将return语句放到合适的地方
finally块中的return语句将会覆盖掉产生的异常信息或者别人抛给它的异常信息,这些异常信息不会传出方法外面。
当finally块中的代码产生异常信息时,这样的异常信息会传到方法外面,但是之前的异常信息却丢掉了。
function illustrateReturnStatement(){ var myVar; try { //executable code goes here myVar = 1; } cache(e) { if(defined(e.errText)) { TheApplication().RaiseErrorText("An exception occurred in the "+" of the "+this.Name()+" object. "+"ERROR: "+e.errText+"“STACK:"+e.toString()); } else { TheApplication.RaiseErrorText("An exception occurred in the "+" of the "+this.Name()+" object. "+"ERROR:"+e.errText+"STACK:"+e.toString()); } }//end catch finally { //cleanup code goes here } return myVar;}
13.使用Top对象来集中浏览器端代码
在客户端代码中,top是到顶层文档的捷径。使用top对象,开发人员可以撰写一个浏览器端代码函数一次,然后从其他的浏览器端对象中调用它。
14.在服务器端代码中何时使用当前上下文,何时使用新的上下文?
当前上下文处理的对象是系统创建用来支持对用户来说可用的数据;
bc = this.BusObject().GetBusComp(“Contact”);
bc=TheApplication().ActiveBusObject().GetBusComp(“Contact”);bc=this;
而新上下文是在代码中初始化的一系列对象,它与用户当前看到的对象或者数据没有什么关系。
bo = TheApplication.GetBusObject(“Contact”);bc = bo.GetBusComp(“Contact”);
使用当前上下文:访问用户正在处理的数据;执行的处理(此处应指处理结果)让用户可见。使用新的上下文:对一个可见的BC执行不可见的查询;在其他的BO上下文中使用一个BC。
15.为变量使用最小的作用域
创建实例级别的变量:
经常会违反封装的原则;
代码的执行会有交叉;
没有事件保证这些对象会被销毁;
理解这类变量的作用域或状态比较困难,因为他们是在一个方法中初始化的,而在另外的方法也可以访问。
更好的做法是:当需要的时候声明和使用对象,然后将他们作为参数传递给其他方法。
16.只在需要时初始化对象,创建没有使用的对象实例会影响系统性能
评估条件—–>创建对象—–>使用对象
17.当对象变量不再使用时要销毁它
(1)对象引用包括:COM对象,属性集 (Property Sets),BS,BC,BO,Applet
(2)应按照程序创建应用对象顺序的逆序来释放对象,先释放子对象,再释放父对象。
Pick/Associate/MVG BC 在父BC之前释放;
BC在BO之前释放;
属性集和BS因为他们是相互独立创建的,所以先释放哪个都没有关系。
(3)应该将对象销毁语句放到错误处理语句中的finally块中,这样不管方法是执行成功还是执行失败后退出,对象都会被销毁的。
finally{ ChildObject = null; ParentObject = null;}
18.使用条件块来运行代码
function BusComp_PreSetFieldValue(FieldName, FieldValue){ switch(FieldName) { case “Status”: //do something break; … } …}
19.检查返回的对象是不是你想要的
(1)ActiveBusObject方法。该方法返回的是活动Applet对应的BC所对应的BO。
当BC是多个BO的子对象时,那一定要检查返回的BO是不是你想要的。
ActiveBusObject只有在应用程序级代码或者BS中调用才有意义,而在Applet或者BC中你应该使用:this.BusObject() 。
代码示例:
if(TheApplication().ActiveBusObject().Name() == “some name”){ //code here}
(2)ActiveBusComp方法。该方法返回的是与活动Applet相关联的BC。
如果是在BC之外调用该方法,应该检查该方法返回的BC是不是你想要的。
(3)ParentBusComp方法。该方法是根据链接(link)中的子BC返回父BC。总是要检查该方法返回的BC是有效的,且是你想要的。
下面两种情况可能会导致没有可用的引用:
BC是父BC且它没有父BC,比如在Account BO中的Account BC;
在BO中建立的父子关系的link已经被移除了或者更改了。
如果ParentBusComp方法没有返回引用,也不会抛出异常。如果在一个为null的对象上调用方法或者引用属性将会引发运行错误。
var lBC_parent = this.ParentBusComp();if(lBC_parent != null && lBC_parent.Name() == “some name”){ //code}
20.在使用字段之前检查字段是活动的
在非活动字段上调用GetFieldValue 或者SetFieldValue方法会导致数据丢失或者逻辑混乱。
只能在ExecuteQuery执行成功后使用ActivateField方法。作为一个独立语句,ActivateField不会暗中激活一个非活动字段。
ActivateField告诉系统在BC上下次执行的SQL语句时包括这个列。
ActivateField(<Name>);ExecuteQuery(ForwardOnly);GetFieldValue(<Name>);
(1)只要满足下面条件之一,那么服务器端代码字段就是活动的:
系统(保留)字段,如Id, Created, Created By, Updated, Updated By
BC的LinkSpec属性被设置为TRUE ;
BC的Force Active属性被设置为TRUE;
在活动视图中包含了一个Applet定义;
在活动Applet中该字段被用于计算字段的计算公式中;
使用方法BusComp.ActivateField (strFldName) 显式激活。
(2)满足下面条件之一,那么浏览器端代码字段就是活动的:
Id 字段;
在用户界面上该字段可见。
21.Siebel 7 新方法:ctivateMultipleFields, GetMultipleFieldValues 和 SetMultipleFieldValues。
var lbc_account = this;var lPS_FieldNames = TheApplication().NewPropertySet();//创建lPS_FieldNames 来保存字段名称var lPS_FieldValues = TheApplication().NewPropertySet();//创建lPS_FieldValues 在保存字段值var ls_account_products;var ls_agreement_name;var ls_project_name;var ls_description;var ls_name;//使用SetProperty方法设置值以后,调用方法ActivateMultipleFields,Siebel应用程序就会以参数形式传递属性集。//set up the property set which will be used in all three methods to hold the field names.lPS_FieldNames.SetProperty("Account Products", "");lPS_FieldNames.SetProperty("Agreement Name", "");lPS_FieldNames.SetProperty("Project Name", "");lPS_FieldNames.SetProperty("Description", "");lPS_FieldNames.SetProperty("Name", "");//activate the fields using the property set which has the field nameslbc_account.ActivateMultipleFields(lPS_FieldNames);lbc_account.ExecuteQuery(ForwardOnly);if (lbc_account.FirstRecord()){ //当执行ExecuteQuery以后,调用方法GetMultipleFieldValues 来获取字段值 //retrieve the values. This method acts sort of like a BS in that there is an input property set and an output property set. //The field values will be in the second property set passed in. lbc_account.GetMultipleFieldValues(lPS_FieldNames,lPS_FieldValues); //loop through property set to get values. ls_account_products = lPS_FieldValues.GetProperty("Account Products"); ls_agreement_name = lPS_FieldValues.GetProperty("Agreement Name"); ls_project_name = lPS_FieldValues.GetProperty("Project Name"); ls_description = lPS_FieldValues.GetProperty("Description"); ls_name = lPS_FieldValues.GetProperty("Name");}//now set new values in the property setlPS_FieldNames.SetProperty("Account Products", "All My Products");lPS_FieldNames.SetProperty("Agreement Name", "Siebel Agreement");lPS_FieldNames.SetProperty("Project Name", "Siebel Project #2");lPS_FieldNames.SetProperty("Description", "This is the description");lPS_FieldNames.SetProperty("Name", "Joey Joe Joe Junior Shabbidoo");//set the field valueslbc_account.SetMultipleFieldValues(lPS_FieldNames);//commit the datalbc_account.WriteRecord();
22.为查询使用合适的视图模式
with (bcAcct){ SetViewMode(this.GetViewMode());}
23.只查询索引列
24.使用ForwardOnly游标模式
25.在执行查询后检查是否有合法的记录存在
bcContact.ClearToQuery();bcContact.SetSearchSpec(“Id”, sContactId);bcContact.ExecuteQuery(ForwardOnly);//Check to see that a record was actually returned by examining the return of FirstRecord().if (bcContact.FirstRecord()){ //okay to perform data processing…}
26.使用Switch(eScript)或者Select Case语句(Siebel VB)
当需要将某个表达式的值和多个可能性进行比较的时候,最快和最具可读性的方法就是使用switch。
因为表达式只被求值一次,然后和不同的值进行比较,所以效率更高;
比一大堆嵌套的if…else if 语句更具可读性,使用switch或者select case语句往往能把多页代码压缩成一页。
27.在If/Else If语句中比较相同的条件
var ls_first = “first”;var ls_second = “second”;if (ls_first == “first”){ //do something……}else if (ls_second == “second”){ //do something else………}
28.使用Associate方法创建中间表(intersection table)记录
var lBC_mvg = this.GetMVGBusComp(“Sales Rep”);var lBC_associate = lBC_mvg.GetAssocBusComp();with(lBC_associate){ ClearToQuery(); SetSearchSpec(“Id”, SomeRowId); ExecuteQuery(ForwardOnly); if(FirstRecord()) Associate(NewAfter);}
29.使用动态值
最好使用动态值代替将值硬编码到代码中。这对于那些经常更改的值来说特别重要,因为如果你硬编码的话,编码的任何变化都要重新编译和发布。
代码中经常要用到的值都可以通过TheApplication.GetProfileAttr() 函数来获取。
此外,还可以将值存储在List Of Values表或其他表中,在需要的时候查询,用于在代码中要查询的只有一个动态值或较短的值列表时。
//下面代码中,LOV值是从List Of Values这个BC中查询出来的,然后将他们组合成一个查询过滤表达式。var statusList;var moreRecords;var boLOV;var bcLOV;boLOV = TheApplication().GetBusObject("List Of Values");bcLOV = boLOV.GetBusComp("List Of Values");bcLOV.ClearToQuery();bcLOV.SetSearchSpec("Type","SR_STATUS");bcLOV.SetSearchSpec("Active","Y");bcLOV.ExecuteQuery(ForwardOnly);if (bcLOV.FirstRecord()){ statusList = bcLOV.GetFieldValue("Name"); moreRecords = bcLOV.NextRecord(); while (moreRecords != 0) { statusList = statusList + " OR "; statusList = statusList + bcLOV.GetFieldValue("Name"); moreRecords = bcLOV.NextRecord(); }}else{ statusList = "";}
30.使用逻辑常量还是字面量
最好使用逻辑常量,它使代码更加易读且更加容易升级,使用字面量有可能给升级带来问题。
类型 逻辑常量 字面量游标模式 ForwardBackward 0 (默认值) ForwardOnly 1视图模式 SalesRep View 0 ManagerView 1 PersonalView 2 AllView 3 OrganizationView 5 ContactView 6 GroupView 7 CatalogView 8 SubOrganizationView 9新记录位置 NewBefore 0 (默认值) NewAfter 1 NewBeforeCopy 2 NewAfterCopy 3
31.避免使用Exit Function 和 Exit Sub
仅针对Siebel VB,应避免使用Exit Function 和 Exit Sub。
32.将GotoView放到代码的结尾
GotoView语句不会立即退出代码的执行并导航到指定的视图,而是将该语句挂起来直到其他的代码执行完毕,所以最好将该语句放到代码的结尾处。
33.合适的使用DeleteRecord
DeleteRecord 会隐式的将记录指针移到记录集中的下一行。在DeleteRecord 后调用 NextRecord 将会使记录指针移动两次,
也就是说Siebel应用程序会跳过记录集中的一条记录,如果你在一个循环中这样删除记录,Siebel应用程序将会隔行删除记录。
在循环中删除记录的方法(Siebel VB):
While(BC.FirstRecord <> 0) BC.DeleteRecordWend
- siebel编程
- Siebel是什么意思
- 关于siebel
- siebel 编译
- siebel学习
- SIEBEL 安装
- SIEBEL COMMAND
- SIEBEL CRM
- SIEBEL助手
- Siebel config
- Siebel 8.1 Note:Siebel File System
- Siebel Admin: Siebel task manager commands
- siebel CRM初学
- peoplesoft/Siebel/Hyperion
- Siebel EIM Mapping
- Siebel CRM 全接触
- Siebel Scripting Best Practices
- Siebel Tools配置
- 使用系统的tabbar的字体颜色设置。badge的红色过大设置
- canvas系列教程03-柱状图项目1
- 如何获取手机性能测试数据FPS
- android屏幕亮度调节
- easymybatis——mybatis开发利器
- siebel编程
- Java中String的不可变性和创建String的内存变化
- An overview of gradient descent optimization algorithms
- jquery指定输入框获得焦点
- canvas系列教程04-柱状图项目2
- ffmpeg 的那些坑
- scau 9716 矩形的并
- 顺序容器初识
- SpringBoot:AOP Aspect切面编程