2024年6月15日发(作者:)

Form个性化学习

拷贝号 _____

文档控制

变更记录

1

日期

作者

版本

变更说明

审阅

姓名

职位

分发

拷贝编号

姓名

位置/岗位

1

2

3

4

备注:

Form 个性化

FORM个性化是.10新增的功能。通过个性化设置,我们可以不必去修改ORACLE的

FORM源码而实现FORM标准功能的修改,因为个性化代码是独立储存在数据库表中

的,FORM的升级均对此无影响。所以在项目上要对FORM进行修改时,如果能行,

最好还是用FORM个性化来实现。

Form个性化可以减少开发的时间,Form个性化可以完成很多功能,比如:当打开From

时弹出一个消息框、修改Item的属性、调用一个功能、新建一个菜单项等等。

Form个性化可以在界面上修改实现,也可以修改文件来实现,本文侧重是

以在界面上修改为例,本文参考了METALINK Note:279034.1上提供的几个文档

个性化前提

预定义文件

控制form个性化的显示和进入,和控制“诊断”是一样的PROFILE,所以我们首先查

看预定义文件:

FND_HIDE_DIAGNOSTICS (是否隐藏“诊断”)

DIAGNOSTICS (进入“诊断”是否需要apps密码)

隐藏诊断菜单项

个性化步骤

➢ 打开form个性化: 工具栏:帮助-诊断-自定义代码-个性化。打开以后我们可以看

到function和 form的名称,其实从这里来看当前function的名称也是一个便捷的

方法

如图:

定义form个性化:包括条件、活动等

设置完成后,保存,关闭所有form。Form个性化需要重新打开form才可以起作

用。后面提及的需要重新登陆EBS才能够起作用。 Form个性化的

界面主要分为规则头、条件tab页、上下文、活动tab页四个部分

个性化入门案例

下面废话不多说了,先通过一个经典入门案例来SHOW一下然后再具体解析各个属性

是干嘛用的。

Hello World !

我们随便打开一个Form。此处选择的是在:应用开发员>应用产品>注册

工具栏:帮助-诊断-自定义代码-个性化

个性化头上的属性值为

序号

10

➢ 条件Tab页的属性值为

触发器事件

WHEN-NEW-FORM-INSTANCE

条件

Hello World

处理模式

不在输入-查询模式下

说明

Hello World

功能

➢ 活动Tab页的属性值为

序号

10

类型

消息

消息类型

显示

消息文本

Hello world!

➢ 然后保存,关闭Form,再打开Form,就会看到效果了

个性化属性设置

个性化定义头部

函数名:当前Function的名称

表单名称:当前Form的名称

调试模式:

“显示调试信息”在活动Tab页,活动类型选“消息”,消息类型选“调试”

时,消息可以显示出来,如果不选,则显示不出调试信息

“关闭”不允许显示消息,即使活动类型选择“消息”也不显示

“逐步”每次应用满足一个个性化规则时都提示

序号:序号小的会先执行,当然如果序号2的条件中的触发器在序号1之前触发,

那么2肯定比1先执行,序号允许重复

说明:不多说

层:

“功能”表示该个性化规则适用于当前Function,

“表单”该个性化规则适用于当前表单

➢ 启用:不选择则不执行这个个性化规则

个性化条件Tab页

主要定义个性化规则的触发的时间和条件

触发器事件:个性化规则触发的时间触发器

触发器对象:执行规则的对象,比如BLOCK或者ITEM

条件:执行该触发器需要满足的条件,写法:

➢ 处理模式:

“不在“输入-查询”模式下” 正常模式和“录入-查询”模式下都触发

“仅在“输入-查询”模式下”

“两者兼有”

➢ 上下文:“层”有行业、地点、职责、用户。注意,与一般的概念不同,这几个只

要有一个满足条件就会触发该个性化规则。

个性化活动Tab页

在这里面定义的是个性化规则具体要做的事情

序号:

类型:有特性、消息、内置、特殊(或菜单)。特性用来指定一个对象,指定对象

的某个属性,为这个属性指定一个值。消息用来弹出不同类型的信息。内置可以执

行一些标准的form的Builtin,例如GO_BLOCK,DO_KEY等等。特殊(或菜单),

定义special的行为。

个性化底部按钮

插入“获取”表达式:获取SPEL表达式(下面会有解释)

插入项目值:往当前的输入框插入当前Form中选中的ITEM的值

验证:用来测试输入的字符串是否符合语法,如果不符和会报错。如果正确,会弹

出结果。

现在申请:立即应用所做的个性化规则,只对某些类型适用,还是要以实际运行中

为准。

个性化实例

➢ 头和条件填写为如图所示

当活动Tab页填写为

把APPLICATION. APPLICATION_NAME的提示改成了TEST

当输入为:

此时执行的触发器只能为WHEN-NEW-FORM-INSTANCE

效果为在工具栏上增加了一个名为TEST的菜单项

当我们输入为:

此时会打开百度网页

当我们输入为:

会执行cux_test_过程

上面就是一些简单例子,其他的属性可以自己去尝试。

输入时需要注意的问题

规则

个性化的赋值或写条件的时候是有一些规则的,例如在form个性化里面取item的值

用:,也可以用SPEL,不能用name_in()(但是在后面说的中,

只能用name_in())。获取属性不能用GET_ITEM_PROPERTY等。

赋值条件及写法

在消息里面,或是给对象的属性、参数赋值时,都涉及到字符串。字符串的赋值有一些

规则:

如果输入的字符串前面没有“=”的话,那么输入的字符串就是所赋的值。

字符串的长度是有限的。

如果输入的字符串是以“=”开始的话,那么后面的字符串在运行时会被作为表达

式被计算出结果来,再赋值。例如以下的各种形式:

||, TO_CHAR, DECODE, NVL等。

(:), including :system, :global and :parameter values。

调用函数。

select语句。写成“=select”,返回的列只能是字符型的,如果不是。可以用

TO_CHAR处理一下,长度不能超过2000bytes,而且只能返回一列,如果返

回多列,也只取第一列

下面这个列表举例说明了上面的规则(引用oracle文档):

SPEL(Simplest Possible Expression Language)

${ty}

例如:${__red}

SPEL替代了一些form builtins,比如

GET_ITEM_PROPERTY,GET_BLOCK_PROPERTY等。另外,它还可以获取PROFILE、

消息字典的值,以及Local Variables(Local Variables也是新增的,它类似与全局变量,

但是只能在当前form使用,最大长度是4000 bytes,全局变量只有255 bytes)

个性化提升案例

本案例是对并发程序的标准表单进行个性化,要实现的功能是增加一个菜单项实现点击

该菜单时打开可执行程序定义的标准表单界面并对当前的并发程序进行查询(练习用)

整体逻辑

步骤

➢ 打开并发程序定义界面,再打开FORM个性化界面,定义一个名为Executable的

个性化规则,对应的触发器事件为WHEN-NEW-FORM-INSTANCE

打开并发程序定义界面,在Tools菜单栏下新加一个菜单项。

点击该菜单时,如果并发程序名为空,则报一个错误。

如果可执行名非空,增加一个全局变量 ,储存可执行的名称。

点击新增的菜单项,可以打开可执行FORM。

当打开可执行FORM时,对上述定义的全局变量进行初始化。

进入查询模式。

将全局变量的值赋予可执行名称项值。

进行查询。

清除全局变量的值

➢ 在Actions里,增加一个Menu类型,其中Menu Entry选择’SPECIAL1’(SPECIAL1

至15是在Tools菜单下,16至30是在Reports菜单下,31至45在Actions菜单

下),Menu Label输入’Executable’(即菜单项标签),Icon Name为’CONC_PROG’

即并发程序FORM对应的BLOCK

保存,打开可执行界面,可以看到新增的菜单项,点击,没有事件发生。

在可执行界面下,打开FORM个性化界面,我们增加一个事件为,如果可执行的

名称为空,则报一个错误’Please Enter Executable Name!’。新增一个个性化

规则Check Executable Name,Trigger Event为SPECIAL1,条件为可执行名称为

空。即’:CONC_ABLE_NAME IS NULL’

➢ 在Actions下,设置一个Meassage 类型,Message Type为Error,Message Text

为Please Enter Executable Name!

保存。打开并发程序定义界面,Executable Name项为空,直接点击Executable。

在并发定义界面下,打开FORM个性化界面。我们先定义一个全局变量,储存可

执行的名称,在后面中要用到。新增一个名为Excutable Entered的个性化规则,

Trigger Event为SPECIAL1,条件为:CONC_ABLE_NAME is not

null

➢ 在Actions里加入一个Property类型,Object Type为Global Variable即全局变量,

变量名为XX_XH_EXECUTABLE_NAME,为了便于区分,我们FORM个性化的

全局变量全部以XX_开头。Property Name为VALUE,Value为

=:CONC_ABLE_NAME(前面有=号,如果不加等号的话,会被赋

值为’ :CONC_ABLE_NAME’)。

➢ 再增加一个Builtin类型,Builtin Type为Lunch a Function即调用一个功能,

Function Code为FND_FNDCPMFE即可执行对应的功能,Function Name会被

自动调出。

➢ 保存。打开并发程序界面,查找一个并发程序,点击Tools>Executable,可以看到

可执行定义界面被调出,但是没有数据。

➢ 关闭并发请求界面,打开可执行界面,再打开FORM个性化界面。新增加一个FORM

个性化规则INIT XX_XH_EXECUTABLE_NAME,触发器事件为

WHEN-NEW-FORM-INSTANCE。我们做这个个性化规则的目的是初始化全局变

量INIT XX_XH_EXECUTABLE_NAME。

➢ 在Actions下,增加一个Property 类型,Object Type 为Global Variable,变量

名为XX_XH_EXECUTABLE_NAME。Property Name为INITIAL VALUE(注意

与VALUE的区别,VALUE是直接赋值,而INITIAL VALUE为如果该变量为null

或未被创建,会被赋初值,如果有值的话,则不会覆盖),Value为=null。这个个

性化的目的是为了直接打开该FORM时,后面定义的用到此全局变量的个性化规

则有效。

➢ 新增一条名为Enter Query的个性化规则。触发器的事件为

WHEN-NEW-FORM-INSTANCE,条件为:_XH_EXECUTABLE_NAME

is not null 。即上面定义的那个全局变量的值不为空时才会执行。

➢ 在Actions,设置一个Builtin类型,Builtin Type为DO_KEY,就像在FORM中

直接执行的语句。设置Argument为ENTER_QUERY即进入查询模式。

➢ 新增一条名为’Execute Query’个性化规则,触发器项为

WHEN-NEW-RECORD-INSTANCE,对象为FND_EXECUTABLES,条件

为:_XH_EXECUTABLE_NAME is not null。Processing Mode改为Only

in Enter-Query Mode。主要是能在查询模式下继续执行该代码,如果不改在并发

程序界面调出可执行界面时,可执行会停在查询模式里。

➢ 在Actions里,设置type为Property,Object Type为Item,Target Object为

FND_ABLE_NAME,Property Name为VALUE,Value

为=:_XH_EXECUTABLE_NAME。

➢ 增加一个Builtin类型,Builtin Type 为DO_KEY,Argument为

EXECUTE_QUERY。即进行FND_ABLE_NAME的值

等于全局变量的查询。

➢ 新增一条名为Clear XX_XH_EXECUTABLE_NAME Value个性化规则。触发器事

件为WHEN-NEW-RECORD-INSTANCE ,对象为FND_EXECUTABLES,条件

为:_XH_EXECUTABLE_NAME is not null

➢ 在Actions里,设置Type为Property,Object Type为Global Variable,Target

Object XX_XH_EXECUTABLE_NAME ,Property Name为VALUE ,Value为

=null,即查询完之后将该全局变量的值清空。

➢ 至此,完成

个性化

从以上的描述,我们可以看到form个性化满足了我们对form做某些更改的需求,但是

还是有不少的局限。Oracle给我们的个性化还提供了一个途径:。

可以实现我们更加复杂的个性化需求。因为在这里,我们可以写更加复

杂的PLSQL,但是与我们直接在form里做修改相比,还是有很多限制的。

是标准的library,不管是调试还是其它的,都会影响到全局

从本质上来说,form个性化和是相同的,可以发现如果选择了:帮助-

诊断-自定义代码-关闭。的代码也不起作用了。

代码实现

编译命令

路径:$AU_TOP/RESOURCE

在$AU_TOP/RESOURCE路径下编译的命令:

frmcmp_batch module=$AU_TOP/RESOURCE / userid=apps/apps

Module_Type=LIBRARY

中的Function和Procedure

➢ function zoom_available return Boolean;

是否启用工具栏中:view-zoom ,例如

FUNCTION zoom_available RETURN BOOLEAN IS

form_name VARCHAR2(30) := name_in('t_form');

block_name VARCHAR2(30) := name_in('_block');

BEGIN

IF form_name = 'FNDCPMCP' AND block_name = '

CONC_PROG' THEN

RETURN TRUE;

ELSE

RETURN FALSE;

END IF;

RETURN FALSE;

END zoom_available;

➢ function style(event_name varchar2) return integer;

是用来指定下面event里面代码执行的方式,是先执行,后执行,还是覆盖。可选

的有:、、de、rd(默认

值).例如:

FUNCTION style(event_name VARCHAR2) RETURN INTEGER IS

BEGIN

IF event_name IN ('SPECIAL10', 'SPECIAL11', 'SPECIAL12') THEN

RETURN de;

ELSE

RETURN rd;

END IF;

END style;

➢ procedure event(event_name varchar2)

这是主要代码,这里面允许使用的触发器有

ZOOM 、WHEN-NEW-FORM-INSTANCE 、

WHEN-NEW-BLOCK-INSTANCE 、WHEN-NEW-RECORD-INSTANCE 、

WHEN-NEW-ITEM-INSTANCE 、WHEN-VALIDATE-RECORD,还有special

代码结构为:

PROCEDURE event(event_name VARCHAR2) IS

form_name VARCHAR2(30) := name_in('t_form');

block_name VARCHAR2(30) := name_in('_block');

BEGIN

IF (event_name = 'ZOOM') THEN

……--

个性化代码

ELSIF (event_name = 'WHEN-NEW-FORM-INSTANCE') THEN

IF (form_name = 'FNDCPMCP' AND block_name = 'CONC_PROG') THEN

……--

个性化指定的

form

block

trigger

的代码

END IF;

ELSIF (event_name = 'WHEN-NEW-BLOCK-INSTANCE') THEN

……

ELSIF (event_name = 'SPECIAL10') THEN

……

ELSE

NULL;

END IF;

END event;

个性化方法比较

通常会建议首先使用form个性化,其次是。在使用时,也建议

不直接在里面做客户化。因为是标准的library,不管是调试还

是其它的,都会影响到全局。有人建议比较好的做法是复制一份来做个性化,

比较认同。具体步骤:

将另外copy一份,起名为xx_,把xx_加载到

下(用form builder打开,在Attached Libraries里面加上xx_),

然后在的event 里面写代码:xx_(event_name); 。这样,我

们的客户化代码都可以放在xx_这个library里面,降低了风险。(这个没试

过,不知道效果会怎么样,o(∩_∩)o )

未决与已结问题

未决问题

序号

问题

解决方案

负责人

目标日期

实际日期

1

2

已结问题

序号

问题

解决方案

负责人

目标日期

实际日期