Oracle EBS Form开发小技巧汇总

本文记录了一些在Form开发过程中积累下来的技巧:

  1. Form中提交并发请求
  2. 非数据库字段查询处理
  3. 控制Form为只查询
  4. 控制Item的属性
  5. Trigger的执行层次
  6. 按钮处理逻辑
  7. 日历相关

1,Form中提交并发请求

在提交请求之前,首先需要验证块,如果某些必填项没有填的话当然不能提交请求。

APP_STANDARD.APP_VALIDATE(BLOCK_SCOPE);

IF (not FORM_SUCCESS) THEN

Raise form_trigger_failure ;

END IF;

IF :SYSTEM.FORM_STATUS = 'CHANGED' THEN

DO_KEY('COMMIT_FORM');

END IF;

第二个IF语句判断系统状态,如果用户更新了一行记录,之后没有保存提交请求,那么需要在提交之前进行保存,因为可能使用的请求中使用到了该item所对应的后台字段,那么保存这一步就很重要了。

 补充APP_STANDARD.APP_VALIDATE知识:

procedure APP_RECORD.VALIDATE_RANGE(
from_item varchar2,
to_item varchar2,
range_name varchar2 default NULL,
event_name varchar2 default ’WHEN?BUTTON?PRESSED’,
dtype varchar2 default ’DATE’,
product_name varchar2 default NULL,
message_name varchar2 default NULL);
调用这个方法验证from 的值小于to 值这样的范围。在查询按钮的WHEN-BUTTON-PRESSED触发器中使用这个方法或在WHEN-VALIDATE-RECORD 触发器验证用户输入数据的范围是否合法。
APP_STANDARD 包APP_STANDARD.APP_VALIDATE
procedure APP_STANDARD.APP_VALIDATE (scope NUMBER);
这个方法和Oracle Forms中的内建程序Validate基本相似,不同的在于它导航到第一个导致验证失败的item,并且它提供按钮标准的支持。
Scope 验证的范围,包括你DEFAULT_SCOPE,FORM_SCOPE,BLOCK_SCOPE,RECORD_SCOPE和ITEM_SCOPE。

调用请求的例子:

l_request_id := fnd_request.submit_request ( 'XXPO',

'XXPO_JIT_BATCHES_RPT_SECOND',

'',

'',

FALSE,

:SUBJOBS.SUB_JOB_BATCH,

CHR(0)--CHR(0)表示参数结束

NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);

---如果请求提交出错将会返回0

if l_request_id = 0 then

        if NOT app_form.quietcommit then

fnd_message.debug('conc request submited failed');

raise FORM_TRIGGER_FAILURE;

end if;

fnd_message.set_name('FND', 'CONC-SUBMITTED REQUEST');

fnd_message.set_token('REQUEST_ID', to_char(l_request_id));

fnd_message.show;

end if;

请求运行结束以后,可能还需要对Block进行重新查询,这个由具体情况而定。

并发请求中有一个Start_Time的参数,可以设置成何时提交该请求。具体请参考User guide里面对fnd_request.submit_request的描述。

2,对于非数据库字段的查询

在Form中在查询的记录不希望某些记录显示出来,例如不需要供应商A被显示出来,假设供应商A是数据库项,可以使用

set_block_property(’block_name’,
                    DEFAULT_WHERE,
                    ‘VENDOR_NAME <>’ || ‘A’)

但是建议不要使用上述方法,因为Block的Default where一旦被设置了以后,并不是只有本次生效,而是一直生效,也就是当下一次使用Ctrl + F11来进行查询的时候,实际上,查询语句的where条件就一直加入了我们手动加进去的查询语句。所以建议使用app_query.append来添加复杂的查询语句。

我们的重点是对非数据字段的查询,也就是如果供应商为非数据库项,那么如果在查询窗口中刚好对供应商有这个查询条件,该如何去做?

由于供应商字段为非数据库项,那么只能在post-query中去判断,例如在post-query中写道:

If Vendor_name = ‘A’ then
  Raise form_trigger_failure;
End if;

那么供应商A将不会被显示出来。由于Post-query是在查询出每条记录时都执行的,所以raise form_trigger_failure并不影响只是阻止了本触发器,但是并不是阻止了所有的。

最后要说明的一点是建议还是不要采用这样的方式,因为这是效率最低的判断,如果可以使用数据库项进行查询,就尽量不要使用这个方法。

3,控制Form只查询

在定义Function的时候,如果在参数中加入QUERY_ONLY=YES,那么Form就只能查询,在Form中调用

FND_FUNCTION.EXECUTE( FUNCTION_NAME => ‘XXPOFJCT’,
                      OTHER_PARAMS  => ‘QUERY_ONLY=YES’);

那么新加出来的form就是只查询状态。这个QUERY_ONLY参数是系统自带的一个参数,但是实际上,它也是在Form的查询中,进行了对QUERY_ONLY参数的判断。所以需要特别注意的就是,当使用了这个参数后,客户化的Form在控制块查询时,是需要进行QUERY_ONLY参数判断的。

if name_in('parameter.query_only') ='Y' and :block.item = 'TTTT' then

set_block_property('block',update_allowed,property_true);

else

set_block_property('block',update_allowed,property_false);

end if;

对于上例中对块进行控制的语句,如果没有加入对QUERY_ONLY的判断,那么对具有只查询功能的Function来说,QUERY_ONLY这个就等于没有作用了,因为在这里,其他条件可能使得这个Form也是可以进行修改的。

4,控制Item的属性

凡是需要改变item属性,都使用app_item_property.set_property( )代替set_item_property。

假设通过某个item的值来决定另外一个item的属性,例如名为status的item值决定了名为quantity的item是否可以更改,首先,第一个触发器是POST-QUERY,当查询出记录出,根据status的值来决定quantity,当对某条记录进行更改的时候,需要对该记录进行重新判断(如果修改的status就可能需要做出改变),所以第二个触发器为ON-UPDATE(或者POST-UPDATE目前找不出区别来),第三个触发器为WHEN-NEW-RECORD-INSTANCE,当新建记录时,可能Item的默认值已经确定了,那么就需要对其进行判断(这个只是可能,根据具体事件进行处理).

PACKAGE BODY JOBS_PKG

 IS

procedure control_item_property

is

 begin

 if :JOBS.JOB_STATUS = 'NEW' then

app_item_property.set_property('JOBS.REQUIRED_QUANTITY',alterable,PROPERTY_ON);

else app_item_property.set_property('JOBS.REQUIRED_QUANTITY',alterable,PROPERTY_OFF);

end if;

end control_item_property; 

procedure block_event(event varchar2)

is

begin

if event = 'WHEN-NEW-RECORD-INSTANCE' then

control_item_property;

elsif event = 'POST-QUERY' then -- post-insert

control_item_property;

elsif event = 'POST-UPDATE' then

control_item_property;

else app_exception.invalid_argument('JOBS_PKG.BLOCK_EVENT','Event',event);

end if;

end block_event;

END JOBS_PKG;

5,Trigger的执行层次

执行层次属性可以指定,当上一级有同样名称的trigger时,当前的trigger代码如何执行。

有以下三种设置:

Override(忽略):本trigger会执行。上一级的同名trigger会被忽略(不执行)。

Before(之前):本trigger会在上一级同名的trigger之前执行。

After(之后):本trigger会在上一级同名的trigger之后执行。

一般来说,WHEN-NEW-BLOCK-INSTANCE,WHEN-NEW-RECORD-INSTANCE,WHEN-NEW-ITEM-INSTANCE,都需要把执行层次设置为before

6,按钮处理逻辑

点击按钮之前最好先检查一下系统的状态,可能用户在修改了某一些东西后直接点按钮,我们要帮他保存

另外在查询模式下不允许用户点按钮。

app_standard.app_validate(block_scope); 

if(not form_success) then

 raise form_trigger_failure;

end if

if :system.form_status = 'CHANGED' then

if not app_form.quietcommit then

raise form_trigger_failure;

end if;

end if;

7,关于日历

Calendar.show(first_date date):first_date指定日历出现时显示的初始日期,如果不填默认当前日期

Calendar.step(’name(标识符)’, <low_date>, <high_date>):可以屏蔽一个日期范围,第一个参数为标识名字(唯一,可任意)。<low_date>若为空则默认为无穷小,而<high_date>为空则默认无穷大

Calendar.step(’WEEKEND’):可以屏蔽周末,即周六周日的日期都不能用

综合的Exp:

需要使得ORD_HOLIDAYS表中的日期都不可用

calendar.setup( 'Manafacturing Holidays',

null , null ,

 'select action_date LOW_DATE, action_date HIGH_DATE'|| ' from org

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值