ebs form开发总结

更新时间:2024-01-24 13:39:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

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(模

板中的FOLDER块有现成的trigger) PRE-QUERY//POST-QUERY WHEN-NEW-BLOCK-INSTANCE //WHEN-NEW-RECORD-INSTANCE…

提示项的item type为display,子类为FOLDER_PROMT_MULTIROW 第四步:在when-new-form-instance初始化form。

使用app_folder.define_folder_block

如果用到了FIX画布,需要使用参数8

第五步:在画布上调整布局

设置块的Scrool Bar Canvas在fix画布上 注意:

ITEM名称 FOLDER_SWITCHER DRILLDOWN_RECORD_INDICATOR FOLDER_TITLE FOLDER_OPEN 画布 FIX ~~ 子类 SWITCHER DRILLDOWN_RECORD_INDICATOR DYNAMIC_TITLE FOLDER_OPEN FOLDER_DUMMY ORDER_BY1 TOOLBAR FOLDER_DUMMY STK FOLDER_ORDERBY 第六步:在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.txtshow_main_tab.txtgo_tab_first_item.txt

以下的两个过程是为了防止bug

参考(\\桌面\\ebs常用文档大全\\FOLDER) 1.在FORM触发器内 ELSIF (event = 'FOLDER_RETURN_ACTION') THEN if(:global.folder_action = 'CONFIRM-HIDE-FIELD') THEN if :global.folder_filed = 'ADDITION1' THEN :global.folder_action_allowerd := 'FALSE'; END IF; end if; 2.在block触发器 elsif event = 'WHEN-NEW-ITEM-INSTANCE'then curr_canvas_name := get_item_property(name_in('SYSTEM.CURSOR_ITEM'), item_canvas); current_tab := get_canvas_property('MAIN_TAB', topmost_tab_page); tab_canvas_name := name_in('SYSTEM.EVENT_CANVAS'); IF curr_canvas_name IN ('TAX_STK','BASE_STK') THEN IF curr_canvas_name != current_tab THEN set_canvas_property('MAIN_TAB', topmost_tab_page, curr_canvas_name); ENDIF; ENDIF; 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.4在pre-form触发器获取账户结构ID select b.CHART_OF_ACCOUNTS_ID from gl_sets_of_books b where b.SET_OF_BOOKS_ID = fnd_profile.value('GL_SET_OF_BKS_ID')

4.5 初始化键弹性域 fnd_key_flex.define( block =>'DETAIL', field =>'CODE_COMBINATION', appl_short_name =>'SQLGL',--注册的应用简称 code =>'GL#',--弹性域的注册代码 id =>'GL_CCID', description =>'COMBINATION_DESC', num =>':parameter.CHARTS_ACCOUNT_ID');--4.4得到的账户结构ID 4.6遇到的奇葩问题 1).建好弹性域以后,如果我们为账户项赋了值以后,会自动获取数据库表项的值(GL_CCID),如果你有自己的函数来为数据库表项赋值(在系统自动获取之前),那就会被自动获取的值覆盖,关键是这个自动获取的值还有可能是错误的,所以在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.启用功能

fnd_function.execute(function_name INVARCHAR2, open_flag INVARCHAR2DEFAULT'Y', session_flag INVARCHAR2DEFAULT'SESSION', other_params INVARCHAR2DEFAULTNULL, activate INVARCHAR2DEFAULT'ACTIVATE', browser_target INVARCHAR2DEFAULTNULL); 关于详细介绍请查看 http://note.youdao.com/share/?id=cfde5dcc68e15a303e53a4f8b5166919&type=note

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', :PARAMETER.ORG_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 \property\= Window1, and Window2 has \Primary

Canvasproperty\

In this case you have to put (for Canvas1) \property\= Window2 or (for Window2) \

大概意思就是一个画布只能对应一个窗口

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已过时,请及时更新。将域名添加到可信任站点中即可

本文来源:https://www.bwwdw.com/article/abuo.html

Top