PeoplesoftHCM项目AE程序技术总结_第1页
PeoplesoftHCM项目AE程序技术总结_第2页
PeoplesoftHCM项目AE程序技术总结_第3页
PeoplesoftHCM项目AE程序技术总结_第4页
PeoplesoftHCM项目AE程序技术总结_第5页
已阅读5页,还剩53页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

在Peoplesoft系统里AE(ApplicationEngine)程序是比较核心的技术,本文将结合我在上海日立上项目的情况,对AE程序进行总结。首先从AE程序概要说起,包含它的概念以及组成部分,peoplecode是编写AE程序必须要熟练掌握的语言,本文将会结合一个页面开发的实例来做一介绍。然后会来讲述AE程序的运行方式以及如何来调试和管理AE程序,最后会对一个具体AE开发实例进行介绍并且对遇到问题进行总结。1.对AE程序的理解AE程序是PeopleTools的组成部分之一,用于开发、测试和运行对PeopleSoft数据库进行的后台SQL处理程序,主要负责与数据库进行的大量复杂的SQL交互任务,如币种换算、更新员工工龄工资等。事实上AE程序并不能产生,解析和理解SQL语句,它只是去执行我们提供的SQL语句。它的开发是在后台开发工具ApplicationDesigner里进行的。在应用程序升级时也会用到AE程序。AE程序存储在PeopleSoft数据库内,它不像Crystal报表定义、SQR程序等储存在文件系统内。一个AE程序可以同时运行多个实例。AE程序实际上是一组SQL语句,peoplecode代码和处理逻辑的集合。它的特点便是可以在后台进行批处理,适合于大量数据的操作,具有着严格的程序结构,并且使用Meta-SQL和标准SQL结合的方式进行编程。当有数据必须被处理而又不需要通过用户时,这时我们就可以用AE程序进行批处理。它包含了两个组件,一个是设计工具,用来定义我们的AE程序,另外一个则是运行环境,来运行和检测我们的AE程序。2.AE程序的组成部分下面我们来在开发工具里看看一个AE程序的结构:通过上图,我们可以很形象的看到,一个AE程序是由一个或者多个Section组成的,一个Section又是由一个或者多个Step组成的,而一个Step又是由一个或多个Action组成的。下面我们将对每一个部分进行简要说明:a.Section它包含一个或者多个steps,它就相当于SQR报表程序里面的procedure,任何AE程序都应该至少包含一个名字为“MAIN”的Section,程序总是从它开始执行的。从上图可以看到。Section是可以被本程序的其它Section或者被其它程序来调用的。下面来对它的主要属性予以说明:Market:地区,例如Global或其他如AUS、BEL、BRA。可以将鼠标点击在其上,然后就会在该项上出现下拉列表供选择,其它属性的选择方法类似。如下图:Platform:数据库平台,如Default、Oracle、DB2等。EffectiveStatus:生效状态。用于临时性停用某个Section。SectionType:普通的数据库操作,或是对数据库的关键性升级。AutoCommit:控制下属各Step的默认Commit方式。Access:只有设为Public的Section才能被其他Program调用。需要注意:点击上图中的文件夹图标,当它处于打开状态时,才可以看到Section的属性,当然Step和Action也是一样的方法来看属性的。在每一个Definition前面都有一个小加号或者减号,这是用来展开或者隐藏该项内容的。b.Step它是提交给AE程序的一个最小的工作单位。可以用Step来执行peoplecode,SQL语句,或者来调用其它的Section等。这些SQL、peoplecode是被包含在一个Step里来作为一个Action进行执行的。Step的属性说明:CommitAfter:本Step的Commit方式(Default,AfterStep,Later)。Frequency:下属Action循环多少次后进行Commit。OnError:下属Action运行出错后的反应方式(Abort、Ingore、Supress)。Active:用于临时性停用某个Step。需要注意:如果要给本Section添加新的Step,并且要把它放在该Section里的第一项时,那么鼠标应该点击在MAIN处进行操作,如下:如果想把它放在某个Step的后面,那么鼠标就放在该Step上进行操作即可。另外Step的名字是不能够超过8个字符的。当不想要自己建立的Step的时候,鼠标点击在上面,然后右键删除即可,如下:c.Action一共有八种不同的Action,分别执行不同类型的任务。这八种Action又可以分为两大类。流程控制型Action:DOWHEN:如果有返回行,就执行一次。DOWHILE:只要有返回行,就一直执行下去。DOSELECT:遍历返回的各行,每行执行一次。DOUNTIL:一直执行到有返回行。操作型Action:PeopleCode:执行一段PeopleCode。…SQL:执行一段SQL代码,如删除某些行、插入某些行。CallSection:调用另一个SectionLogMessage:向MessageLog写信息(如错误信息、程序运行状态信息等)需要注意1:SQLAction和CallSectionAction不能共存于同一Step中,故同一个Step最多有7个Action。假如在一个Step里已经包含了一个SQLAction,那么当新添加一个Action时,在下拉列表里是找不到CallSectionAction的。如下:需要注意2:Action有着严格的执行顺序和嵌套关系,可以从下图看到。另外,可以用DOUNTIL来终止对应的DOWHILE。开发AE程序,内部逻辑由peoplecode来控制,因此我们需要对peoplecode熟练的运用。下面将结合一个页面开发的实例,来说明在页面开发中如何使用peoplecode的,在本项目里虽然涉及到的页面开发不多,但是它也是一项很重要的技术,需要掌握,因此在本节里除了会说明如何用peoplecode来实现开发实例的要求,还会对一些页面开发方面的问题进行说明。1.开发实例说明该页面开发实例的说明:开发三个页面,当点击其component进入页面之后,只显示两个页面,但是在页面上有链接按钮,点击相应链接,则可以跳转到第三个页面,同时还可以从第三个页面跳转到前两个页面,并且这些页面还具有包含历史记录和更正历史记录的功能。2.对开发实例之分析在分析之前,我们假定已经掌握如何在开发工具里定义field,record,page等,并且掌握将页面挂在某个菜单下,具体挂在菜单下的方法可以参考我写的“SQR报表技术总结”一文。下面我们就针对上面的实例进行具体分析:a.首先我们来分析包含历史记录和更正历史记录的问题在peoplesoft系统里我们会看到有些页面的底部会显示包含历史记录和更正历史记录,如下:在刚开始一点击compnent进入页面的时候,用户就可以勾选是以什么方式进入页面,如下图。更正历史记录则可以更新页面里的数据,而包含历史记录则可以将页面里的其它历史记录也显示出来。而有的页面却没有,如下:实际上是否有这两项内容是由具体的业务逻辑来规定的,那么我们就从技术的角度来看看这是怎么设定的。首先我们打开具有访问该页面权利的权限列表,查看是否是权限列表里面限定了不能包含这两项内容:可以看到在“操作”栏里,的确有对包含历史记录和更正历史记录的限定,对应到操作里就是后两项“更新/全部显示”以及“更正”,但是也可以看到这两项是灰色的,没办法勾选。看来问题不是出在权限列表里,而是有更底层的原因。事实上这个更底层的原因就出在了component里,打开该页面所属的component,我们来看看它的属性:可以看到这个属性里面在Actions里的确是有对包含历史记录和更正历史记录的限定,可以看到后两项是没有勾选的,而这里是否勾选就是直接来决定权限列表里面相应的操作是否是可选的。正因为这里的后两项是没有选中的,所以才会在相应的权限列表里看到对应的项是灰色的。那么我们就将其勾选上,看看会有什么样的效果:这样设置了以后,再次打开权限列表,后两项依然是灰色的,那么问题到底是出在哪里了呢?问题就出在了虽然我们已经将component的属性已经更改了,但是这个更改是在上次注册该component之后进行的。也就是说对component的属性所做的这种改动只有经过注册后才是起效果的。在component属性的Action里哪些项选中了,直接影响注册的时候哪些操作是可以被选中的,如果我们将component属性的Action里后两项没有选中,那么注册的时候就会看到如下图所示的界面,相应的操作的后两项也是灰色的:那么我们就component属性更改之后重新进行注册,这个时候再次打开相应的权限列表:可以看到操作里面的全部项都成了可选的了。需要注意1:我们在开发页面的时候,有可能会经常查看给某个组件赋予了什么权限,那么怎么样能够快速的知道该组件都赋给了哪些权限列表呢?那么我们就需要寻找系统里面组件和权限列表之间的关系,以及在系统里面是通过哪些表来存储这些信息的,我们用如下的SQL语句就可以快速查到某个组件的的权限列表:SELECTDISTINCTauth.classid,a.menuname,d.pnlgrpname,b.itemlabel,rtrim((casewhenbitand(authorizedactions,1)>0then'A,'END||casewhenbitand(authorizedactions,2)>0then'U,'END||casewhenbitand(authorizedactions,4)>0then'U+,'END||casewhenbitand(authorizedactions,8)>0then'C,'END||casewhendisplayonly=1then'V,'END),',')AuthActionFROMpsauthitemauth,psmenudefna,psmenuitemb,pspnlgroupc,pspnlgrpdefndWHEREa.menuname=b.menunameANDb.pnlgrpname=c.pnlgrpnameANDd.pnlgrpname=c.pnlgrpnameANDauth.menuname=a.menunameANDauth.barname=b.barnameANDauth.baritemname=b.itemnameANDauth.pnlitemname=c.itemnameANDb.itemnameLIKE'HE_JOB_PAGE_CPT'ORDERBYd.pnlgrpname黑斜体字样部分是我们根据自己的具体需要,来进行替换的,它表示的是我们将组件注册在菜单下的该菜单项的名字,像上面我们就可以在开发工具里找到这个菜单项的名字,如下:有时候我们不仅仅需要查看某个组件和权限列表之间的关系,甚至还会查找权限列表和角色之间的关系,那么它们的关系可以通过下面的SQL来实现的:SELECTDISTINCTd.pnlgrpname,e.rolename,f.descr,auth.classid,rtrim((casewhenbitand(authorizedactions,1)>0then'A,'END||casewhenbitand(authorizedactions,2)>0then'U,'END||casewhenbitand(authorizedactions,4)>0then'U+,'END||casewhenbitand(authorizedactions,8)>0then'C,'END||casewhendisplayonly=1then'V,'END),',')AuthAction,g.classdefndescFROMpsauthitemauth,psmenudefna,psmenuitemb,pspnlgroupc,pspnlgrpdefnd,psroleclasse,psroledefnf,psclassdefngWHEREa.menuname=b.menunameANDb.pnlgrpname=c.pnlgrpnameANDd.pnlgrpname=c.pnlgrpnameANDauth.menuname=a.menunameANDauth.barname=b.barnameANDauth.baritemname=b.itemnameANDauth.pnlitemname=c.itemnameANDauth.classid=e.classidANDe.rolename=f.rolenameANDauth.classid=g.classidANDauth.classid='SHEC_COMPENSATION_MANAGEMENT'ORDERBYd.pnlgrpname,e.rolename,auth.classid黑斜体字样部分是我们需要查找的权限列表的名字,可以进行替换。需要注意2:通过上面对包含历史记录和更正历史记录的研究,那么会看到对于某些页面具有什么样的操作的权限,例如是否可更改等,我们可以在一开始注册component的时候进行限定,这里的限定直接就决定了我们在权限列表里面可以对哪些操作进行权限控制。也就是说component是最低层原因,在此基础上我们再来通过权限列表进行控制。那么我们来看看用权限列表进行控制的操作:进入下面的页面后,点到“页面”这个页面:然后在相应的菜单下,点击编辑组件:然后点击相应组件下面的编辑页面:此时就可以对相应的组件的操作进行权限控制了。如果我们把后两项不进行勾选,那么点击相应的组件的时候,一开始就不会出现对“包含历史记录”和“更正历史记录”的选择字样,可以将它跟在权限列表里对操作的后两项勾选了的页面进行比较,如下:需要注意3:从上图我们可以看到打开页面时有一个搜索依据,那么这个搜索依据是怎么来设置的呢?我们可以在组件的属性里面查找得到下面红圈里面的属性,是对搜索记录的指定。限定完上面的记录之后,我们还需要在记录的字段属性里面进行设置:这样设置之后就会在打开该component的时候出现搜索依据里面需要显示的字段。需要注意4:在开发页面的过程中,可能会在WEB上遇到下面的错误:提示数据完整性错误。分析这个错误的原因:是因为我在后台的开发工具里面修改了此页面上的一些东西,但是我之前在这个WEB页面进行了一系列操作之后,依然停留在此,当在后台修改完了之后再次继续在刚才停留的这个页面上操作,就会提示这样的错误。解决办法是:重新打开该页面。b.下面我们再次回到开发实例说明,对其进行分析。我们可以知道前两个页面是可以注册在一个组件下的,那么第三个页面是否也要注册在这个组件下呢。回答是肯定的。按照常规将三个页面注册在同一个组件下面,点击进入之后,三个页面会同时显示出来。但是我们需要的是点击进入该组件之后一开始只能显示前两个页面,通过点击链接按钮才能够跳转到第三个页面,这又是怎么来控制的呢?这就是peoplecode的功能所在了。通过编写一系列的peoplecode代码,并且确保其写在合适的位置,那么就可以实现我们想要的功能。那么接下来我们就将包含这三个页面的组件注册在某个菜单下。c.现在我们再来讨论子页面的问题。为什么要建一个子页面呢?因为在页面上需要有链接按钮来实现页面之间的相互跳转,如果给三个页面分别建立跳转按钮,那么会发现这样做很麻烦,并且还牵扯到peoplecode的编写问题,那么如果我们把链接按钮做在一个子页面上,在这三个页面上分别插入这个子页面即可,peoplecode编写起来也很方便。现在我们就来建立一个record,目的是让该record里的两个字段分别充当两个链接按钮,并且将它们放在子页面上,如下:需要注意1:建立子页面的时候,点击新建,选择的是Page,那么这个子页面体现在哪里呢?事实上这是通过页面的属性来设置的,如下:对于链接按钮的实现,是在field的属性里设置的,如下:需要注意2:我们会发现在record里面,有些field的名字是以黑体显示的,而有些字段却没有,这是为什么呢?原因是有些field里编写了peoplecode代码,那么就会显示黑体。d.对着上图来说明这个子页面上两个链接按钮的用意,点击“职务数据”按钮另其可以跳转到前两个页面:HE_JOB_TEST_PG和HE_POSITION_PG,并且该按钮当即失效,不能点击;点击“员工数据”按钮则可以跳转到HE_LABOR_TEST_PG页面,并且“员工数据”按钮当即失效,“职务数据”按钮又生效。根据这样的需求我们来在两个field里编写peoplecode。在“职务数据”(JOB_DATA_BTN1)里我们编写下面的代码:If%Component=Component.HE_JOB_PAGE_CPTThenPage.HE_JOB_TEST_PG.Visible=True;Page.HE_POSITION_PG.Visible=True;TransferPanel(Panel.HE_JOB_TEST_PG);End-If;在“员工数据”(JOB_DATA_BTN2)里我们编写下面的代码:If%Component=Component.HE_JOB_PAGE_CPTThenPage.HE_LABOR_TEST_PG.Visible=True;TransferPanel(Panel.HE_LABOR_TEST_PG);End-If;需要注意1:在上面我们已经看到编写的peoplecode了,事实上在上例中除了需要考虑在哪个field里面编写代码之外,我们还需要考虑另外一个方面,即这个代码应该写在什么样的事件里呢?像上面的例子,实际上我们是把它写在FieldChange事件里的。由此我们引开了一个话题,peoplecode都可以编写在哪些Defidition里面?每种Defidition里都可以有什么样的事件?那么在页面上做了某些操作之后,在后台会引发哪些事件,他们之间触发顺序是什么?针对上面的问题我们来进行分析:在RecordField、ComponentRcordField、ComponentRecord、Component、page、Menu等对象里都可以来编写peoplecode的。Fields是独立定义的,是其他对象的基础,它的属性在使用它的所有Record中被共享。独立的Field是没有事件的;Recordfields是包含在Record中被定义的,只在被定义的Record中有效;Componentrecordfields是被某个component使用的Recordfields,有自己独特的事件和PeopleCode程序。我们通过一个表格来说明各个对象里的都包含了什么样的事件:RecordFieldComponentRcordFieldComponentRecordComponentpageMenuFieldChangeFieldDefaultFieldEditFieldFormulaPrePopupRowDeleteRowInitRowInsertRowSelectSaveEditSavePostChgSavePreChgSearchInitSearchSaveWorkflowFieldChangeFieldDefaultFieldEditPrePopupRowDeleteRowInitRowInsertRowSelectSaveEditSavePostChgSavePreChgSearchInitSearchSavePostBuildPreBuildSavePostChgSavePreChgWorkflowActivateItemSelected现在我们来举一个例子说明事件之间的触发顺序,当用户改变了一个Field之后,都会触发哪些事件呢?顺序是什么?如下:Record.recordA.fielda.FieldEdit->Component.recordA.fielda.FieldEdit->Record.recordB.fieldb.FieldEdit->Component.recordB.fieldb.FieldEdit->Record.recordA.fielda.FieldChange->Component.recordA.fielda.FieldChange->Record.recordB.fieldb.FieldChange->Component.recordB.fieldb.FieldChange当然不同的操作会触发不同的事件顺序。需要注意2:像其它程序一样,peoplecode也可以写注释的,那么一共有三种加注释的方式:第一种:使用/**/第二种:使用REM,以分号作为注释的结尾。第三种:使用<**>e.我们再来分析应该在页面上编写的peoplecode代码,当我们点击了组件进入页面之后,希望页面上有哪些设置呢?根据实例要求已经很明了了,当是前两个页面时,我们希望第二个链接按钮可点击,第三个页面隐藏,当是第三个页面时,我们希望前两个页面隐藏,第一个链接按钮可点击进入前两个页面。而三个页面都需要这样的代码,那么我们是否可以把它编写为一个通用的代码,从而在三个页面里面调用即可,回答是可以的。在peoplecode里这是怎么实现的呢?事实上我们可以再建一个Record,在该Record的Field的FieldFormula事件里面存放这个通用的函数,令这个函数的参数为页面。建立的Record如下:在其Field的FieldFormula事件里编写如下的函数:Functionshec_JobNavigation(&Page);If(%Component=Component.HE_JOB_PAGE_CPT)ThenEvaluate&PageWhen=Page.HE_JOB_TEST_PGWhen=Page.HE_POSITION_PGGray(SHEC_DERIVED_HR.JOB_DATA_BTN1);UnGray(SHEC_DERIVED_HR.JOB_DATA_BTN2);Page.HE_LABOR_TEST_PG.Visible=False;Break;When=Page.HE_LABOR_TEST_PGUnGray(SHEC_DERIVED_HR.JOB_DATA_BTN1);Gray(SHEC_DERIVED_HR.JOB_DATA_BTN2);Page.HE_JOB_TEST_PG.Visible=False;Page.HE_POSITION_PG.Visible=False;Break;End-Evaluate;End-If;End-Function;做了上面之后,我们就需要在三个页面上分别调用这个函数了,调用的代码如下:DeclareFunctionshec_JobNavigationPeopleCodeFUNCLIB_HR_SHEC.JOB_DATAFieldFormula;shec_JobNavigation(%Page);需要注意1:在上面我们已经用到了函数,那么下面我们就来讨论下peoplecode里的函数。在peoplecode里,定义函数的语法如下:Functionname[(paramlist)][Returnsdata_type][statements]End-functionpeoplecode里都可以有哪些函数呢?Build-in函数是最常用的一种,它不用声明,直接调用,例如GetRow、Month等;有一种是在peoplesoft程序中声明定义的函数;有一种是外部函数;那么另外一种则是我们上面的开发实例中用到的。将该函数存储在某个Record上,这种情况我们做一个说明。首先Record的类型我们并不需要定义为table,定义为Derived/Work即可,如下:因为其上的代码是程序运行中动态调用的,其次Record是有一定的命名规范的,它必须以FUNCLIB作为该Record名字的开头,最后在这里定义了函数之后,我们在需要调用的地方还需要声明,那么声明的语法如下:DeclareFunctionfunction_namePeopleCoderecord_name.field_nameevent_type我们也可以在上面的开发实例中感受到这种用法。需要注意2:在peoplesoft里有一些名词是可以相互替换的,举例说明:%panelgroup=%component;%panel=%page这是因为ORACLE将peoplesoft买入之后,在一些专用名词上做了调整,像上面的例子,那么我们就建议使用%component和%page,因为这样的描述更为准确和贴切。需要注意3:从上面的例子中实际上我们已经能够感受得到PeopleCode的一些逻辑控制语句,并且在PeopleCode里一般是以分号作为一句的结尾。一般的条件语句语法如下:IFconditionThen[statement_list_1][Else[statement_list_2]]End-ifEvaluateleft_termWhen[relop_1]right_term_1[statement_list]...When[relop_n]right_term_n[statement_list][When-other[statement_list]]End-evaluate;Forcount=expression1toexpression2[Stepi];statement_listEnd-for;一般的循环语句语法如下:Repeatstatement_list*Untillogical_expression;Whilelogical_expressionstatement_listEnd-while需要注意4:在PeopleCode里可以调用一些系统的变量,例如:%Date、%Currency、%EmployeeId等。需要注意5:当我们在编辑器里编写peoplecode时,如果在语法上有问题,那么在保存时是通不过的,例如:上面的错误是因为Page.HE_JOB_TEST_PG=False这句话的语法有问题,而正确的赋值语句应该是Page.HE_JOB_TEST_PG.Visible=False;又如:这个错误的原因是我们所指定的函数实际上根本就不存在。f.那么现在我们已经将要实现的功能基本完成,我们再来看看系统里某个组件下的页面标签:可以看到这些页面上都有快捷键,通过这些快捷键可以实现这些页面之间的切换,按ALT键外加该标签页上的字母,然后回车就可以实现相应页面的切换了。那么这项功能是如何来设置的呢?我们继续回到component上,打开相应的component:可以看到这项功能就是在上面的红圈里设置的,只需要在该项标签名字的后面按照(&..)格式来写就可以实现上面的功能。我们也用这样的方法来对自己的组件下的页面进行这样快捷键的设置。g.下面我们就对完成的实例的要求进行测试,验证是否符合。可以看到点击该组件之后,“职务数据”的链接按钮变灰,展示的是前两个页面,我们再来点击“员工数据”按钮,如下:可以看到“员工数据”按钮变灰,“职务数据”的链接按钮恢复可以点击状态。同时可以看到页面的标签上设置有快捷键。并且在页面的底部也包含了包含历史记录和更正历史记录。总结:通过上面的实例,我们可以看到页面开发中是离不开peoplecode的,因此熟练运用peoplecode是必需的。那么当我们需要完成一项页面开发中的功能时,实际上最好的办法就是参考系统标准,看看他们都是如何来设置才实现的,往往我们会从其中收获很多的制作技巧,例如上例中为何设置子页面,为何将函数那样编写和调用,我们都是可以从系统的标准里得到参考的。对于peoplecode,那么就需要多编写,才能够熟练运用。1.Meta-SQLAE程序使用Meta-SQL和标准SQL结合的方式来编写SQL语句。Meta-SQL是PeopleSoft专用的一种用来构造标准SQL语句的“宏SQL语句”。它的好处就是简化SQL语句的编写并且可以跨数据库平台。数据库平台有很多不同的语法规则,特别是针对于日期,时间,和其它的数字计算。AE程序支持我们可以根据这些不同的规则来使用peoplesoftMeta-SQL。Meta-SQL是一组事先定义好的Meta-strings,这些事先定义好的Meta-SQL可以代替关系数据库管理系统里的专门的SQL语法。而且peoplesoftMeta-SQL可以动态的产生一些SQL代码。我们来举个例子:例如:让两个表的关键字段进行关联可以用代码%Join(COMMON_KEYS,PSAESECTDEFNABC,PSAESTEPDEFNXYZ)来写,而实际上执行的SQL是:ABC.AE_APPLID=XYZ.AE_APPLIDANDABC.AE_SECTION=XYZ.AE_SECTIONANDABC.DBTYPE=XYZ.DBTYPEANDABC.EFFDT=XYZ.EFFDT2.AE中常用的Meta-SQL语句在AE程序里有一些常用的Meta-SQL。与StateRecord交互的有:%bind、%select进行数据操纵的有:%ExecuteEdits、%SQL、%Table、%UpdateStats等对于日期/时间的处理如:%CurrentDateIn,%CurrentDateOut、%CurrentTimeIn,%CurrentTimeOut等如下是一个在AE程序里面使用Meta-SQL的典型例子:1.AE程序运行图解从上图中我们可以很形象的看到AE程序运行的完整图景。2.运行方式进程调度器首先我们要确保后台的AE程序已经编写好。其次,我们可以给AE程序制作一个传递参数的页面,并将其挂在相应的菜单下。做这些类似于给SQR报表制作传递参数的页面以及如何来挂页面。这里不再做说明,可以参考我写的“SQR报表技术总结”一文。同时通过这个页面怎么来运行该AE程序和运行SQR的方法类似,在这里也不再做说明。上图就是一个为运行AE程序制作的传递运行参数的页面的例子。最后我们来说明如何定义AE程序。这和定义SQR报表程序也是类似的。进入如下页面:选择添加一个新值,然后进程类型应该选择“ApplicationEngine”,最后输入与后台开发的AE程序相同的名字。通过这种方式来运行AE程序,事实上是最终用户在功能模块中进行操作的。用户点击相应component进入运行页面,触发某个程序,通过调度器来运行该程序,最后可以查看得到结果。这种方式适合于最终用户使用。需要注意:定义的程序的名字必须和在后台开发的AE程序的名字保持一致,同时一个AE程序是可以被多个组件调用的,并且一个组件下面也是可以运行多个程序的,这一点也和SQR程序是类似的。那么AE程序是怎样被多个组件调用的呢?这是在定义AE程序的时候设定的,添加哪些组件,就可以被哪些组件来调用,在“进程组”中输入允许运行此Process的用户组名字,如下:一个组件下面也是可以运行多个AE程序的,如下例:在运行时我们可以选择到底是运行哪个AE程序。3.运行方式专门的AE程序请求页面也可以有一个专门的AE程序页面,来运行它。实际上最终也是通过程序调度器来运行的。这种方式适合于开发者或者系统管理员使用。在定义该程序时,将这个专门的页面的组件添加进去即可。4.运行方式用peoplecode调用还有一种方式就是通过peoplecode调用AE程序了。调用函数如下:CallAppEngine();其语法如下:CallAppEngine(applid[,statereclist,processinstance]);5.其它的运行方式在本次项目中,AE程序的调度方式主要就是前面介绍的三种情况,那么还有一种运行方式,就是直接通过命令行进行调度。使用PSAE.EXE直接运行,需要指定运行参数。它适合于开发者或者系统管理员使用。事实上我们的其它的运行方式也是会产生命令,系统最终也是执行的命令,在执行AE程序时,进入如下页面后,我们可以点击“参数”,例如:可以在如下的页面看到该命令1.调试AE程序a.查看消息目录当运行完AE程序出错后,在WEB上可能会出现某些参数,其中就有关于消息目录的,如下:那么出现这样的系统消息,我们可以在如下的目录下进行查看,消息集合编号就是上图中的蓝色字体部分:在调试中我们可以参看下这些消息目录。b.使用日志文件在本次项目中,我用的最多的就是根据日志文件来调试AE程序,这是一种非常好的方法,我推荐使用。

如何来做呢?如下,在开发工具中打开该AE程序,点击红圈里的小图标:此时出现如下的框图之后:两项全选:点击确定,这时就会在相应目录生成日志文件。日志文件会默认放在c:\temp\HE_OTR01_AE.log目录下,需要说明的是每一次运行之后选择相同的目录都会覆盖之前的日志文件。c.学会使用Error和Warning利用上面查看日志的方法,我们还需要结合Error和Warning的使用。这样可以跟踪程序里的一些变量,以及执行情况,从而更好的判断程序的出错范围,最后进行定位和调试。我们来对Error和Warning进行下说明:在peoplecode里面使用Error,可以停止程序的处理,并且展现一条错误信息,它是不同于Warning的,对于Warning,它只是展现一条警告信息,而并没有停止对程序的处理。Error的语法如下:ErrorstrWarning的语法如下:Warningstr我们来看一个例子:Warning"&aetRecordName="|&aetRecordName;上面的句子就将程序里的变量&aetRecordName的值以警告的方式出现在日志文件里,“|”是peoplecode里连接字符串的符号。Error和Warning也经常会和函数MsgGet和MsgGetText来使用。MsgGet的语法如下:MsgGet(message_set,message_num,default_msg_txt[,paramlist])根据message_set和message_num来从目录册里面找回这个消息,如果没有找到的话,那么就会根据default_msg_txt来找消息,消息的设置从消息号1到19999是预留给peoplesoft应用的,从20000到32767是预留给peoplesoft的用户的。例如:ErrorMsgGet(1000,38,"DateofDeathmustbelaterthanBirthdate.")2.查看临时表的使用首先我们来说明下临时表。AE程序执行时,有时需要从数据库中取出大量数据,进行较多步骤的处理后,再写回数据库。为提高程序执行性能,可以定义TempTable,将这些中间数据储存在其中进行处理。一个AE程序可以定义多个TempTable。一个TempTable可以拥有多个实例,以适应AE程序的多实例运行。我们可以在如下的目录下面查看得到临时表的使用情况,包括临时表所使用的实例数,已经锁定的实例和未使用的实例等:并且也可以对临时表按照程序进行设置,包括程序是否可以使用重新启动功能,是否限制为批处理等,如下:3.管理AE程序的非正常结束事实上并不是每个AE程序都能够正常的结束的,那么我们在后台开发好了AE程序之后进行运行测试的时候,经常会碰到一些异常的情况,这个时候会造成什么后果呢?我们可以通过下面的路径来查看异常终止的进程。下面是一个异常终止的实例:通常AE程序被挂起是在调用第三方服务器,AE程序是以队列的形式运行的,如果总是出现同样的一个日志文件,那么很有可能是因为出现了异常,从而使得队列被截断,导致现在调用的AE程序并不能正常进行,停留在了原来运行的脚步,那么需要做的就是把这个异常删除掉。一般如果AE程序是一些正常的错误,那么是不会出现在这里,只有那些异常才会出现在这里。4.重启AE程序对于允许Restart的AE程序,如果该程序运行出错而导致非正常结束,AE会允许使用同一用户ID和同一运行控制ID的用户重新启动该程序,并忽略掉上次运行时已经成功提交的部分,从尚未提交的部分恢复运行。这样使得AE程序的执行更加可靠,出现错误后更容易恢复,有利于AE程序的并发运行,减少对数据库资源的锁定。对允许Restart的程序,AE在每次Commit之前,会把StateRecord中的数据重新写一遍。它的设置如下:1.AE程序开发过程分析首先来对使用AE程序进行开发的整个过程做一个分析:明白这个过程,将对本文后面的具体分析和描述有一个整体的思路。2.开发实例说明需要开发一个浦发银行的报盘程序,最后输出的格式是TXT文本格式。程序的页面传递参数是:报盘日期、日立组ID,其处理逻辑是输出指定日历中的员工账户名称、账号、发薪金额、员工ID、报盘总人数、总金额、报盘日期。输出表样如下:在ZONGJE以上的输出数据是固定格式,并不需要什么取数逻辑,只需要写入文本文件即可。ZONGJE总金额BISHUU报盘总人数RUZHRQ报盘日期银行帐号,个人总金额,姓名,员工ID3.对开发实例之分析及对常规问题总结针对上面的开发实例,我们进行具体的分析,它需要通过一定的处理逻辑选择出我们想得到的数据,从这里也可以看出AE程序主要负责与数据库进行的大量复杂的SQL交互任务。并且我们需要把最后的数据以规定的样表格式输出到文本文件里,这也正是这个AE程序的价值所在了,因为SQR程序虽然可以以多种格式输出,如下:但却不能够以文本文件的格式输出。另外生成的文本文件我们期望把它存放在服务器的哪个路径下呢?以怎样的名字来命名?如何把我们得到的数据写入到生成的文件里呢?这些就需要用到peoplecode里的知识了,我们可以用一些函数来实现这些操作。明白了这些实际上我们已经有了一个基本的思路了,那就是在一定的路径下先把这个文本文件生成,然后再给该文件里把我们按照一定的逻辑取出来的数据进行写入。那么我们再来看看一个总体的过程,需要先制作传递程序参数的页面并挂在相应的菜单下,然后在后台开发AE程序,在前台定义同名进程,再进行运行和测试,通过日志文件来调试,最终将程序调试成功。a.制作传递程序参数的页面并挂在相应的菜单下其参数包括报盘日期、日立组ID,那么我们需要建立一个包含运行报表时的参数的Record,其中它还必须包含两个字段用户ID和运行控制ID:OPRID和RUN_CNTL_ID,用来在运行该程序时绑定当前的用户ID和运行控制ID,如下:那么制作好了该Record之后,就可以用该Record上的字段来制作传递参数的页面了。然后我们再将其挂在合适的菜单下,具体方法参考我写的“SQR报表技术总结”一文。制作好的传参页面如下:需要注意:在制作传递程序运行参数的页面时,我们需要包含一个子页面,这个子页面是系统已经有的,名字为PRCSRUNCNTL__LC_SBP,包含它的目的是就是通过该页面可以跳转到进程监视器来查看程序的运行情况。这个子页面在我们制作的页面中,可以看到是下图的红圈部分:b.现在我们来讨论StateRecord。在AE程序的开发当中,Staterecord是必须要创建的record,这个record用来存储AE程序在运行过程中的一些参数,储存类似于其他编程语言中的“全局变量”。它必须以“processinstance”字段作为唯一主键。AE程序的每一个实例运行时,都唯一的对应Staterecord里的一行,AE程序每一个运行的实例都有一个实例号。现在我们就来建立这个运行该AE程序的Staterecord,事实上它只是比我们刚才建立的那个包含运行参数的record多了一个“processinstance”字段,建立的Staterecord如下:那么我们来看看在AE程序里的哪里来设置这个StateRecord,如下:需要说明的是:不是每一个AE程序都需要临时表的,这是和Staterecord所不同的地方。在我们本程序里并不需要建立临时表,因为我们本程序并不需要对数据库做写回操作。一般我们会根据AE程序的需要来判断是否建立临时表,以及为该程序建立几个临时表,为AE程序选择临时表的地方如下:c.现在我们来为本AE程序编写功能型Section以及MainSection,最后再将各个Section串起来来完成程序。在一开始我们已经做了一个大体的分析,那么接下来就是具体的实施。首先可以定义一组全局变量,把我们程序里面可能会经常用到的一些参数定义为全局变量,并为其赋值,例如生成的文本文件的名字、应该把该文件放入的路径等。接着我们需要绑定运行报表时的参数,通过Meta-SQL来实现。做完这些准备之后,我们就需要来根据业务需求建立相应的SQL语句,并且编写为存放文本文件创建目录的代码以及给文本文件写入数据的代码了。我们先来把几个SQL建立好。绑定程序运行时的用户ID和运行控制ID的SQL:HE_OTR01_AE如下:%Select(CAL_run_id,cal_prd_id,shec_offer_dt)SELECTcal_run_id,cal_prd_id,%DateOut(shec_offer_dt)FROMps_he_otr01_runWHEREoprid=%Bind(OPRID)ANDrun_cntl_id=%Bind(run_cntl_id)报盘总人数的SQL:HE_GP_BISHUU如下:SELECTCOUNT(1)FROM(SELECTDISTINCTp.emplidFROMps_gp_pye_seg_statpWHEREp.cal_run_id=:1ANDp.pin_net_val>0)总金额的SQL:HE_GP_ZONGJE如下:SELECTSUM(p.pin_net_val)FROMps_gp_pye_seg_statpWHEREp.cal_run_id=:1银行帐号,个人总金额,姓名,员工ID的SQL:HE_PSON_PYINFO如下:SELECTa.account_ec_id,b_val,a.account_name,a.emplidFROMps_pye_bankaccta,(SELECTb.emplid,SUM(b.pin_net_val)netvalFROMps_gp_pye_seg_statbWHEREb.cal_run_id=:1GROUPBYb.emplid)b_etWHEREa.emplid=b_et.emplidANDa.eff_status='A'ANDa.account_type_pye='B'可以看到后面三个SQL语句都有“:1”这样的参数,那么这样做我们又是在程序里面怎么将具体的参数传递进去的呢?我们来看一个例子就明白了:例如调用报盘总人数的SQL:HE_GP_BISHUU,可以用peoplecode做如下的实现:SQLExec(SQL.HE_GP_BISHUU,&calRunId,&offerBishuu);在这个调用的函数里,第一个参数用来说明是调用哪个SQL,第二个参数就是具体的SQL里面用来替代“:1”的参数,第三个参数就是存放该SQL语句选择出来的值。当然可能具体的SQL中还有“:2”等,那么只需要在调用该SQL的时候把这些具体的参数写完整,最后再把选择的值要存放的变量也写在调用的函数里,要注意这两种参数的位置。SQLExec会自动进行匹配。SQLExec的语法如下:SQLExec({sqlcmd|SQL.sqlname},bindexprs,outputvars)使用SQLExec是通过执行SQL命令字符串,该命令可以直接与数据库进行交互,该命令只能够选择出来一行的数据,如果查询出来的值多于一行,那么只会把查询出来的第一行的值赋给变量,其余行的值被丢弃,因此我们需要慎用。那么如果选择出来的值是多行,该做怎样的处理呢?我们可以使用GetSQL结合fetch函数以及WHILE循环的使用来实现这样的多行处理。GetSQL的语法如下:GetSQL(SQL.sqlname[,paramlist]例如:&SQL=GetSQL(SQL.HE_PSON_PYINFO,&calRunId);While&SQL.fetch(&bankAccount,&personSum,&name,&id)…………….End-While;d.根据c部分一开始的分析,我们来构建该AE程序的组成。如下:MainSection:Step1:GET_PARAPeoplecodeSQLStep2:INI_FILEPeoplecodeStep3:OUT_FILEPeoplecodeStep1用来定义全局变量和绑定运行参数,Step2用来创建文件目录,Step3用来将数据写入创建的文件。Step1的Peoplecode如下:Globalstring&reportName;Globalstring&filePath;Globalstring&aetRecordName;Globalstring&psHomePath;&psHomePath=GetEnv("PS_HOME");&filePath=&psHomePath|"\psreports\shec_report\";&reportName="HE_OTR01_REPORT_TEST";&aetRecordName="HE_OTR01_AET";从上面的代码我们就可以看到,我为该文本文件起名为"HE_OTR01_REPORT_TEST",还有一些变量是用来存放路径的。Step1的SQL如下:%Select(CAL_run_id,cal_prd_id,shec_offer_dt)SELECTcal_run_id,cal_prd_id,%DateOut(shec_offer_dt)FROMps_he_otr01_runWHEREoprid=%Bind(OPRID)ANDrun_cntl_id=%Bind(run_cntl_id)接下来我们可以为实现Step2和Step3来编写函数了,那么我们可以将这些函数存放在一个record的field的FieldFormula事件中,下面我们就来建立这样的一个record,如下:再来看具体的函数实现:/*========================================================================描述:取得文本文件的工作目录名称===========================================================================*/FunctionHE_GetDirectoryName(&aetRecordNameAsstring)ReturnsstringLocalstring&directoryName;LocalRecord&aetRecord;&aetRecord=GetRecord(@("Record."|&aetRecordName));&directoryName=Date

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论