博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【ERP】如何在多行数据块中实现仅能勾选唯一的主联系人
阅读量:5823 次
发布时间:2019-06-18

本文共 2782 字,大约阅读时间需要 9 分钟。

功能背景

本篇所描述的功能是基于Oracle E-Businees Suite 11i 版应收模块的客户标准界面下的联系方式输入功能。有过该界面操作经历的同学应该知道,上面的主联系人标记在任何情况下只能选择唯一的一个。在实际的客户化开发中,该功能有时也是格外的有用。因此本人从标准客户界面上抽取出该功能,并作了一些格外的功能限制。

  

功能实现

前提

我们在FORM中有一个显示多行的数据块CONTACT,数据源为一张联系人表,暂且取名为ZZ_CONTACTS吧。该表除了拥有标记主联系人的字段PRIMARY_FLAG外,还包含其他一些信息,但本例中不太重要,故略之。

数据块: CONTACT

数据表: ZZ_CONTACTS

CREATE TABLE ZZ_CONTACTS (   CONTACT_ID NUMBER NOT NULL.   PRIMARY_FLAG VARCHAR2(1), -- 其他联系人信息   CONTACT_NAME VARCHAR2(30),   EMAIL VARCHAR2(30) -- ... ... );

实现

1. 为数据块CONTACT的PRIMARY_FLAG项添加触发器WHEN-CHECKBOX-CHANGED, 代码如下:

-- -- 当用户勾选了主联系人标记时,进行检查 -- IF :CONTACT.PRIMARY_FLAG = 'Y' THEN -- 执行检查   CONTACT_UTL.VALIDATE_PRIMARY_FLAG; END IF;

2. 在Form中创建程序包CONTACT_UTL来验证“界面显示部分”的主联系人的唯一性,代码如下:

程序包声明部分:

PACKAGE CONTACT_UTL IS PROCEDURE validate_primary_flag; END;

程序主体部分:

PACKAGE BODY CONTACT_UTL IS PROCEDURE validate_primary_flag IS      v_cur_blk varchar2(30) := name_in('system.cursor_block');      v_cur_rec number := name_in('system.cursor_record');      v_primary_flag varchar2(1);      b_validate_passed boolean := TRUE; BEGIN --      -- 备份当前主联系人标识      --      v_primary_flag := name_in(v_cur_blk || '.primary_flag'); -- 反选当前主标识,若之后的验证通过,再将其还原      IF v_primary_flag = 'Y' THEN        Copy('N', v_cur_blk || '.primary_flag'); END IF; -- 若当前记录仍有必输项未填写,则跳过验证,转向该ITEM      IF app_record.get_status(v_cur_blk) IN ('INSERT', 'CHANGED') THEN IF NAME_IN(v_cur_blk || '.EMAIL') IS NULL THEN           GO_ITEM(v_cur_blk || '.EMAIL'); RETURN; END IF; -- 更多验证...      END IF; --      -- 循环界面上的记录,如果之前已经有主联系人标记      -- 则打上验证失败标记      --      FIRST_RECORD;      LOOP IF v_primary_flag = name_in(v_cur_blk || '.primary_flag') AND           v_cur_rec != :system.cursor_record THEN            b_validate_passed := FALSE; EXIT; ELSE IF :system.last_record = 'TRUE' THEN EXIT; ELSE               NEXT_RECORD; END IF; END IF; END LOOP; -- 回复原始光标位置      GO_RECORD(v_cur_rec);      GO_ITEM(v_cur_blk || '.primary_flag');   -- 如果验证失败,报错,否则,回复其选中时的值      IF NOT b_validate_passed THEN         fnd_message.debug('Validate failed!');         RAISE form_trigger_failure; ELSE         Copy('Y', v_cur_blk || '.primary_flag'); END IF; END; END;

3. 最后,在向插入到数据库里之前,我们还要做一次数据库层面的验证,因为并不是所有的记录都显示在了form界面上,在这里,我采取的策略是以用户界面上最后验证通过的主联系人为主,其他的在数据表中并且未显示出来的主联系人记录则将其设为非主联系人。为此,我们要在数据块CONTACT的ON-INSERT触发器中添加如下代码:

-- CODE for ON-INSERT/ON-UPDATE trigger -- 代码... BEGIN IF :CONTACT.PRIMARY_FLAG = 'Y' THEN UPDATE ZZ_CONTACTS SET PRIMARY_FLAG = 'N' WHERE PRIMARY_FLAG = 'Y' AND ( CONTACT_ID IS NULL OR CONTACT_ID != :CONTACT.CONTACT_ID )     ; END IF; END; -- INSERT/UPDATE实现代码...

  

已知问题

在主从块设计中,该解决方案不能应用到主块上,明细块可以,主块在loop 记录的时候会引发GET_RELATION_PROPERTY非法调用的错误。目前还有找到什么解决方法,欢迎交流!

  

示例代码仅供参考,请根据实际需要进行修改:)

Enjoy!

转载于:https://www.cnblogs.com/objectorl/archive/2011/07/17/how-to-implement-primary-flag.html

你可能感兴趣的文章
PHP环境安装套件:快速安装LAMP环境
查看>>
CSS3
查看>>
ul下的li浮动,如何是ul有li的高度
查看>>
C++ primer plus
查看>>
python mysqlDB
查看>>
UVALive 3942 Remember the Word Tire+DP
查看>>
从微软的DBML文件中我们能学到什么(它告诉了我们什么是微软的重中之重)~目录...
查看>>
被需求搞的一塌糊涂,怎么办?
查看>>
c_数据结构_队的实现
查看>>
jquery 选择器总结
查看>>
1月10日,11日工作情况
查看>>
Qt设置背景图片
查看>>
Grunt使用心得
查看>>
【阿里云文档】常用文档整理
查看>>
iptables 配置需要保存
查看>>
.NET各种小问题
查看>>
ApkTool反编译和重新打包
查看>>
OpenState: Programming Platform-independent Stateful OpenFlow Applications Inside the Switch
查看>>
java中的Volatile关键字
查看>>
前端自定义图标
查看>>