Form技巧:如果在输入Item之后,可以自动执行GO_BLOCK等内置函数
2012-09-25 08:34
295 查看
很多时候,我们想实现这样子的操作效果:
当向一个特定的Item输入数据之后,自动触发一系列的动作,例如GO_BLOCK,然后Loop这个Block,向这个Block维护一定的值(或者检查值)。这样子可以很大程度方便User操作(因为是自动操作的)。
但是,众所周知,如果在WHEN-VALIDATE-ITEM等触发器用GO_BLOCK等导航的内置函数,会报错:FRM-40737存在非法的受限过程。因为验证的触发器是不可以导航到别的记录的(大部分触发器都不可以)。
这里发现一个触发器可以达到这个效果:KEY-NEXT-ITEM。
这个触发器KEY-NEXT-ITEM是当用户向对应的Item输入数据,然后点Tab按键或者Enter按键(当然,画面没有Enter就直接调用的按钮)的时候,会触发这个触发器。而这个触发器是可以随意做一些我们想做的动作。例如跳到别的Item,别的Block等等。
但是,用这个触发器的程序猿会发现,如果用户录入数据的导航方式不是:向特定的Item输入值之后,用键盘Tab(或者Enter)导航到下一个Item;而是用鼠标直接点击,那是触发不了KEY-NEXT-ITEM事件,从而导致程序有隐含的bug!
怎么办?这里给出一个解决方案,虽然不是最好的,但是却是可以用的:对于这个Item,禁用鼠标导航的操作方式!
如何禁用?其原理:利用当用户点Tab按键的时候,触发器的顺序是:先触发KEY-NEXT-ITEM;再触发WHEN-VALIDATE-ITEM。当用户直接用鼠标导航的时候,只是触发WHEN-VALIDATE-ITEM。所以在WHEN-VALIDATE-ITEM下手即可,用RAISE
FORM_TRIGGER_FAILURE;禁用。
实现步骤:
1 增加一个参数::PARAMETER.CURRENT_KEY_MODE。目的是为了区分用户的录入之后,导航的方式。
2 在WHEN-VALIDATE-ITEM触发器直接写下面的代码:
Begin
---当有变更,而且CURRENT_KEY_MODE(输入之后的导航类型)不是KEY-NEXT-ITEM的时候,必须用tab按键或者enter导航!
FND_MESSAGE.DEBUG('WHEN-VALIDATE-ITEM1');
IF :MDS_CONTROL.SCHEDULE_DATE IS NOT NULL AND NVL(:PARAMETER.CURRENT_KEY_MODE,'WHEN-VALIDATE-ITEM') <> 'KEY-NEXT-ITEM' THEN
FND_MESSAGE.SET_STRING('请注意:该栏位输入之后,请按Tab按键或者Enter按键导航!');
FND_MESSAGE.HINT;
RAISE FORM_TRIGGER_FAILURE;---禁止用户用鼠标点击导航!
END IF;
FND_MESSAGE.DEBUG('WHEN-VALIDATE-ITEM2');
End;
3 然后在KEY-NEXT-ITEM增加代码:
Declare
l_cur_record Number;
Begin
FND_MESSAGE.DEBUG('KEY-NEXT-ITEM1');
If :MDS_CONTROL.SCHEDULE_DATE Is Not Null Then
:PARAMETER.CURRENT_KEY_MODE := 'KEY-NEXT-ITEM';
Go_Block('XYG_MANUFACTURE_NEED');
l_cur_record := :SYSTEM.cursor_record;
First_Record;
Loop
If Nvl(:XYG_MANUFACTURE_NEED.CHK,'N')='Y' AND NVL(:XYG_MANUFACTURE_NEED.SCHEDULE_DATE,SYSDATE) <> :MDS_CONTROL.SCHEDULE_DATE
AND NVL(:XYG_MANUFACTURE_NEED.PROCESS_STATUS,'N') = 'Y' ---没审核的不可以预排
Then
:XYG_MANUFACTURE_NEED.SCHEDULE_DATE := :MDS_CONTROL.SCHEDULE_DATE;
---2011-10-19 samt add
:XYG_MANUFACTURE_NEED.SCHEDULE_USER_ID := FND_GLOBAL.USER_ID;
:XYG_MANUFACTURE_NEED.SCHEDULE_USER :=SUBSTRB( XYG_PUB_COMMON_PKG.GET_FND_FULL_NAME(FND_GLOBAL.USER_ID,SYSDATE,0),1,240) ;--FND_GLOBAL.USER_NAME;
End If;
Exit When :SYSTEM.LAST_RECORD='TRUE';
Next_Record;
End Loop;
--:MDS_CONTROL.SCHEDULE_DATE := NULL; ---清空
Go_record(l_cur_record);
:PARAMETER.CURRENT_KEY_MODE := 'WHEN-VALIDATE-ITEM';
End If;
FND_MESSAGE.DEBUG('KEY-NEXT-ITEM2');
End;
----2014.9.26更新:
有个问题:
form header block中的一个item值发生变化,自动删除 line block中的值,这个你一般怎么做的?
一个办法是:
先增加一个对应要核对头Item是否发生变化的判断Item,可以叫ITEM_COPY之类的,非数据块的。
在Key-commit的时候,再判断这个头的ITEM_COPY是否<>ITEM,如果是,则自动删除行的内容。
因为KEY-COMMIT是可以实现GO_BLOCK,清除BLOCK等动作。
另外,在用户试图进入到行BLOCK的时候,如果头的ITEM_COPY是否<>ITEM,则提醒用户:这个ITEM的值发生变化了,请保存。
就可以实现这个效果了。
另外一个办法:
还是增加一个ITEM_COPY(比对是否有做修改嘛,这个是必须的),然后在被修改的ITEM的WHEN-VALIDATE-ITEM触发器里面,判断是否值被修改(ITEM_COPY<>ITEM),如果是,则自动在数据库DELETE记录,并且标识一个有自动做了DELETE记录的标识(可以用PARAMETER做,要考虑多个头的数据行的切换的问题。)
然后当用户点到行Block的时候,系统判断上面的(是否有自动做了DELETE记录的标识),如果是=Y,则自动刷新行的BLOCK即可。
这样子的话,就可以完全防呆了,反正有做了修改,DB数据库一定会删除记录。只不过对于用户来说刷新动作晚了一点而已。
其实可以给个提示
当删掉行数据之后,直接提示:
您已经修改了这个值,系统已经在后台将行记录清空。请鼠标点到行块以确认数据。
最后的办法:
这个办法是我这个帖子说的办法,但是不是很建议,因为这个办法阉割了用户用鼠标操作画面的操作模式。
当向一个特定的Item输入数据之后,自动触发一系列的动作,例如GO_BLOCK,然后Loop这个Block,向这个Block维护一定的值(或者检查值)。这样子可以很大程度方便User操作(因为是自动操作的)。
但是,众所周知,如果在WHEN-VALIDATE-ITEM等触发器用GO_BLOCK等导航的内置函数,会报错:FRM-40737存在非法的受限过程。因为验证的触发器是不可以导航到别的记录的(大部分触发器都不可以)。
这里发现一个触发器可以达到这个效果:KEY-NEXT-ITEM。
这个触发器KEY-NEXT-ITEM是当用户向对应的Item输入数据,然后点Tab按键或者Enter按键(当然,画面没有Enter就直接调用的按钮)的时候,会触发这个触发器。而这个触发器是可以随意做一些我们想做的动作。例如跳到别的Item,别的Block等等。
但是,用这个触发器的程序猿会发现,如果用户录入数据的导航方式不是:向特定的Item输入值之后,用键盘Tab(或者Enter)导航到下一个Item;而是用鼠标直接点击,那是触发不了KEY-NEXT-ITEM事件,从而导致程序有隐含的bug!
怎么办?这里给出一个解决方案,虽然不是最好的,但是却是可以用的:对于这个Item,禁用鼠标导航的操作方式!
如何禁用?其原理:利用当用户点Tab按键的时候,触发器的顺序是:先触发KEY-NEXT-ITEM;再触发WHEN-VALIDATE-ITEM。当用户直接用鼠标导航的时候,只是触发WHEN-VALIDATE-ITEM。所以在WHEN-VALIDATE-ITEM下手即可,用RAISE
FORM_TRIGGER_FAILURE;禁用。
实现步骤:
1 增加一个参数::PARAMETER.CURRENT_KEY_MODE。目的是为了区分用户的录入之后,导航的方式。
2 在WHEN-VALIDATE-ITEM触发器直接写下面的代码:
Begin
---当有变更,而且CURRENT_KEY_MODE(输入之后的导航类型)不是KEY-NEXT-ITEM的时候,必须用tab按键或者enter导航!
FND_MESSAGE.DEBUG('WHEN-VALIDATE-ITEM1');
IF :MDS_CONTROL.SCHEDULE_DATE IS NOT NULL AND NVL(:PARAMETER.CURRENT_KEY_MODE,'WHEN-VALIDATE-ITEM') <> 'KEY-NEXT-ITEM' THEN
FND_MESSAGE.SET_STRING('请注意:该栏位输入之后,请按Tab按键或者Enter按键导航!');
FND_MESSAGE.HINT;
RAISE FORM_TRIGGER_FAILURE;---禁止用户用鼠标点击导航!
END IF;
FND_MESSAGE.DEBUG('WHEN-VALIDATE-ITEM2');
End;
3 然后在KEY-NEXT-ITEM增加代码:
Declare
l_cur_record Number;
Begin
FND_MESSAGE.DEBUG('KEY-NEXT-ITEM1');
If :MDS_CONTROL.SCHEDULE_DATE Is Not Null Then
:PARAMETER.CURRENT_KEY_MODE := 'KEY-NEXT-ITEM';
Go_Block('XYG_MANUFACTURE_NEED');
l_cur_record := :SYSTEM.cursor_record;
First_Record;
Loop
If Nvl(:XYG_MANUFACTURE_NEED.CHK,'N')='Y' AND NVL(:XYG_MANUFACTURE_NEED.SCHEDULE_DATE,SYSDATE) <> :MDS_CONTROL.SCHEDULE_DATE
AND NVL(:XYG_MANUFACTURE_NEED.PROCESS_STATUS,'N') = 'Y' ---没审核的不可以预排
Then
:XYG_MANUFACTURE_NEED.SCHEDULE_DATE := :MDS_CONTROL.SCHEDULE_DATE;
---2011-10-19 samt add
:XYG_MANUFACTURE_NEED.SCHEDULE_USER_ID := FND_GLOBAL.USER_ID;
:XYG_MANUFACTURE_NEED.SCHEDULE_USER :=SUBSTRB( XYG_PUB_COMMON_PKG.GET_FND_FULL_NAME(FND_GLOBAL.USER_ID,SYSDATE,0),1,240) ;--FND_GLOBAL.USER_NAME;
End If;
Exit When :SYSTEM.LAST_RECORD='TRUE';
Next_Record;
End Loop;
--:MDS_CONTROL.SCHEDULE_DATE := NULL; ---清空
Go_record(l_cur_record);
:PARAMETER.CURRENT_KEY_MODE := 'WHEN-VALIDATE-ITEM';
End If;
FND_MESSAGE.DEBUG('KEY-NEXT-ITEM2');
End;
----2014.9.26更新:
有个问题:
form header block中的一个item值发生变化,自动删除 line block中的值,这个你一般怎么做的?
一个办法是:
先增加一个对应要核对头Item是否发生变化的判断Item,可以叫ITEM_COPY之类的,非数据块的。
在Key-commit的时候,再判断这个头的ITEM_COPY是否<>ITEM,如果是,则自动删除行的内容。
因为KEY-COMMIT是可以实现GO_BLOCK,清除BLOCK等动作。
另外,在用户试图进入到行BLOCK的时候,如果头的ITEM_COPY是否<>ITEM,则提醒用户:这个ITEM的值发生变化了,请保存。
就可以实现这个效果了。
另外一个办法:
还是增加一个ITEM_COPY(比对是否有做修改嘛,这个是必须的),然后在被修改的ITEM的WHEN-VALIDATE-ITEM触发器里面,判断是否值被修改(ITEM_COPY<>ITEM),如果是,则自动在数据库DELETE记录,并且标识一个有自动做了DELETE记录的标识(可以用PARAMETER做,要考虑多个头的数据行的切换的问题。)
然后当用户点到行Block的时候,系统判断上面的(是否有自动做了DELETE记录的标识),如果是=Y,则自动刷新行的BLOCK即可。
这样子的话,就可以完全防呆了,反正有做了修改,DB数据库一定会删除记录。只不过对于用户来说刷新动作晚了一点而已。
其实可以给个提示
当删掉行数据之后,直接提示:
您已经修改了这个值,系统已经在后台将行记录清空。请鼠标点到行块以确认数据。
最后的办法:
这个办法是我这个帖子说的办法,但是不是很建议,因为这个办法阉割了用户用鼠标操作画面的操作模式。
相关文章推荐
- S1006 scanf()可以全部输入数字再点击,程序自动执行
- C#代码生成器 如果发生重构或模板变更可以直接覆盖,在自动生成之后不会被覆盖,防止误操作?
- C#代码生成器 如果发生重构或模板变更可以直接覆盖,在自动生成之后不会被覆盖,防止误操作?
- Q:当我将USB设备链接至计算机时,WinDriver会自动显示出USB的ID,但当我在执行热插入时,该USB的ID会变更,因此我无法确认该ID是指何者设备。请问WinDriver是否可以定义该设备的ID内容在执行热插入前后皆是相同的?
- 解决vscod 执行python 在控制台输入 以后不自动执行下一行代码的问题
- Oracle错误:动态执行表不可访问,本会话自动统计被禁止,关闭自动统计之后的问题
- shell 脚本监控程序是否正在执行, 如果没有执行, 则自动启动该进程
- Spring-boot中添加commandLineRunner之后,写单元测试会自动执行commandLineRunner的解决方案
- form中的button按钮在IE11中自动提交表单问题导致弹出框关闭之后表单被重置
- 初学iOS,刚看到控件的strong&weak问题,如果答的不对还请指正。首先有一点,在OC中,如果对象没有强引用,就会被自动释放,那么为什么控件还可以设为weak?
- 一个班有n个学生,需要把每个学生的简单资料(姓名和学号)输入计算机保存。然后可以通过输入某一学生的姓名查找其有关资料。当输入一个姓名后程序就查找该班有无此学生,如果有,则输出他的姓名和学号,如果找不到
- 通过点击Item的图标可以实现对可执行文件的调用
- Unix/Linux 下如果手动执行脚本可以正常运行,而放在crontab里面就有问题的话
- Oracle错误:动态执行表不可访问,本会话自动统计被禁止,关闭自动统计之后的问题
- 【Mac技巧】mac自带的safari游览器默认百度可以输入关键字无法正常搜索了
- cocos2d-x 打包成so文件之后,如果出现错误,可以使用ndk-stack来查看里面的异常
- FORM 中输入一条记录自动保存?如何做到
- 为什么mysql设置了密码之后,本地还可以直接访问,不需要输入密码就可以登录数据库了?
- 判断文本框里是否输入值,如果没有输入就会让其焦点自动到其那儿
- 关于Oracle错误:动态执行表不可访问,本会话自动统计被禁止,关闭自动统计之后的问题