ebs form开发总结

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1.前言
这是在深航2期项目期间学习form的过程中总结出来的一些东西,但内容比较零散,不包含form开发的完整过程。

1.开发规范
1.1 命名规范
文件命名:
一般将源码放在….\SVN\05.客户化开发\05.源代码\ 目录下,文件的格式参考该目录下的代码包模板:开发编号-开发项名称文件夹,该文件夹命名如:EAM010_资产报废计划EAM代表模块,010和资产报废计划是由开发文档给出,不需要自己取编号。

路径:05.源代码\代码包模板:开发编号-开发项名称\SZAXXXXX\code 中,SZAXXXXX 也有自己的命名规范,一般取表名称的前6个字符,即应用名+模块名,在取表名后的5-6字符作为后缀,例如:表名是SZA_EAM_RETIRE_PLAN ,则取SZAEAMREPLAN,该文件夹名称与form名称保持一致。

SVN模板目录:
Sql :注册弹性域的plsql代码块,名称与表名一致
Table :建表脚本
View :建视图脚本
Pck : 基于视图的增删改form,在hss_public_util程序包中,Table_Handle_Pkg这个过程生成的代码要在数据库中执行,并且代码保存在package文件夹下,并以.pck保存。

Form_Table_Handle这个过程是要放在form中
Form规范
1.Form的命名:例如表名SZA_INV_TST_DOC_TYPES,选取前6个字符SZAINV,加上后面字符串的5-6个字符,SZAINVTSTDOCTP.
2. 块名命名:SZA_INV_TST_DOC_TYPES选表中间字段TST_DOC
3.窗口查询的块QUERY_FIND 的名称:块名+QF,对应的FIX和STK画布名字也要保持一致,但是QUERY_FIND触发器名称不能修改。

4.在ebs上注册表单,功能,弹性域时,form表单,功能和弹性域名称:SZA INV:+中文解释,
例如:SZA INV:单据类型定义。

因为这些名称都是用户在查找时给用户看的。

5. 在窗口查询中,一般用id来作为查询字段,一般在id字段建立索引,查询速度更快,所以应该有消除依赖的代码
6. LOV的显示:id字段一般不显示出来,可以设置id字段的display width为0即可。

2.常用开发组件和功能
1.无TAB的Folder功能
一般情况下,将不随横向滚动条移动的列放置在FIX画布上,变成固定列,固定列是没有拖动效果的。

画布:MAIN ,FOLDER_FIX ,FOLDER_STK
第一步:使用data block wizard创建块
第二步:ROW_ID项的子类名设置为ROW_ID。

其他需要显示在画布上的项设置子类, 另设置显示在STK画布上的属性:
第三步:将数据块中显示在STK上的项复制到PROMT块中,并设置数据块中的trigger(模
提示项的item type为display,子类为FOLDER_PROMT_MULTIROW
第四步:在when-new-form-instance初始化form。

使用app_folder.define_folder_block
如果用到了FIX画布,需要使用参数8
第五步:在画布上调整布局
设置块的Scrool Bar Canvas在fix画布上
注意:
第六步:在WHEN-WINDOW-RESIZED触发器内
if :system.event_window in ('MAIN','DOC','TXN_DETAILS') then
app_folder.event('WHEN-WINDOW-RESIZED');
end if;
2.TAB页的Folder功能
原理:与无tab页不同就是创建画布时,我们会选择创建一个tab_canvas类型的画布假如你要显示的item都来自一个block,则我们只需要一个fix画布;如果画布上的item 来自多个block,则需要多个fix画布。

我们通过when-tab-changed触发器和show_view (hide_view)来控制画布的显示与隐藏
2.1 首先要创建类型为Tab的画布,在画布下添加两个子类为Tab_page的画布,注意的是最好使得这两个画布的名称和将来放在两画布上的stacked画布名称一致。

如下图左
2.2 画布建好以后,我们来看如何布局。

首先将MAIN_TAB画布,堆叠在MAIN画布上,再将图中TAX画布(fix和stacked画布)和BASE 画布(同上)堆叠在MIAN_TAB画布,尽量保持TAX和BASE重合,就是说x和y坐标相同。

2.3 接下来就是在form builder中写显示和隐藏的代码
FORM级的WHEN-TAB-PAGE-CHANGED
hide_main_tab.txt show_main_tab.txt go_tab_first_item.txt
以下的两个过程是为了防止bug
参考(\桌面\ebs常用文档大全\FOLDER)
3.说明性弹性域
第一步:在实际开发中(暂时做过的项目中),会提供给你注册的plsql块(保存在sql 中),
执行后,就会在ebs中注册。

第二步:在数据块中创建item,取名DF,类型text item,子类TEXT_ITEM_DESC_FLEX
第三步:在DF项下,创建两个触发器
WHEN-VALIDATE-ITEM --override
代码:FND_FLEX.EVENT(‘WHEN-VALIDATE-ITEM’)
WHEN-NEW-ITEM-INSTANCE --before
代码:FND_FLEX.EVENT(‘WHEN-NEW- ITEM-INSTANCE’)
第四步:修改DF所在数据块的trigger,添加完成后初始化弹性域
添加此代码:FND_FLEX.EVENT( ‘ ..’)
使用fnd_descr_flex.define初始化弹性域
第五步:启用弹性域
1.先是查找出注册好的弹性域
2.进入段设置界面
Open 弹性域
3.
然后保存4.
最后保存。

4.关键性弹性域
下面讲解的是核算科目账户对应的键弹性域的创建方法
4.1创建三个item项,设置相应属性
CODE_COMBINATION:显示项(称为账户项),字段长度设置2000,显示核算科目的数字组合。

LOV为ENABLE_LIST_LAMP, 验证为NO
COMBINATION_DESC:显示项,字段长度设置2000,显示核算科目的中文描述组合
GL_CCID:数据库表项,存储的是核算科目对应的ID
4.2为账户项添加两个触发器
WHEN-NEW-ITEM-INSTANCE : 触发器执行层次设置为Before
WHEN-VALIDATE-ITEM
为两个触发器添加代码: fnd_flex.event('WHEN-NEW-ITEM-INSTANCE');
4.3为这三个item所在的block块添加触发器
PRE-QUERY POST-QUERY PRE-INSERT PRE-UPDATE WHEN-VALIDATE-RECORD
触发器代码:fnd_flex.event('PRE-INSERT');
4.单选框和复选框
Value when Checked:Y
Value when Unchecked:N
Check Box Mapping of Other Values:Unchecked 因为复选框除了选中,被选中外,还有一个null值状态,所以要设置null状态下的值是多少。

获得复选框的值:块名.复选框名–> Y or N
单选框:是一个单选组,组里有单选按钮
单选组:子类---Radio Group
单选按钮:子类---Radio Button
Radio Button Value—这个属性必须有值
5.手电筒窗口查询
1.打开一个模板APPSTAND,将Object Groups下的QUERY_FIND对象拖到自己的form中,点击copy。

将在block,canvases,windows下生成对应名称为QUERY_FIND的对象。

2. 将new 和find按钮,QUERY_FIND数据块下的key-nxtblock代码修改
New:新建的数据块名称
Find:查询的数据块名称
key-nxtblock:查询数据块的名称
3.设置query_find查询块的属性为主界面块,这样关闭query_find的时候,就会显示主界面块。

4.在主界面块内创建query_find触发器,名称不能修改,添加如下代码:
App_find.query_find(main_win,query_find_win,query_find_block);
参数1:main_win—查询窗口显示在哪个窗口上
参数2:query_find_win ---查询窗口界面对应的窗口
参数3:query_find_block –查询窗口对应的块名称
5.在主界面块中的pre-query内添加查询代码
Copy ,app_find.query_range等
6.主界面块的when-new-record-instace触发器Execution Hierarchy 设置为After
注意:在其他窗口上调用出手电筒
若该窗口有两个块。

则在两个块上建立query_find触发器,代码为app_find.query_find
6.菜单栏
通过这种方法来设置菜单的名称(when-new-form-instance)
fnd_message.set_name('SQLSZA',
'SZA_PA_010_BUDGET_CHECK')/*;消息内容:预算检查(&B)*/ app_special.instantiate('SPECIAL1',
fnd_message.get);
app_special.disable('SPECIAL1');--使菜单灰显(失效)app_special.enable('SPECIAL1');--启用菜单
7.主从块
7.启用功能
8.行指示器打开记录
1).更改行指示器的子类,如图
2.在Item触发器when-item-instance内
CURRENT_RECORD_INDICATOR名称改成DRILLDOWN_RECORD_INDICATOR
三.Form开发中常用的技巧
1.关闭窗口
如何正确的关闭非主窗口(A是主窗口块,B是非主窗口块)
在APP_CUSTOM.close_window这个过程内,if语句内注册window的关闭事件,代码为clear_block;
go_item(‘A.Item_name’);
第二种方法是:设置B的previous navigate block为A,建议使用
在form触发器WHEN-WINDOW-RESIZED中的代码作用:folder能否随着窗口大小变化而变化。

2.lov查找
为item(lov)赋初值,初值在lov中存在多个。

在这中情况下,当你做其他操作时,lov会自动弹出让你选择某一个值。

如果lov中数据过多,需要先在查找中先输入字符,然后在匹配查找的方法:
不显示lov项可以设置显示项的宽度为0即可
3.得到dml语句错误信息
在on-insert触发器内,加入如下代码:
exception
when others then
fnd_message.debug(sqlerrm);
可以得到触发器的具体信息。

4.clear_block 函数
一般在form的插入或更新模式下,clear_blcok会引发是否保存当前内容的系统提示,如果不希望提示,可以使用clear_block(NO_VALIDATE)
5.查询函数的使用
app_query.append( block_name,sql)
参数1:block_name ---字符串
参数2:sql ---字符串,一条查询语句
app_find.query_range( qf_block_name.item_name1,qf_block_name2,block_item_name)参数qf_block_name.item_name1,qf_block_name2:因为该函数适用于范围查找,所以参数1表示范围开始,参数2表示范围结束
参数3:block_item_name –数据块对应的item项
Copy(qf_item,block_item)
类似于第二种,不是范围查找,针对某一个数据块
do_key
使用如下代码,不直接调用execute_query。

:parameter.g_query_find := 'TRUE';
do_key('execute_query');
:parameter.g_query_find := 'FALSE';
app_query.reset('TRACK');
6.设置头块和行块的增删改属性
尽量不设置insert_allowed 和update-allowed属性,insert属性一般只设置行块,头块都是可以新增的,update属性通过设置item的能否输入来实现。

当查询后重新在when-new-block-instance调用一下刷新按钮以及块状态的过程。

一般都会在过程中先把块的delete_allowed和insert_allowed设置为NO,然后再根据逻辑去该状态。

这样就不会出错。

示例代码:
PROCEDURE set_repl_status IS
BEGIN
sza_set_block_property(p_block_name => 'REPL_HEADERS',
p_delete_flag => 'N');
sza_set_block_property(p_block_name => 'REPL_LINES',
p_delete_flag => 'N',
p_insert_flag => 'N');
IF :repl_headers.status_code IN ('1NEW') THEN
sza_set_block_property(p_block_name => 'REPL_HEADERS',
p_delete_flag => 'Y');
sza_set_block_property(p_block_name => 'REPL_LINES',
p_delete_flag => 'Y',
p_insert_flag => 'Y');
ELSIF :repl_headers.status_code = '4REJECT' THEN
sza_set_block_property(p_block_name => 'REPL_LINES',
p_delete_flag => 'Y',
p_insert_flag => 'Y');
END IF;
app_standard.synchronize;
END set_repl_status;
7.设置窗口的标题
在when-new-form-instance设置
app_window.set_title('RETIRE_PLAN', :_CODE);
8.跳转块或者查询块的正确方法(system.message_level)
在ebs form中,消息是有等级的,为了clear_block,do_key('execute_query')等时,屏蔽一些小错误,将等级下调至10.
if event = 'WHEN-BUTTON-PRESSED' then --在ebs form中
l_message_level := :system.message_level;
:system.message_level := 10;
go_block('approve_action');
clear_block;
:parameter.g_query_find := 'TRUE';
do_key('execute_query');
:parameter.g_query_find := 'FALSE';
:system.message_level := l_message_level;
end if;
9. 分段排序
实现:晚于当前系统时间的item排在前面,升序。

早于当前系统时间的item排在后面,升序
使用union的原因:
Union:对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序;
Union All:对两个结果集进行并集操作,包括重复行,不进行排序;
10.编译刚定义好的消息
刚定义好的消息要通过编译才能显示详细说明,不然只会显示简码。

编译消息- 应用开发员职责-->其他-->请求-->运行复制按钮,选择‘生成消息’行,(如果自己选择,则需要输入参数信息)
11.提示:FND_MESSAGE
Question的使用:
fnd_message.set_name('SQLSZA', 'SZA_EAM_DRAW_RETURN_SAVE_TIP');
//用于显示在选择框的内容提示(set_string也可以)
l_question_rt := fnd_message.question('YES',
'NO',
'CANCEL',
1,
3,
'question');
if l_question_rt <> 1 then
raise form_trigger_failure;
end if;
定义变量接受返回值即可l_question_rt为number类型,根据返回值执行逻辑。

例子:
第二种使用方法:
fnd_message.set_name('SQLSZA', 'SZA_EAM_TXN_CANCEL_LIN');
app_special.instantiate('SPECIAL5', fnd_message.get);
使用fnd_message.get取出栈内的消息
12. 提示:set_alert_property
使用set_alert_property来设置提示的信息,可以用字符串连接来输出信息,比FND_MESSAGE方便
13.屏蔽错误
如果碰到无法解决的错误,但是错误对程序并不影响。

在ON-ERROR触发器中,用一下代码替代
app_standard.event('ON-ERROR');
BEGIN
IF ERROR_CODE = 41016 THEN
NULL;
ELSE
app_standard.event('ON-ERROR');
END IF;
END;
14.关于list的一些函数
clear_listadd_list_element配合使用在procedure中动态生成,参考帮助文档
DELETE_LIST_ELEMENT('EVALUATION.EVAL_TYPE_CODE',2);删除list内index 为2值GET_LIST_ELEMENT_COUNT('SHIP_LINES.CHECK_RESULT_CODE') 这个函数用途是得到list内元素的个数,NULL也是元素之一。

15.FOLDER中prompt块中的display item名称
在form中如果我们有需求,改变folder中的提示item,例如图中的”鉴定单号”-->”评估单号”,我们如何去改呢?
一般要在在folder初始化之前就改变他的值。

(一定是有效果的)
但是像下图这种方式有可能成功,也有可能不成功,看具体的应用场景。

16.form中global变量的使用
使用global变量时可以在任何地方声明(声明方法是:global.xxx := ‘xxx’),然后可以在任意form,个性化中获取到
17.调试PLSQL Developer卡死
exception
when others then
rollback;
dbms_output.put_line('---------');
在Test Window后加入以上语句
四.Form错误以及注意事项
1. frm-40350:查询没有检索到记录
数据库有数据,但是在form中查不出,并报错:frm-40350查询没有检索到记录
原因:1.块中有list,查出的数据不能再list中显示,所以会报错。

list对应code(相当于id)和meaning两个字段,在form中,code对应数据库的简码,meaning用于简码显示意义。

在画布上使用code作为项目即可。

2.暂时未遇到其他原因
2. frm-92101,
当在when-create-record内写下,在其他触发器也有可能,
fnd_message.set_string('1');
fnd_message.show;
代码时,会frm-92101:form server.....错误。

原因暂时未知。

建议使用规范的消息弹出代码。

3.frm-30161
Suppose you have two windows, Window1 and Window2, and one canvas, Canvas1.
If, for example, Canvas1 has "Window property" = Window1, and Window2 has "Primary
Canvas property" = Canvas1, then the error FRM-30161 occurs.
In this case you have to put (for Canvas1) "Window property" = Window2 or (for Window2) "Primary Canvas property"
大概意思就是一个画布只能对应一个窗口
4. FRM-40654:记录已被更新。

重新查询块以查看更改。

基于视图的增删改,lock_row的过程中,IF匹配语句发生了错误,可以一个个注释运行观察。

在删除和更新数据时,他会先检测已经查询出来的数据,与数据库中的数据是否有一致,如果有就报出frm-40654错误。

比如说form中item1有值,item1对应的数据库字段没值。

则进行更新和删除时,都会报错。

5.displayed 和enabled属性
当设置了displayed属性为false时,再设置enabled属性为true时,则会报错,因为在项隐藏的情况下,不能设置为灰显。

使用APP_ITEM_PROPERTY.SET_PROPERTY函数处理ALTERABLE、ALTERABLE_PLUS、ENTERABLE、DISPLAYED、ENABLED、REQUIRED等属性
6. frm-41050:你不能更新此记录
当block状态为insert之后,使用代码为某个item赋初值,则会报出此错误
7. ora-06508 plsql无法找到正在调用的程序单元
1.解决1(未成功)
重启OACORE,在secure CRT中执行命令
cd $ADMIN_SCRIPTS_HOME
adoacorectl.sh stop
adoacorectl.sh start
2.经过刘老师解决,发现程序包里多了line_num字段,在PLSQL Developer中tools -->Compile Invalid Objects查看未编译的包
cd $ADMIN_SCRIPTS_HOME
adoacorectl.sh stop
adoacorectl.sh start
7. frm-40831 row_id截断值太长
设置row_id字段的Maximum Length = 240
8.ORA-01722: 无效数字的解决方法
一般出现在to_char和to_number这两个方法上,因为字符串装换成数字to_number时,字符串含有非数字的字符,一般在select后使用该函数时,要确定转换的列,造成转换错误;to_char时,传入的数字非法
9.Oracle错误-20001(关于MOAC的错误)
触发场景:打开form时触发
原因:这是由于要实现MOAC控制的话必须为某个应用环境注册。

没有注册的话不能使用
moac控制,对应着form内的SZA_MOAC_PKG包
解决方法:把form内注释掉使用到的方法
10.ORA-04602
可能需要重新编译form或者plsql包才能解决
ORA-01752: 不能从没有一个键值保存表的视图中删除
1.要删除的这个视图中应该包含计算结果。

2.不能直接删除视图,要去找基表。

应该是有针对视图的DML操作
注意事项:
1.tab键导航问题
问题1:资产报废机计划retire_plan界面,在pl_headers块,按tab键导航到item,发生了错误,直接回到了汇总界面
解决:在pl_headers 块的trigger中,有很多设置folder的触发器以及语句,删除就可以了。

2.导入fmb时会导致form builder崩掉
解决:先链接数据库,在打开fmb文件即可,原因暂时未知。

3.FOLDER画布第一次显示一半
必须调用该函数,来初始化FOLDER
3.pre-record在F11+(ctrl- F11)模式下失效
写在pre-record的设置item是否灰显的代码在F11+(ctrl- F11)执行后失效。

一般都是结合post-query触发器一起使用
4.exit FORM时提示保存
在退出FORM时,会检查记录的状态,如果变为insert 或change则,会提示是否保存数据,这是因为在退出form时,某处代码改变了item的值,使得记录的状态改变了。

6.键弹性域(科目账户)的自动返回值
为什么在pre-insert触发器赋值,可能因为键弹性域在赋值时,会自动计算GL_CCID的值,在GL_CCID的WHEN-VALIDATE-ITEM触发器(之前)就计算了值,但是计算的值又是不正确的。

--计算错误的原因未知,所以在他自动计算值后,我们自己为其赋值即可。

我们使用键弹性域时,一般会有三个字段:数据库表字段科目账户ID,显示核算科目字段,显示科目的中文描述字段。

7.关闭窗口出现folder文件夹
使用FORM folder模板时,control块的NAVIGATION属性必须修改,不然就会关闭窗口时,出现文件夹。

8.登录ebs:JTM已过时
在ebs环境挂载form时,需要使用jre1.6,如果经常弹出提示:jtm已过时,请及时更新。

将域名添加到可信任站点中即可
五.触发器
1.when-new-record-instance
一般触发条件:是每次在光标进入Record 后触发(when-new-block-instance先触发)。

其他触发条件:在删除行块的最后一条记录,保存时,它会检验记录有没有数据,如果有必输字段没有数据,则会不断提示你输入数据。

2.when-create-record
作用:主要用于给新纪录指定某些栏位的缺省值,一般为item赋初值时写在该触发器内。

触发条件:创建record时触发。

触发场景:
第一次进入form时,WHEN-CREATE-RECORD触发在前,when-new-form-instance触发在后。

进入block时(即打开窗口时),when-create-record也会触发。

进入新的记录时,会触发。

关闭窗口时,也会触发。

查询窗口点击清除按钮时,也会触发,所以赋初值放在该触发器内。

when-create-record先于pre-record 执行
WHEN-CREATE-RECORD的三大定律一大推论:
1.如果BLOCK是可INSERT的,且BLOCK的记录数为0,则在PRE-BLOCK之前必会调用
2.如果BLOCK是当前块,且是可INSERT的,如果记录数为0,则会调用。

比如,CLEAR_BLOCK 时,执行查询但未查到记录时
3.如果BLOCK得状态是NEW,那么每次FOCUS ON该BLOCK时,都会触发;QUERY,CHANGED 不会
例子:/share/?id=92c68dae0ea7150fa10cc8c7ee345e94&type=note
3.pre-record
一般没进入一行数据之前都会触发,因为查询后也会触发,用于控制block,item的状态。

注意:
触发器内,先设置item能否更新,即是否灰显,再设置块的增删改属性。

不然可能会导致使用F11+ctrl F11后,item变成必输的样式。

4.do-key 和execute_trigger
execute_trigger:用来运行一个指定的触发器,一般是用户自定义的触发器。

do-key:运行一个关联了键(Key)的内置触发器
注意:do-key的参数是关联了key的内置子程序,不是键触发器本身。

例如,在默认的处理中,如果when-validate-item触发器失败,那么它会抛出一个异常并停止form的运行,但是,如果when-validate-item是由execute_trigger来调用执行的,那么如果调用执行失败了,这个失败并不会停止form的运行
六.PLSQL相关
1.MOAC对于OU的控制(暂时没理解逻辑的,但是代码可以大概看懂)
moac.txt
2. 手动建立库存组织模板,增加org_id参数:
1、从INVSTANDARD.fmb中拖INV_PARAMS到我们的Form中,并用Subclass,这样会生成4个参数。

2、在FORM级的trigger pre-form中加上:FND_ORG.CHOOSE_ORG;
3、想把库存组织显示在窗口上面的话在form level 的trigger when-new-form-instance(或者when-new-block-instance视情况而定)中加上:APP_WINDOW.SET_TITLE('WDW_XXX',:_CODE);
3. fnd_standard.set_who函数
EBS系统在在进行客户化表结构设计的时候,会建立如下5个who字段,用来记录用户的相关信息,这5个字段是:
CREATE_BY NUMBER
CREATE_DATE DATE
LAST_UPDATE_BY NUMBER
LAST_UPDATE_DATE DATE
LAST_UPDATE_LOGIN NUMBER
一般form开发时,设置CREATION_DATE和LAST_UPDATE_DATE两个字段的subclass为:CREATION_OR_LAST_UPDATE_DATE,这样可以看到form的更新日期是谁。

一般在XXXX_private包中会包含该代码。

4.item的动态布局
基本思路:
①.改变LIST item的值,在when-list-changed(或者其他触发器)内包含如下代码DECLARE
timer_id timer;
BEGIN
timer_id := create_timer('SET_LINE_LAYOUT',
1,
no_repeat);
END;
参数1:表示这个timer定时器的名字
参数2:表示执行定时器的间隔时间
参数3:是否重复执行,还有一个值为repeat(重复执行)
②在FORM级的WHEN-TIMER-EXPIRED内调用
IF get_application_property(timer_name) = 'SET_LINE_LAYOUT'THEN SET_LINE_DYMIC_LAYOUT(:pc_req_headers.DOC_TYPE_CODE,'PC_REQ_HE ADERS');
ENDIF;
③. SET_LINE_DYMIC_LAYOUT是一个存储过程。

动态行布局.txt
关于代码详解:。

相关文档
最新文档