如何修改oracle ebs应用ip_百度知道snans 的BLOG
用户名:snans
文章数:29
访问量:56111
注册日期:
阅读量:5863
阅读量:12276
阅读量:324050
阅读量:1033941
51CTO推荐博文
oracle ebs 通配置文件可以改变界面的显示风格和显示颜色,一般我们默认显示风格为ORACLE风格(典型的蓝色)通过如下路径可以设置:系统管理员/配置文件/系统Profile Name:Java Look and Feel设置界面风格,Oracle 就是默认的蓝色调,Generic就是传统Windows风格。 Profile Name:Java Color Scheme
设置具体的界面颜色。下面通过网友的截图展示不同的设置,oracle ebs展现的风格颜色:defaultTealTitaniumRed BlueOlivePurple Khaki 本文出自 “” 博客,请务必保留此出处
了这篇文章
类别:┆阅读(0)┆评论(0)博客访问: 224857
博文数量: 405
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: 信息化
【内容导航】 第1页: 第2页: 第3页: 第4页: 第5页: 第6页: 第7页: 第8页: 第9页: 第10页: 第11页: 第12页: 第13页: 第14页: 第15页: 第16页: 第17页: 第18页: 第19页: [@more@]文本Tag: 【IT168 技术文档】
ORACLEERP开发基础之前言 ORACLE ERP开发之OracleForms基础(一)Forms设置部分 ORACLEERP开发基础之OracleForms基础(二)FORMS代码部份 ORACLE ERP开发基础之Oracle Report基础
ORACLEERP开发基础之Oracle数据库基础
开发工具安装 Oracle EBS11i 开发工具是developer6i的东西,非常古老。因为是转手过来的机器,开发工具都是安装好了, 所以也没去在意这工具的安装。今天系统重装了,才知道这工具安装起来也是特烦人的。 先安装FORMS6i与REPORT6i,安装完后一定要打补丁。否则会出现一大堆莫名的错误。接着安装discoverer。 安装discoverer时先将注册表备份出来,因为discoverer不能和Forms安装在同一目录。然后再安装 discoverer的补 丁,接着再将注册表恢复回来。 大致这样可以了。注意顺序一定要不能错了,否则又会出现一堆无聊的错误。唉!developer6i是98年的工 具。盼着EBS R12应该是用DEVELOPER10g吧。 EBS二次开发包注册 2.1 从 Server 中下载 ERP Library (.pll), 存放于本机Server Path : /u01/au/11.5.0/resource Form文件与Library文件要存放在固定目录 例如: Form存放在 d:ErpFormForm Library 存放在d:ErpFormL 2.2 在 Regedit > HKEY_LOCAL_MACHINE > SOFTWARE > ORACLE > FORMS60_PATH 加入client 端存放 Form 及 Library的路径(如图) 例如:d:ErpFormLd:ErpFormForm(建议要加在最前面) 利用TEMPLATE.fmb 模板来开发Form Oracle 已经为我们提供了一个Form 的开发模板,(/data/deve/devappl/au/11.5.0/forms/ZHS/TEMPLATE.fmb) 我们的开发实际要基于这个模板,这个模板里面已经存在了我们将会用到的Oracle 标准的对象,我们需要做的, 就是这这个模板的基础上面,添加我们自己的对象。这也是人家说二次开发没啥技术含量的重大原因。但如果 真让你出写那么PL 包,估计也没几人能写好。人有时就是这样,让你站在巨人的肩膀,还在抱怨这抱怨那的。 我也是这类人啦。出出气呀。^_^! 1、更改template.fmb 文件名,同时删除一些无用的样本对象。
2、增加数据块 一路照做就可以了,步骤太简单就不用讲了吧。完成后,选择“仅创建数据块”。 3、增加一个画布 选择工具菜单上面的布局向导来做。 注意:选择画布时,选择新画布。如上图。 显示记录数一般为10就可以了。如上图。 注:将画布名称改成与数据块的名称一致 4、增加一个窗口 注:窗口尽量保持与画面一致,同时选择相应的主画布。对应的画布那边也要选择主窗口 5、选择对象的子类信息 所有的对象都应选择相对的子类信息,这边仅以BLOCK为例。 6、调整布局 不需要显示到画布的ITEM,可以将ITEM的画布属性设成空 7、修改触发器(这一步很关键!) 8、选择第一导航块 9、上传及编译FORMS 9.1先将FORMS上传至/data/deve/devappl/au/11.5.0/forms/ZHS/ 9.2telnet至server,进入/data/deve/devappl/au/11.5.0/forms/ZHS/目录 目录:cd /data/deve/devappl/au/11.5.0/forms/ZHS/ 编译:f60gen FRMSTONE.fmb apps/apps 复制:cp FRMSTONE.fmx /data/deve/deveappl/hek/11.5.0/forms/ZHS/ 注:一定要进入FORM的目录,再进行编译。否则编译也可以通过,但会出现奇怪的问题。这个问题折腾了我二天时间,才发现是ORACLE的BUG。 好了,一个最基本的EBS FORM就开发完成了。 注册表单FORM 1.定义表单 操作路径:应用开发员=>应用产品=>表单 填写说明如下: 表单:FORMS文件名 应用:HEK 惠尔康客户化应用 用户表单名:这个参数与“功能”中的表单名是相关联的。 2.定义功能 操作路径:应用开发员=>应用产品=>功能 2.1 2.2 2.3 3.定义菜单 操作路径:应用开发员=>应用产品=>菜单 注:“子菜单”是指菜单可以将另一个菜单的功能全部包含进来。也就是父菜单的关系。 5. 完成设置,效果如下: 注册请求 1.定义可执行 路径:系统管理员->并发->方案->可执行 注意:定义成请求的过程或函数,必须加入(Errbuf Out Varchar2,Retcode Out Number)两个形参。 2.定义并发程序 路径:系统管理员->并发->方案->可执行 注意:并发程序界面的可执行组中的“名称”,与上面的可执行并发程序界面的“简称”是一致的。 注意:如果要传入参数到PL/SQL包中,点击《参数》按钮进行设置。 也可以为参数赋给默认值,例:默认取得用户ID 如果要限定参数的取数范围,则要定义值集(如何定义?请参考后面的定义值集)。 3.定义请求组 路径:系统管理员->性->责任->请求 4.将请求组置于职责下 系统管理员->安全性->责任->定义 注册职责 1.新建菜单 操作路径:应用开发员=>应用产品=>应用菜单 2.新建一个职责 操作路径:系统管理员=>性=>责任=>定义 将职责分配给用户 操作路径:系统管理员=>安全性=>用户=>定义 3.转到EBS主页,多显示一个职责。 注册值集 1.定义集 操作路径:总帐=>设置=>财务系统=>验证=>集 1.1如果值的来源于数据表,则值的验证类型选择“表”,然后点击“编辑信息”。 注:如果要实现请求参数的值集来源,作前后过滤条件的话。其语法: where head.customer_number = :$FLEX$.HEK_OM_KHJGB_ACCT_CUST and head.created_by = :$FLEX$.HEK_OM_FHD_CREATE_BY and TO_CHAR(head.ordered_date,'YYYYMMDD') = :$FLEX$.HEK_DAY_TIME_ID ORDER BY HEAD.ORDER_NUMBER :$FLEX$.为参数界面的名称 HEK_OM_KHJGB_ACCT_CUST为某个参数的值集名称。 1.2实现的效果如下: 1.3定义多列值集 1.4实现效果 1.5从属 2.定义值 2.1如果值的来源固定的某些值,那么可以直接定义值。将值的验证类型选择=>独立 2.2定义集所对应的值 操作路径:操作路径:总帐=>设置=>财务系统=>验证=>值 通过应用开发员取得系统管理员责任 一般公司都有区分DBA与DEVELOPER的,业务机上一般是APPS用户由DBA掌握,诸如用户管理也是DBA来负责的。developer是不知道 没有APPS密码,也没有‖SYSTEM ADMINISTTRATOR―职责的。也就是说DEVELOPER只有‖Application Developer―这个职责。同理,应用开发员是没有权限给终端用户加权限的。 但我今天测试了一下,developer虽然没直接加职责的权限,但developer有‖Application Developer―职责,这个职责下面有注册菜单的权限,完全可以通过注册菜单将SYSTEM ADMINISTROR加进来。如图: 查询视图时没有显示数据 在EBS以外的地方(含report),如果确认SQL语句没有问题,这主要是因为视图是OU屏蔽的,因此需要初始化身份。例如:PO_HEADERS。有两种方法,方法一适用于知道相应的组织代码,方法二就比较通用了。 方法一: BEGIN DBMS_APPLICATION_INFO.set_client_info(122); --122代表具体的组织代码,不同公司,代码是不同。 END; 方法二: BEGIN APPS.FND_GLOBAL.apps_initialize ( user_id =>APPS.FND_GLOBAL.user_id, resp_id =>APPS.FND_GLOBAL.resp_id, resp_appl_id =>APPS.FND_GLOBAL.resp_appl_id ); END; 注册报表(report) 路径:系统管理员->并发->方案->可执行 注册报表与注册请求的步骤是差不多的。 定义并发 路径:系统管理员->并发->方案->定义 定义报表参数 点击上图的参数按钮。 注:这边与注册请求不一样的就是,要填写变量栏(变量名称就是REPORT中的变量名称) 定义请求组 操作路径:系统管理员->性->责任->请求 将请求组置于职责下 系统管理员->安全性->责任->定义 OK,完成了报表的注册。 请求的输出及日志 1、Effect: Oracle EBS会在EBS的安装目录,保存查看输出及日志之文件。查看具体目录: select t.logfile_name,t.outfile_name from fnd_concurrent_requests t where t.request_id = _request_id 2、当我们自行定义了一个并发请求时,也经常需要使用上面的方式进行一些调试。 请求的输出:apps.Fnd_File.Put_line (apps.FND_FILE.OUTPUT, '请求的输出'); 请求的日志:apps.Fnd_File.Put_line (apps.FND_FILE.LOG, '请求的日志'); 对于报表,一般情况是把报表的内容输出到OUTPUT,把报表中间的debug逻辑输出到日志中。 对于请求包,一般情况是输出到日志中。OUTPUT就不用管了。 实现手动提交请求 在Form里面,我们可以用 APPS.FND_REQUEST.SUBMIT_REQUEST 提交一个Request到Oracle Request Manager。如果提交成功,该函数返回Request ID,否则,返回0。 1、初始化 在提交一个Request之前,我们会调用Oracle Standard的Procedure对这个Request做一些基本的参数的初始化。 APPS.FND_GLOBAL.apps_initialize ( user_id =>APPS.FND_GLOBAL.user_id, resp_id =>APPS.FND_GLOBAL.resp_id, resp_appl_id =>APPS.FND_GLOBAL.resp_appl_id ); 注:这个初始化不是必须的,之所以要初始化,是因为视图是OU屏蔽的。 上述语句等同于dbms_application_info.set_client_ 2、函数介绍 2.1 函数APPS.FND_REQUEST.SUBMIT_REQUEST有105个参数: APPS.FND_REQUEST.SUBMIT_REQUEST ( APPLICATION IN VARCHAR2 DEFAULT NULL, PROGRAM IN VARCHAR2 DEFAULT NULL, DESCRIPTION IN VARCHAR2 DEFAULT NULL, START_TIME IN VARCHAR2 DEFAULT NULL, SUB_REQUEST IN BOOLEAN DEFAULT FALSE, chr(0),'','','','','','','','','','','','','','','','','','','', '','','','','','','','','','', '','','','','','','','','','', '','','','','','','','','','', '','','','','','','','','','', '','','','','','','','','','', '','','','','','','','','','', '','','','','','','','','','', '','','','','','','','','','' ) RETURN NUMBER; 2.2 参数详解 2.2.1 APPLICATION(必需参数) 应用程序的名称缩写。一般我们可能会用到下面的几个: Oracle Assets „„> OFA Oracle General Ledger „„> SQLGL Oracle Inventory „„>INV Oracle Order Management „„>ONT Oracle Payables „„SQLAP Oracle Pricing „„QP Oracle Purchasing „„PO Oracle Receivables „„AR 操作路径:系统管理员=>应用=>注册 2.2.2 PROGRAM(必需参数) 要提交到Oracle Request Manager的并发程序之简称 操作路径:应用开发员=>并发=>程序 2.2.3 第三、第四个参数 第三、第四个参数默认为空 2.2.4 第五个参数 第五个参数默认为false 2.2.5 第六至第十零五个参数 第六至第十零五个参数为要传入到请求中的自定义参数值。如果无须这么多参数时,以chr(0)作为参数结束的标记。Chr(0)后面剩余的参数为 ‘‘。 手动提交请求示例 declare v_order_ v_req_ begin v_order_number := :HEK_ODS_TH_FEE_M_V.OE_HEAD_NUMBER; if :HEK_ODS_TH_FEE_M_V.OE_HEAD_NUMBER is null then FND_MESSAGE.DEBUG('请选择配送单后再打印!'); RAISE FORM_TRIGGER_FAILURE; v_req_id := fnd_request.submit_request('HEK', 'HEK_退货单', '', '', FALSE, v_order_number,--v_batch_no, null,--v_batch_no, null,--v_cust_num, null,--v_driver_num, null,--v_trans_num, null,--v_vendor_num, null, null,null, chr(0), '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '','', '', '', '', '', '', '', '', '', '','', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',''); if (v_req_id = 0) then FND_MESSAGE.RETRIEVE; FND_MESSAGE.ERROR; else update HEK_ODS_TH_FEE_M set print_mark='Y' where OE_HEAD_NUMBER = (v_order_number); commit_ fnd_message.debug('您的请求已经提交,请求号为:' || to_char(v_req_id) || ',请通过查看->请求来查看输出结果。'); 客制化菜单 Effect: Usage:调用 app_special.instantiate包 Examples: 1、增加一个自定义Form Level的触发器(SPECIAL11) 2、增加测试代码如下: ―――――――――――――――――――――――――――――――――――――――――――――― declare v_invoice_num varchar2(50); begin v_invoice_num := '菜单栏客制化100'; fnd_message.debug(v_invoice_num); ――――――――――――――――――――――――――――――――――――――――――――――― 3、在Form WHEN-NEW-FORM-INSTANCEFJ 进行调用: APP_SPECIAL.INSTANTIATE('SPECIAL11','测试菜单2', '', TRUE, 'LINE'); ――――――――――――――――――――――――――――――――――――――――――――――― 4、一些特殊说明: 上面自定义FORMS级触发器,名字必须定义为“SPECIAL+数字‖,否则会报错。并且数字的大小决定了菜单出现的先后顺序。数字还有更大作用就是决定了,自定义菜单选项放在哪个主菜单下。 SPECIAL1—SPECIAL15在“工具”主菜单下。 SPECIAL16—SPECIAL30在“报表”主菜单下。 SPECIAL31—SPECIAL45在“活动”主菜单下。 SPECIAL46以上就直接报错了。^_^ 如下图 5、 控制自定义菜单的是否激活可用。 使用app_special.enable函数可以控制菜单是否可以使用。 例如:基于不同的数据块,实现菜单的不可用。在block的‖when-new-block-instance‖中加入 效果: app_special.enable('SPECIAL1',property_off); 效果 6、 在自定义的菜单上使用checkbox按钮。 ①增加一个自定义Form Level的触发器(SPECIAL1_CHECKBOX),代码如下: if app_special.get_checkbox('SPECIAL1_CHECKBOX')='TRUE' then fnd_message.debug('Special 1 is True!'); else fnd_message.debug('Special 1 is False!'); 注:使用app_special.get_checkbox来获取checkbox的状态值。 ②在Form的WHEN-NEW-FORM-INSTANCE触发器中初始化菜单。 app_special.instantiate('SPECIAL1_CHECKBOX','Spe&cial 1 Box w Line', '',TRUE,'LINE'); app_special.set_checkbox('SPECIAL1_CHECKBOX','TRUE'); 注:app_special.set_checkbox是对checkbox进行赋值操作。 ③效果如下: 客制化右键菜单 1、 首先如果是要为某个ITEM,另外开发一个右键菜单。这个需要直接按照FORM的开发教程,自定义一个POPUP菜单就可以了。但本文讲的在EBS所有的快捷菜单上,额外增加所需的菜单按钮。也就是要图上所示的快捷菜单上增加菜单按钮。 2、 在FROM-LEVEL增加自定义触发器(名字规则为:POPUP+N) 3、 ITEM的“PRE-POPUP-MENU”触发器上初始化菜单。 APP_POPUP.INSTANTIATE('POPUP1','First Entry'); APP_POPUP.INSTANTIATE('POPUP10','SECONED Entry',TRUE,'LINE'); APP_POPUP.INSTANTIATE('POPUP3','THREE Entry',FALSE,NULL); 4、 如果是整个BLOCK的ITEM都需要客制化快捷菜单,可以在BLOCK的“PRE-POPUP-MENU”定义。 APP_POPUP.INSTANTIATE('POPUP1','global'); 调用EBS日期控件 1、 首先将ITEM的LOV属性设置为“ENABLE_LIST_LAMP”、列表验证属性设置为“否” 2、在ITEM的“KEY-LISTVAL”解发器下加入对下代码: BEGIN calendar.show(); END; 3、注意:ITEM对应数据库类型必须是DATE类型,否则会报frm-40700错误。效果如下: 查询数据时限定语言环境 EBS是个多语言的业务系统,界面上只查询到一条记录,实际上后台数据表是多条记录的。如:值集表。 select * from apps.FND_FLEX_VALUES_TL t, apps.FND_FLEX_VALUES B where B.FLEX_VALUE_ID = T.FLEX_VALUE_ID and t.language = userenv('LANG') 实现历史记录查询 1.要实现的效果 2.在定义数据表时,必须加入以下五个字段: 即:CREATED_BY NUMBER、CREATION_DATE DATE、LAST_UPDATED_BY NUMBER、LAST_UPDATE_DATE DATE、LAST_UPDATE_LOGIN NUMBER 网上有些文章说还必须定义主键、序列。但如果仅实现此功能是不需要的。当然从数据库设计方面来说,这些定义也是必须的。 3、在数据块的PRE-INSERT、PRE-UPDATE触发器中加入代码 FND_STANDARD.SET_WHO; 实现文件夹功能 1、在客制的Form里面实现Oracle Folder的功能,最终效果如下: 2、使用TEMPLATE.fmb创建一个Form(名称:FRMSTONE)。 2.1添加Form Objects 包括一个Window,MY_FOLDER 一个Canvas, MY_FOLDER 一个Block,MY_FOLDER(可以使用向导创建),并修改其属性。如下图: 注:使用文件夹的数据块,其名称总长不能超过22字节! 2.2修改Trigger和ProgramUnits Form Level Trigger: PRE-FORM: app_window.set_window_position('MYFOLDER', 'FIRST_WINDOW'); Program Units:APP_CUSTOM: if (wnd = 'MYFOLDER') then app_window.close_first_ 2.3修改FORM属性设置 注:须要说明的是:设成第一个导航数据块的blockname必须至少一个item处于canvas中,否则会报FRM-40106的错误。 2.4其他的具体步骤同一般的FORM开发一样,就不多说了。 3、添加Folder相关的Objects 3.1文件夹相关的Window、Canvas、Block、Item…等都包含在Oracle Standard Form APPSTAND.FMB。 3.2在同一窗口打开标准的Form和我们自己客制的Form,并且选择APPSTAND.FMB 的Object Groups STANDARD_FOLDER然后用拖动至我们自己的Form的Object Groups。 3.3此时会弹出对话框: 选择子类,你会发现Form Builder都会在你的Form里面自动添加很多对象。做完这一步后,请不要关闭APPSTAND.FMB。 4、增加Attached Libraries 做完上面的步骤后,检查一下Attached libraries里面有没有APPFLDR。如果没有,我们需要手工添加。 5、增加Stacked Canvas FOLDER_STACK 这一步是必须的,而且你期望实现Folder拖动功能的那些Item都是放在这个Canvas里面,这个Stacked Canvas又是放在前面我们建立的Canvas:MY_FOLDER上面的。 5.1增加Stacked Canvas 双击打开Canvas MY_FOLDER,在左侧工具条里面选择Stacked Canvas,然后在Canvas MY_FOLDER里面拖动即可。 5.2设置Stacked Canvas属性 6、更改数据块MY_FOLDER中的Item属性 7、创建控制块MY_FOLDER_PROMPT 7.1设置块的属性 子类信息:block 数据库数据块:否 7.2增加ITEM 注:增加Item,名称必须和Block MY_FOLDER中的Item保持一致。 另外,数据块中有些item(如id)不要显示在canvas上的,那么此类item也无须在MY_FOLDER_PROMPT创建相应的item. 7.2设置其初始值,也就是显示的标签名及子类信息 7.3增加其他相关Item 我们还需要增加其他的一些Item,都是和Folder的功能有关的。 8、增加相应的trigger 9、其他注意事项 9.1错误:在编译带有文件夹的FORM时,经常会出现如下提示。 FRM-30085: Unable to adjust form for output 这是因为ITEM超出的了画布的高度或是宽度造成的。如图: 可以通过调整ITEM的X坐标或Y坐标来解决此错误。 9.2错误:无法实现拖动。 解决:数据块的item与folder的item与调整一定的距离。 实现手电筒查找的功能 首先,先按TEMPLATE将其他功能先实现,然后再来实现查找的功能。手电筒查找的Effect有两二种,①LOV形式,②window形式。 1、LOV查找模式:一般适用于查询结果只返回单条条件的查询(如主从数据块的界面)。 ①创建一个parameter参数:TEST_P ②创建一个基于主键查询LOV-TEST_L,并将主键字段映射给Parameter参数TEST_P。 ③在数据块中创建PRE-QUERY触发器。 IF :parameter.G_query_find = 'TRUE' THEN :BLOCKNAME.HEADER_ID := :parameter.TEST_P; :parameter.G_query_find := 'FALSE'; ④在数据块中再创建QUERY_FIND触发器。 begin app_find.query_find('TEST_L'); --调用LOV ⑤完成效果如下: 2、WINDOW查找模式:一般适用多条件查询,可以返回多条查询记录。 ①打开在标准FORM---APPSTAND.fmb。将对象组中的QUERY_FIND拖至待开发的FORM中。 ②重命名第一个数据块、画布、窗口(QUERY_***都是刚才自动创建的)。USER GUID说可以重命名,但我没有重命名成功。也懒得去折腾一个命名的问题。^_^ ③打开QUERY_FIND画布,改写“新建”、“查找”两个按钮WHEN-BUTTON-PRESS之中的代码。 NEW按钮代码: --app_find.new('Your blockname here'); app_find.new('HEK_SALE_CUST_MANUAL'); FIND按钮代码: :parameter.G_query_find := 'TRUE'; --app_find.find('your blockname here'); app_find.find('HEK_SALE_CUST_MANUAL'); :parameter.G_query_find := 'FALSE'; ④设置QUERY_FIND数据块的“前一导航数据块”,也就是要实现询查功能的数据块。 ⑤修改QUERY_FIND数据块KEY-NXTBLK触发器代码 :parameter.G_query_find := 'TRUE'; --app_find.find('your blockname here'); app_find.find('HEK_SALE_CUST_MANUAL'); :parameter.G_query_find := 'FALSE'; ⑦修改QUERY_FIND窗口的标题及尺寸,并在QUERY_FIND画布上创建要查找的条件ITEM。 ⑧在要实现查询的数据块(如:HEK_SALE_CUST_MANUAL),创建PRE-QUERY触发器。 if :parameter.g_query_find = 'TRUE' then app_find.query_range(name_in('query_find.CUSTOMER_NUMBER'),name_in('query_find.CUSTOMER_NUMBER'),'HEK_SALE_CUST_MANUAL.CUST_CODE'); app_find.query_range(:query_find.CUST_DATE,:query_find.CUST_DATE,'HEK_SALE_CUST_MANUAL.TIME_ID'); :parameter.G_query_find := 'FALSE'; 注:app_find.query_range参数前两个是QUERY_FIND中的ITEM,后一个是查询块中的ITEM。 ⑨在要实现查询的数据块(如:HEK_SALE_CUST_MANUAL),再创建QUERY_FIND触发器。 --APP_FIND.QUERY_FIND('','',''); app_find.query_find('HEK_SALE_DEPT_MANUAL','QUERY_FIND','QUERY_FIND'); ⑩完成效果如下: 记录指示器切换标签页 Effect: 1、 在该数据块中手工增加一个ITEM 设置ITEM的属性:子类信息:设成DRILLDOWN_RECORD_INDICATOR,数据库项:否. 2.在新增的ITEM的WHEN-MOUSE-CLICK触发器加入 declare v_ begin v_order := : block_name1. --block_name表示要切换tab的数据块 if v_order is not null then go_block(' block_name1'); set_block_property('block_name1 ',DEFAULT_WHERE,'ORDER_NUMBER='||v_order); execute_ 3.这样就可以实现类似VB中的TAB切换了。由于ORACLE FORM没有专门的TAB函数,只能如此曲折实现。 EBS的条件查询方法 1、使用app_find.find IF (NAME_IN('PO_HEADERS.PO_HEADER_ID') IS NOT NULL) THEN :parameter.G_query_find := 'TRUE'; app_find.find('CUX_PO_HEADERS_ADD_MESSAGE'); go_block('CUX_PO_HEADERS_ADD_MESSAGE'); :parameter.G_query_find := 'FALSE'; ELSE FND_MESSAGE.DEBUG('请先保存订单头'); END IF; 在CUX_PO_HEADERS_ADD_MESSAGE的PRE-BLOCK中处理 copy(name_in('PO_HEADERS.PO_HEADER_ID'),'CUX_PO_HEADERS_ADD_MESSAGE.PO_HEADER_ID'); 2、使用Default_where属性处理 declare lv_default varchar2(2000); begin lv_default:='.....'; go_block('CUX_PO_HEADERS_ADD_MESSAGE'); set_block_property('CUX_PO_HEADERS_ADD_MESSAGE',DEFAULT_WHERE,‘PO_HEADER_ID=‘||lv_default); execute_ 3、使用app_find.query_range()来处理 注:app_find.query_range()必须有三个参数,也只能有三个参数 begin app_find.query_range(:find_date_from, :find_date_to, 'CUX_PO_HEADERS_ADD_MESSAGE.REATE_DATE'); :parameter.Q_query_find:='false'; 4、查询综合运用举例 前提准备工作,数据块:HKE_TEST 控制块:CONTROL 4.1.在数据块HKE_TEST的PRE-QUERY触发器设定查询条件 if :parameter.g_query_find = 'TRUE' then app_find.query_range(:CONTROL.CUST_F, :CONTROL.CUST_F ,'HKE_TEST.CUSTOMER_NUMBER'); :parameter.g_query_find := 'FALSE'; 4.2在查询按钮的WHEN-BUTTON-PRESSED :parameter.G_query_find := 'TRUE'; app_find.find('HEK_TEST'); :parameter.G_query_find := 'FALSE'; 自定义代码 例:实现某个项为必填项(当然自定义代码的功能还有很多)。 菜单:诊断=>自定义代码=>个性化 选择相应的触发器。如果是基于block的触发器,则要选择触发器对象(是哪一个块?)。 选择相应的项为必填。注:项的名称可通“检查”来查看。 作用于项的内容是什么,本例为必填。 保存完后,就可以实现“销售人员这一项为必填了”。 Fnd_Profile begin fnd_message.debug('user_id= ' || fnd_profile.value('user_id')); --取当前登录EBS用户ID fnd_message.debug('user_name= '||fnd_profile.value('USERNAME')); --取当前登录EBS用户名 fnd_message.debug('FND_Global.User_Name='|| FND_Global.User_Name); --取当前登录EBS用户名 fnd_message.set_string('GL_SET_OF_BKS_ID='||fnd_profile.value('GL_SET_OF_BKS_ID')); fnd_message. --取当前帐套 弹性域 弹性域分成键弹性域、说明性弹性域。这两种弹性域用途是不一样的。 关键性弹性域:在使用KEY弹性域的基表中,只保存ID。但可以通ID查询到相应的SEGMENT。在表结构中表现为***_ID、SEGMENT1等。 说明性弹性域:针对特定用户扩展输入特定信息的字段。在表结构中表现为attribute_category、attribute1字段等。 注册关键性弹性域 注册说明性弹性域 1.创建数据表。 注:使用说明性弹性域的数据表,必须含有ATTRIBUTE_CATEGORY及若干ATTRIBUTEN字段。 ATTRIBUTE_CATEGORY字段:指弹性域的CONTEXT字段。 ATTRIBUTEN字段:指实际使用的字段。 create table HEK_DISCOUNT_POLICY_H_NEW( POLICY_ID NUMBER, POLICY_NO VARCHAR2(30) not null, CUSTOMER_ID NUMBER, CUSTOMER_NUMBER NUMBER , CUSTOMER_NAME VARCHAR2(100), BENIFICIARY_ID NUMBER, BENIFICIARY_NUMBER NUMBER , BENIFICIARY_NAME VARCHAR2(100), RELATION_NUMBER NUMBER , RELATION_NAME VARCHAR2(100), PAYMENT_TYPE VARCHAR2(20), POLICY_PERIOD VARCHAR2(20) not null, ATTRIBUTE_CATEGORY VARCHAR2(150), ATTRIBUTE1 VARCHAR2(150), ATTRIBUTE2 VARCHAR2(150), ATTRIBUTE3 VARCHAR2(150), CREATED_BY NUMBER, CREATION_DATTE DATE, LAST_UPDATED_BY NUMBER, LAST_UPDATE_DATE DATE, LAST_UPDATE_LOGIN NUMBER) 2.注册弹性域表 begin ad_dd.register_table('HEK','HEK_DISCOUNT_POLICY_H_NEW','T',10,10,40); 3.注册弹性域表的列 begin ad_dd.register_column('HEK','HEK_DISCOUNT_POLICY_H_NEW','ATTRIBUTE_CATEGORY',1,'VARCHAR2',150,'N','N'); ad_dd.register_column('HEK','HEK_DISCOUNT_POLICY_H_NEW','ATTRIBUTE1',2,'VARCHAR2',150,'N','N'); ad_dd.register_column('HEK','HEK_DISCOUNT_POLICY_H_NEW','ATTRIBUTE2',3,'VARCHAR2',150,'N','N'); ad_dd.register_column('HEK','HEK_DISCOUNT_POLICY_H_NEW','ATTRIBUTE3',4,'VARCHAR2',150,'N','N'); 4.查看是否注册成功 select ft.table_id from FND_TABLES ft where ft.table_name='HEK_DISCOUNT_POLICY_H_NEW' select * from FND_COLUMNS fc where fc.table_id in (select ft.table_id from FND_TABLES ft where ft.table_name='HEK_DISCOUNT_POLICY_H_NEW') 5.注册弹性域列 操作路径:应用开发员=>弹性域=>说明性=>注册 点列按钮,选择注册相应的列 6. 注册弹性域段 点段按钮,输入提示文本 7.启用说明性弹性域 7.1先按将相应的FORM开发好,然后在FORM级的以下TRIGGER中加入 PRE-QUERY: FND_FLEX.EVENT('PRE-QUERY'); POST-QUERY: FND_FLEX.EVENT('POST-QUERY'); PRE-INSERT: FND_FLEX.EVENT('PRE-INSERT'); PRE-UPDATE : FND_FLEX.EVENT('PRE-UPDATE'); WHEN-VALIDATE-ITEM: FND_FLEX.EVENT('WHEN-VALIDATE-ITEM'); WHEN-VALIDATE-RECORD: FND_FLEX.EVENT('WHEN-VALIDATE-RECORD'); 7.2在PRE-FORM的TRIGGER中加入 fnd_descr_flex.define ( BLOCK=>'HEK_DISCOUNT_POLICY_H_NEW', FIELD=>'DESC_FLEX', APPL_SHORT_NAME=>'HEK', DESC_FLEX_NAME=>'HEK返利_订金'); 说明一下相应参数:BLOCK:指启用弹性域的数据块名 FIELD:指后面新增的ITEM APPL_SHORT_NAME:指相应模块的简称(系统管理员->应用->注册) DESC_FLEX_NAME:指注册弹性域时的名称 8.在要启用弹性域的数据块中增加一个ITEM。名称为:DESC_FLEX。 8.1 DESC_FLEX属性设置如下: 子类信息:TEXT_ITEM_DESC_FLEX 数据库项:否 画布:MAIN_C 8.2在DESC_FLEX项的以下trigger中加入: WHEN-VALIDATE-ITEM :FND_FLEX.EVENT('WHEN-VALIDATE-ITEM'); WHEN-NEW-ITEM-INSTANCE:FND_FLEX.EVENT('WHEN-NEW-ITEM-INSTANCE'); 9.完成效果: 条件控制说明性弹性域 说明:通过一个字段的值控制是否显示说明性弹性域。与普通的说明性弹性域类似。下面仅说明不同之处。 1. 注册弹性域列时,定义一个参考列。 点击参考字段按钮 DISCOUNT_TYPE是要启用弹性域数据表中的一个字段,即通过这个字段,来控制是否显示弹性域。 2.定义弹性域段 新增一条上下文值记录,例:年返。即当DISCOUNT_TYPE的值为“年返”时,才显示弹性域。 3.实现效果。 调用会计科目弹性域 1.首先在创建数据表时,添一个字段用来保存会计科目的ID。如:CODE_COMBINATION_ID 2.在FORM相应的数据块增加两个ITEM,用来显示科目NUMBER与DESCRITION。 例:GL_CODE_NUMBER、GL_CODE_DESC 注 : ENABLE_LIST_LAMP是TEMPLATE模板自带的,无须手工去定义。 将GL_CODE_NUMBER项的LOV设成“ENABLE_LIST_LAMP”,数据库项设为“否”。 将GL_CODE_NUMBER“从列表中验证”属性设成否。 3.在Form Level 的WHEN-NEW-FORM-INSTANCE Trigger初始化弹性域 FND_KEY_FLEX.DEFINE(BLOCK => 'BlockName ', FIELD => 'GL_CODE_NUMBER', ID => 'CODE_COMBINATION_ID', DESCRIPTION => 'GL_CODE_DESC', APPL_SHORT_NAME => 'SQLGL', CODE => 'GL#', NUM => 101, --STRUCTURE Number REQUIRED => 'N' ); 说明:APPL_SHORT_NAME查找:系统管理员=>应用=>注册 CODE查找:应用开发员=>键=>注册 NUM查 4.可以在GL_CODE_NUMBER项的WHEN-VALIDATE-ITEM触发器中,对所选择的科目进行核查。 IF : BlockName.CODE_COMBINATION_ID = -1 then fnd_message.debug('所选科目组合无效!'); raise form_trigger_ 5、完成效果: 键弹性域与说明性弹性域明显的区别。就是使用键弹性域的数据表只保留了ID。以会计科目弹性域为例,数据表只保存了ID(即CODE_COMBINATION_ID,这个字段是对应会计科目的ID)。GL_CODE_NUMBER、GL_CODE_DESC都只是控制块的ITEM,通过CODE_COMBINATION_ID来查询对应的科目。 EBS11i FormMVC模式 一个同事在的上提到,在做EBS开发时,要用MVC模式来满足不断在变化的业务需求。很有意思的话题,值得展开讨论。JAVA设计模式的书偶看了N次,但只会在JAVA应用,但从未想过在其他的4GL编程语言实现。以下是我的理解。 首先,按JAVA的那一套,MVC是指MODEL(模型层)、VIEW(表现层)、CONTROLLER(控制层)的缩写。编写为什么分层,这个是软件工程的需求。也就是说分层的目的是提高软件的可维护性,避免“动一牵百”的修改软件。 其次,按照这种软件分层原理,在JAVA中比较容易实现。Struts就是这类比较典型应用。模型层可以用实体类来实现,表现层可以用JSP+STRUTS标签实现,控制层可以action类实现。那么在ORACL FORMS如何实现分层呢?以下对号入座的想法。 MODEL用数据块来实现、VIEW用FORM界面实现、控制层呢?MVC中最为关键的是CONTROLLER。因为CONTROLLER实现业务逻辑与流程流转。并且按照设计模式的要求,CONTROLLER又被分成若干小层,如DAO层、SERVICES层等等,并且带来的“面向接口编程”之方法。ORACLE FORM实现业务逻辑与界面分离是通过程序单元来实现,控制层具体表现在ORACLE FORMS当中没有,只能通过繁琐的PL/SQL语句实现。 不知道这种理解对不对。这个话题是很有意思的,大家觉得呢?欢迎讨论哦。 EBS预警功能自定义开发 EBS预警分为事件预警和定期预警。预警功能非常强大,本例以订单录入后,以邮件的形式通知财务主管进行“订单登记”审核。 1、 定义预警。 操作路径:预警系统管理器=>预警=>定义 2、 编写SQL语句(注:SQL必须包含INTO、where rowid=:rowid) select ORDER_NUMBER into &order_number from OE_ORDER_HEADERS_all head WHERE rowid = :ROWID 3、 点击上图中的“活动按钮”。 4、 点击上图中的“活动详细资料”按钮。 5、 定义活动集。 6、 预警安装 点击“预警详细资料”按钮。 7、 完成效果如下: EBS自定义邮件通知 前面已经介绍过了EBS预警的功能,事实上Oracle数据库本身就有提供UTL_SIMPLE(ORACLE10g以后变成UTL_MAIL)包来实现邮件发送的功能,利用这个包可以开发出更灵活东西来。首先要安装utlsmtp.sql、utltcp.sql这两个包。 ①发送带有URL邮件代码 declare p_sender varchar2(30) := 'chongdong_'; p_recipient varchar2(30) := 'jian_'; p_subject varchar2(50) := '使用PL/SQL发送邮件'; p_body long := '这是邮件正文内容啦!我又来啦!!!进行ORACLE ERP'; mail_conn utl_smtp. mail_host varchar2(15) := ''; user_name varchar2(156) := 'chongdong_'; user_pwd varchar2(156) := '***'; begin --创建一个TCP MAIL连接 mail_conn := utl_smtp.open_connection(mail_host, 25); --ehlo与helo的区别:是否对邮件主机进行登陆认证 --utl_smtp.helo(main_conn,mail_host); utl_smtp.ehlo(mail_conn, mail_host); --登陆认证语句 mand(mail_conn, 'AUTH LOGIN'); --对用户及密码进行加密 mand(mail_conn, demo_base64.encode(utl_raw.cast_to_raw(user_name))); mand(mail_conn, demo_base64.encode(utl_raw.cast_to_raw(user_pwd))); --指定发件人 utl_smtp.mail(mail_conn, p_sender); --指定收件人 utl_smtp.rcpt(mail_conn, p_recipient); --开始写邮件内容 utl_smtp.open_data(mail_conn); --指定显示的发件人,注意这边的显示的发件人可以上面指定发件人不同 --这实际上是SMTP协议的缺陷,也是造成垃圾邮件主要原因 utl_smtp.write_data(mail_conn, 'From:' || p_sender || utl_tcp.CRLF); utl_smtp.write_data(mail_conn, 'To:' || p_recipient || utl_tcp.crlf); --邮件主题:中文必须进行编码转换,否则会乱码 utl_smtp.write_raw_data(mail_conn, utl_raw.cast_to_raw(convert('Subject:' || p_subject || utl_tcp.CRLF, 'ZHS16GBK'))); --设置邮件内容模式为HTML,也可以直接设置文本Content-Type:text/plain utl_smtp.write_raw_data(mail_conn, utl_raw.cast_to_raw(convert('Content-Type:text/ charset=GBK' || utl_tcp.CRLF, 'ZHS16GBK'))); utl_smtp.write_data(mail_conn, utl_tcp.CRLF); --邮件正文 utl_smtp.write_raw_data(mail_conn, utl_raw.cast_to_raw(convert(p_body, 'ZHS16GBK'))); --关闭连接 utl_smtp.close_data(mail_conn); utl_smtp.quit(mail_conn); exception when utl_smtp.transient_error or utl_smtp.permanent_error then utl_smtp.quit(mail_conn); raise_application_error(-20000, sqlerrm); when others then raise_application_error(-20001, 'The send mail was error ' || sqlerrm); ②发送带有附件的邮件 declare p_sender varchar2(30) := ''; p_recipient varchar2(30) := 'chongdong_'; p_subject varchar2(50) := 'PL/SQL发邮件、带链接、带附件'; p_body long := 'PL/SQL发邮件、带链接带附件 这是邮件正文内容啦!这是带附件的啦!! 进行ORACLE ERP'; mail_conn utl_smtp. mail_host varchar2(15) := ''; user_name varchar2(156) := ''; user_pwd varchar2(156) := 'metalink'; --发附件要用到的变量 L_FIL BFILE; L_FILE_LEN NUMBER; L_MODULO NUMBER; L_PIECES NUMBER; L_FILE_HANDLE UTL_FILE.FILE_TYPE; L_AMT BINARY_INTEGER:=672*3;/* e 2016 */ L_FILEPOS PLS_INTEGER:=1;/* pointer for the file */ L_CHUNKS NUMBER; L_BUF RAW(2100); L_DATA RAW(2100); L_MAX_LINE_WIDTH NUMBER:=54; L_LINE VARCHAR2(1000); L_MESG VARCHAR2(32767); BOUNDARY CONSTANT VARCHAR2(256) := '-----7D81B75CCC90DCBD'; FIRST_BOUNDARY CONSTANT VARCHAR2(256) := '--' || BOUNDARY || utl_tcp.CRLF; LAST_BOUNDARY CONSTANT VARCHAR2(256) := '--' || BOUNDARY || '--' || utl_tcp.CRLF; --发送带有附件邮件,MIME必须设为multipart/mixed MULTIPART_MIME_TYPE CONSTANT VARCHAR2(256) := 'multipart/ boundary="'|| BOUNDARY || '"'; begin --创建一个TCP MAIL连接 mail_conn := utl_smtp.open_connection(mail_host, 25); --ehlo与helo的区别:是否对邮件主机进行登陆认证 - -utl_smtp.helo(main_conn,mail_host); utl_smtp.ehlo(mail_conn, mail_host); --登陆认证语句 mand(mail_conn, 'AUTH LOGIN'); --对用户及密码进行加密 mand(mail_conn, demo_base64.encode(utl_raw.cast_to_raw(user_name))); mand(mail_conn, demo_base64.encode(utl_raw.cast_to_raw(user_pwd))); --指定发件人 utl_smtp.mail(mail_conn, p_sender); --指定收件人 utl_smtp.rcpt(mail_conn, p_recipient); --开始写邮件内容 utl_smtp.open_data(mail_conn); utl_smtp.write_data(mail_conn, 'From:' || p_sender || utl_tcp.CRLF); utl_smtp.write_data(mail_conn, 'To:' || p_recipient || utl_tcp.crlf); utl_smtp.write_data(mail_conn, 'Subject: ' || p_subject || utl_tcp.crlf); --中文编码转换 utl_smtp.write_raw_data(mail_conn,utl_raw.cast_to_raw(convert('Subject:' ||p_subject ||utl_tcp.CRLF,'ZHS16GBK'))); utl_smtp.write_raw_data(mail_conn,utl_raw.cast_to_raw(convert('Content-Type:'||MULTIPART_MIME_TYPE||utl_tcp.CRLF,'ZHS16GBK'))); --utl_tcp.CRLF 数据流行尾符 utl_smtp.write_data(mail_conn, utl_tcp.CRLF); - -邮件正文 utl_smtp.write_data(mail_CONN, FIRST_BOUNDARY); utl_smtp.write_raw_data(mail_conn,utl_raw.cast_to_raw(convert('Content-Type:text/charset=GB2312' ||utl_tcp.CRLF, 'ZHS16GBK'))); utl_smtp.write_data(mail_conn, utl_tcp.CRLF); utl_smtp.write_raw_data(mail_conn,utl_raw.cast_to_raw(convert(p_body, 'ZHS16GBK'))); utl_smtp.write_data(mail_conn, utl_tcp.CRLF); --附件格式 utl_smtp.write_data(mail_CONN, FIRST_BOUNDARY); utl_smtp.write_raw_data(mail_conn,utl_raw.cast_to_raw(convert('Content-Type:text/charset=GB2312' ||utl_tcp.CRLF, 'ZHS16GBK'))); utl_smtp.WRITE_RAW_DATA(mail_conn, UTL_RAW.CAST_TO_RAW(CONVERT('Content-Disposition' || ':' ||'filename="'||'qq.xls"' || utl_tcp.CRLF, 'ZHS16GBK'))); utl_smtp.write_raw_data(mail_conn,utl_raw.cast_to_raw(convert('Content-Transfer-Encoding:base64'||utl_tcp.CRLF,'ZHS16GBK'))); utl_smtp.write_data(mail_CONN, UTL_TCP.CRLF); --附件二进制流 BEGIN --把附件分成多份,这样可以发送超过32K的附件 L_FILEPOS := 1; --CREATE OR REPLACE DIRECTORY U_FIEL AS '/data/book/' --qq.xls附件放在ORACLE/data/book/下,注意大写 L_FIL := BFILENAME('U_FIEL', 'qq.xls'); L_FILE_LEN := DBMS_LOB.GETLENGTH(L_FIL); L_MODULO := MOD(L_FILE_LEN, L_AMT); L_PIECES := TRUNC(L_FILE_LEN / L_AMT); IF (L_MODULO
0) THEN L_PIECES := L_PIECES + 1; END IF; DBMS_LOB.FILEOPEN(L_FIL, DBMS_LOB.FILE_READONLY); DBMS_LOB.READ(L_FIL, L_AMT, L_FILEPOS, L_BUF); L_DATA := NULL; FOR I IN 1 .. L_PIECES LOOP L_FILEPOS := I * L_AMT + 1; L_FILE_LEN := L_FILE_LEN - L_AMT; L_DATA := UTL_RAW.CONCAT(L_DATA, L_BUF); L_CHUNKS := TRUNC(UTL_RAW.LENGTH(L_DATA) / L_MAX_LINE_WIDTH); IF (I
L_PIECES) THEN L_CHUNKS := L_CHUNKS - 1; END IF; utl_smtp.write_raw_data(MAIL_CONN, UTL_ENCODE.BASE64_ENCODE(L_DATA)); L_DATA := NULL; IF (L_FILE_LEN
0) THEN L_AMT := L_FILE_LEN; END IF; DBMS_LOB.READ(L_FIL, L_AMT, L_FILEPOS, L_BUF); END LOOP; DBMS_LOB.FILECLOSE(L_FIL); EXCEPTION WHEN OTHERS THEN DBMS_LOB.FILECLOSE(L_FIL); utl_smtp.WRITE_DATA(mail_CONN, UTL_TCP.CRLF); RAISE; END; --结束处理二进制附件 --关闭连接 utl_smtp.close_data(mail_conn); utl_smtp.quit(mail_conn); exception when utl_smtp.transient_error or utl_smtp.permanent_error then utl_smtp.quit(mail_conn); raise_application_error(-20000, sqlerrm); when others then utl_smtp.quit(mail_conn); DBMS_OUTPUT.put_line(sqlerrm); EBS配置文件(Profile)常用设置 IE打不开EBS ①症状:一直停留在EBS弹出式窗体,显示正在加载FORMS。 解决:安装SUN JDK1.4,并将JVM.DLL替换掉X:Program FilesOracleJInitiator 1.3.1.21binhotspot ②症状:无法查看工作流状态图(view datagram) 解决:安装微软的虚拟机msjavx86.exe。 获取EBS的查询语句 1.帮助=>诊断=>检查 2.在块中输入SYSTEM、在字段中输入LAST_QUERY,就可以得到查询的SQL语句。
阅读(10267) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。