设为首页 收藏本站
查看: 879|回复: 0

[经验分享] 【BAdI】Definition&Using SAP New BAdI

[复制链接]

尚未签到

发表于 2015-9-18 08:22:12 | 显示全部楼层 |阅读模式
  1, T-CODE:SE18,进入如下界面,选中 ’ Enhancement Spot’ 并输入所决定的名称.  
DSC0000.png   
  2, 点击上图中的 ’Create’ 按钮进入下一屏.在下面这个屏幕中输入Short Text,然后选择绿勾按钮.  
DSC0001.png   
  3,在上一屏,选择绿勾按钮后,出现下面这个屏幕,输入合适的package,可以使用本地对象这个package,然后点左下角的保存按钮.  
DSC0002.png   
  4,在上一屏保存之后出现下面的界面.选择 ‘Enh. Spot Element Definitions’ 这个页签(这个是进入后的默认页签),点击该页签左上角的 ‘Create BAdI’ 按钮,进入下一屏.  
DSC0003.png
  5,在如下屏幕中输入 BAdI Definition的name和Short Description. 然后选择绿勾按钮  
DSC0004.png   
  选择multiple use,这样对同一个接口可以存在多份实现。

  6,在上一屏选择绿勾后,在界面左边部分,找到Z_BADI_SAY字样,然后点开,双击Interface,然后在屏幕右边部分找到Interface字段,并填上自己决定的名称.最后点击保存.  
  
  7, 在上一屏中点击保存后出现如下对话框,选择Yes创建object.  
  
  8,创建object时,同样需要选择合适的package,这里仍然选择本地package.如下图所示.  
  
  9,在上一屏选择保存按钮之后,出现下面这个对话框,选择yes按钮表示保存.  
  
  10,在上一屏选择yes按钮保存之后,系统会跳到如下界面,要求我们给这个BADI定义method方法.这里定义了一个方法,名为say, level选择Instance Method(当然这里也可以选择Static,顾名思义可以不用创建类对象之间调用), 然后在后面的description里面填写上你所需要的描述.根据实际情况,决定是否需要参数. 这里需要一个输入参数,以便测试.所以点击下面这个屏幕的左上中部分的那个Parameters按钮.进入下一屏.
  
  11,在面的参数定义table control中,输入一个参数,名为forsay, 类型type为:importing.选中Pass Value,在Associated type中输入C,表示字符型. 点屏幕左上中部分的Methods按钮返回到方法设置界面.点击屏幕最上方的保存按钮,然后点击激活按钮.  
  
  12,在上一屏点击激活按钮后,出现下面的对话框,本次需要激活的对象都已默认选择,直接选择左下角的绿勾按钮确认.  
  
  13,到此为止,一个BADI的definition部分就算做完了.直接在上面一步绿勾激活后停留的界面上,在命令区域输入/NSE18, 或者/OSE18打开一个新的对话进程.我们将implementing这个BADI, 维护BADI Implementation.  
  在如下界面中,选择菜单->Enhancement Implementation->Create.  

  或者点击两个小人按扭

  14, 在上一步选择create之后,出现下面这个对话框,填写上面两个必输field之后,选择绿勾按钮确认.  
  
  15,在上一步选择绿勾按钮确认后,出现下面的对话框,选择合适的package以便保存.  
  
  16, 在上一步选择保存之后,出现如下对话框, 需要在BAdI Implementation这个列中,填写上我们第14中填写的Enhancement Implementation中值,即z_badi_say_impl. 填写完成后,选择左下角的绿勾按钮确认.  
  
  17,在上一步如果正确填写了BAdI Implementation列值后,将会进入如下界面.在这个界面中,选择Enh. Implementation Elements页签,在该页签的左边部分找到并点开Z_BADI_SAY_IMPL,然后双击出现的Implementing Class,直到该页签右边部分出现需要填写的Implementing Class字段,在该字段上填写上名称.  
  
  18, 在上一步操作完成后,点击上一屏上的保存按钮,出现下面对话框,选择Y确认创建该object.  
  
  19, 在创建时又会出现选择package的对话框,请选择合适的package.这里可以选择本地package.  
  
  20, 在上一步进行保存之后,如果一切都正确,则会出现下面的界面.将会出现我们在BADI Definition部分创建的method,在此即z_badi_say_interface~say. 双击该method.  
  
  21, 双击方法method时,出现下面这个确认对话框,选择Yes进行创建create.  
  
  22,在上一步选择Yes进行创建后,将会进入下面这个屏幕.如果不是在编辑状况,请点击左上角的Display<->Change按钮,切换到编辑状态.  
  
  23, 在编辑状态下,输入需要的codes.这里很简单,只是将在BADI Definition中定义的形参forsay给popup出来.  
  
  24, 上一步中输入的简单代码如下:  
  CALL FUNCTION 'POPUP_TO_DISPLAY_TEXT'
EXPORTING
      textline1          = forsay.  
  25,校验代码没有问题后,保存并激活.在点激活时出现如下界面,将所有项都选择后,点绿勾确认按钮.  
  
  26,以上完成了BADI的definition和implementation.下面创建一个非常简单的report进行测试.  
  REPORT Z_TEMP.
DATA: EXIT_SAY TYPE REF TO Z_BADI_SAY_IMPL_CLS,
      EXIT_SAY_INS TYPE REF TO Z_BADI_SAY_INTERFACE.
WRITE: 'CLICK ME' HOTSPOT.
AT LINE-SELECTION.
CREATE OBJECT EXIT_SAY.
EXIT_SAY_INS = EXIT_SAY.
CALL METHOD EXIT_SAY_INS->SAY
EXPORTING
        FORSAY = 'Hi you'.  
  27,总结.以后,在不改动上面这个简单的report的情况下,我们通过更改这个report所对应的BADI的say方法,就可以让这个report作出不同的效果.就比如SAP标准程序中有Call method的地方,并且对应BADI的话,我们可以不改动程序,通过应用BADI,实现程序的额外功能.  
  28.重复13的动作可以创建多个实现

  29. 对于classic BAdI可以用以下代码获取执行,(对于New BAdI会报出DATA_INCONS_IN_EXIT_MANAGEM 的Error信息)
  *get badi implementation class by interface name
CALL METHOD CL_EXITHANdLER=>GET_INSTANCE
CHANGING
    INSTANCE = LR_EXIT.
  CALL METHOD LR_EXIT->lgort_check
    EXPORTING
       LGORT = wa_lgort.
  (这种方式只能应用于Classic BAdI,)
  30. ECC6.0以后的版本,对于New BAdI要用Get BADI/CALL BADI语法搞定
      DATA bd TYPE REF TO Z_BADI_CHECK.
  
GET BADI bd .
CALL BADI bd->LGORT_CHECK exporting lgort = wa_lgort.

  (说明:其中LGORT_CHECK 是BAdI中的Method,系统会自动找到每个implementation 里的代码并执行,当然Method的parameters一定要和Interface定义的一致)
  30. 其它一些关于自定义BAdI的文章
  以下链接转载自 http://scnblogs.techweb.com.cn/abaplv/archives/tag/badi

  Class是object的抽象描述,object只是在程序运行时才能存在。Object是由class描述的,并包含两个层次,inner layer和outer layer。Object的public component就是这个object的interface。Oo的主要目的就是为了保证object本身状态的consistency。Object的attributes一般是internal的,只能被它的method修改。对于具有相同attributes和methods的object他们也有自己的identity来区分。与OO概念相似的有function group,不同的是function group只能有一个instance,而object可以有任意个instance。
  Interface是独立于class之外定义的。.它包含向attributes和methods这样的声明语句。其具体功能是通过class来实现的。这些class应该有统一的与外部联系的方式,并通过实现方法来实现interface的所有功能。在程序中你可以创建interface变量来指向interface,但是你不能instantiate一个interface。Interface变量用来指向不同class的object。
  与customer exit不同的是,badi考虑到了软件修改的发布流程。Badi enhancement的实现至少需要一个interface以及相应的class来实现它,interface的实现由用户来完成。这种enhancement的一个优点是它提供了reuse的能力。一旦实现了,badi在软件的发布过程中仍然可以重新实现。Implementation本身也可以提供badi。
  一个badi包含着enhancement components,其主要包含下面几种components:
  l Program enhancements:program enhancements是通过interface methods来实现的,SAP程序来调取生成的badi class的interface methods。
  l Menu enhancements:同customer exit一样,可以在badi中维护function code。这些menu entry在GUI definition中已经定义就可以在implemented badi看见。
  l Screen enhancements:同customer exit一样你可以在badi中维护screen enhancements。
  创建badi时,几个相关的部件就会被创建:interface和为实现interface而生成的class。生成的class主要实现下面的任务:过滤,如果你实施了一个过滤badi,那么这个class就会保证只有相关的implementation才会被调用。
  Badi的执行流程:首先service class CL_EXITHANDLER会创建一个object reference,并产生调用program enhancement method的条件。当你定义BADI时,就会产生一个BADI class,用来implement badi interface。调用时,badi class的interface method就会被调用。Badi会搜索所有的BADI Implementation并调用implemented methods。
  Badi在调用程序中的实现源代码如下:
  REPORT <program_using_badi>.
  DATA: r_var TYPE REF TO <badi-interface>.
  START-OF-SELECTION.
  CALL METHOD cl_exithandler=>get_instance
  CHANGING
  Instance = r_var.
  CALL METHOD r_var->method
  EXPORTING
  <i_variables>
  IMPORTING
  <e_variables>.
  END-OF-SELECTION.
  首先你必须定义一个指向badi interface的reference variable。这个reference variable的名字不一定要包括badi的名字。第一次调用时一个object reference就会被创建,只用interface的method才会被这个reference object调用。可以通过这个reference object来调用你需要的enhancement中的方法。
  可以通过t-code SE19来implement badi。
  可以给implement class分配任何的名字,不过最好遵循以下规则:namespace以Y或Z开始,对于class的name以CL开始,implementation的name以IM开始,要implement method只要双击method name即可,系统会自动启动Class Builder editor。一旦完成代码编写,一定要激活它。
  如果badi被激活,当调用程序执行时,相应的implementation methods也会被执行。一旦diactivate这个implementation,相应的方法就不会被调用。然而应用程序中的相关调用仍然会被执行。不同的是adapter class的instance不会找到激活的implementations。并不像CALL CUSTOMER-FUNCTION,CALL METHOD CL_EXITHANDLER=>GET_INSTANCE即使没用implementations,仍然会被调用。只有在original system中才可以activate或deactivate implementations,而subsequent systems则只能transport。如果badi只能有一个implementation,那么系统中仍然可以存在这个badi的多个implementation,只不过只能有一个激活版本。
  同customer exit一样badi中也有menu enhancements。但是必须满足以下两个条件:1,必须预留了menu enhancement。2,必须在Badi的implementation中实现。Menu enhancements的function codes必须以+开始。如果相应的enhancement的badi implementation被激活,那么menu就会显示出来。你只能为single use badi创建function code,而且badi不能是filter dependent。这样就保证了一个或多个的badi不出现矛盾。如果用户在程序中选择了相应的以+开始的function code,那么系统就会调用相应的method。Method call和Menu enhancement是不可分离的,它们只能属于同一个badi。
  通过badi builder SE18来创建badi。Badi有两个重要的属性,Reusable和filter-dependent。如果想让你的badi支持多个激活的implementation那么就要选择reusable。不过implementations的执行顺序不能被定义。即使badi本身不支持mulitiple use也可以同时存在多个implementations,只不过只能有一个激活的implementation。Badi如果filter dependent的,这样就可以设置调用的条件。Filter type必须是data element或者ABAP dictionary structure。Data element使用的domain的value table包含了implementation所需要的valid values。如果filter type使用的是structure,那么这适用于structure的每个字段。当调用enhancement method时,filter value必须传给interface。Badi中可以包含function code,需要输入program name,function code以及short description。局限性是不能够创建只包含function code的badi,menu enhancement既不能filter dependent也不能reusable。
  系统提供了badi的interface和生成class的name。理论上可以将这些name改成任何你喜欢的name,但是保留系统推荐的name会使badi更加容易理解。生成的class的name遵循以下规则:namespace prefix + CL_ + EX_(代表 exit) + badi name。双击interface name就会进入class builder,就可以定义interface method。一个badi indterface可以有多个interface method。Class bulder的所有功能都可以使用,如定义interface method,定义method的interface parameters以及声明interface的attributes等。如果badi是filter dependent的,必须给他的每个method定义一个import parameter flt_val。一旦完成了interface的定义就要激活它。一旦修改了interface,badi class也会重新生成。也可以在badi维护事务中通过utilities->Regenerate来重新生成adapter class。Badi在程序中的调用过程:首先声明一个badi interface的reference variable。调用service class CL_EXITHANDLER的static method GET_INSTANCE。这个method返回required object的instance。这里属于narrow cast,所以通过这个variable只能调用interface methods。然后你就可以调用badi的方法了。示例如下:
  DATA: r_var TYPE REF TO <badi-interface>.
  START-OF-SELECTION.
  CALL METHOD
  Cl_exithandler=>get_instance
  CHANGING
  Instance = r_var.
  CALL METHOD r_var-><method>
  EXPORTING
  <i_variables>
  IMPORTING
  <e_variables>/
  如果使用filter dependent badi,要给参数flt_val传递一个适当的值。
  对于ABAP virtual machine,screens和class是不能绑定到一块的。所以只用classical programs(type I,For M)才能作为screen的容器。Badi的screen enhancement也必须考虑到这点。当创建badi screen enhancement时,在应用程序的screen上要保留一块subscreen area。然后implementing program就会填充它。应用程序和subscreen的container program并不直接交换信息,而是通过生成的badi class。如果badi包含screen enhancements那么它就不能是reusable的。在subscreen tab你需要输入calling program,screen number和subscreen area。Implementing program和subscreen number是在implementation过程中指定的。
  如果想通过badi实现screen enhancement,在应用程序中要实现以下步骤:
  l 生成badi class
  l 将badi class instance存入到refernce variable中
  l 将数据传递给badi class
  l 得到enhancement screen的program name和screen number
  l 调用screen
  在main screen的PAI,需要调用另外一个method把修改后的数据传回给application program。
  实现screen enhancement的几个步骤:
  l 首先通过adapter class CL_EXITHANDLER的factory method get_instance来得到生成的badi class的一个instance。并将其存储到一个reference variable中。DATA:EXIT TYPE REF TO <badi-interface>. CALL METHOD cl_exithandler=>get_instance CHANGING instance = exit.
  l 然后implementation必须能够access badi instance。也就是说必须把reference variable赋给handler class的一个attribute。然后这个reference variable就会赋给badi class。通过下面的语句来实现这个步骤:CALL MEHTOD cl_exithandler=>set_instance_for_subsdcreens
  l 为了使implementation获得数据需要通过两个步骤来实现。首先将data传给badi class,这些数据存储在这个方法的implementation的global attributes中,强烈建议在这个步骤提供sample code。通过badi中定义的mehtod来传递数据。然后存储在badi global attributes中的data就会被自动传到implementation的global attributes中,当然,implementation必须是active状态。使用的语句如下:CALL METHOD exit->put_data EXPORTING <data>.
  l 在执行CALL SUBSCREEN语句之前,必须得到subscreen的screen number和program name,这个通过方法cl_exithandler=>get_prog_and_dynp_for_subsc来实现。如果没有active implementation,就会得到dummy function group(SAPLSEXM)的dummy subscreen (screen number 200)。如果存在active implementation,在implementation中指定的subscreen就会被使用。语句如下:CALL METHOD cl_exithandler=>get_prog_and_dynp_for_subscr EXPORTING … IMPORTING called_program = … called_dynpro = ..
  l 调用相应的subscreen,如果没有active implementation,就会显示default empty subscreen。
  l 如果在离开screen之后向得到Implementation中的data,则需要使用method:CALL METHOD exit->get_data IMPORTING <data>。
  Implement badi screen enhancement的步骤如下:
  l 创建badi的implementation指定包含subscreen的程序名和screen number
  l 创建指定的program
  l Layout指定的subscreen
  l Implementing program必须得到badi的instance
  l 从应用程序传递给badi的数据可以被取得。
  l 如果想将修改后的数据返回给application program,需要调用相应的方法。
  得到badi class instance的方法是CALL METHOD cl_exithandler=>get_instance_for_subscreens,这个reference是通过方法cl_exithandler=>set_instance_for_subscreen来传递的。这允许你在implementation中访问badi的attributes以及interface methods。Implementing program通过方法:exit->get_data IMPORTING <data>来获取badi中的data。通过方法exit1->put_data EXPORTING <data>将修改后的data传回给badi class的instance。
  Filter type扩展性局限于以下几个方面:
  l Filter type参考的domain必须符合下面的几个条件:
  Ø Domain要指向cross client value table。这个value table只有一个使用的data element的domain是这个domain的key field。
  Ø Domain有一个两个key field的text table,一个key field使用的是这个domain本身,另一个key field是language field。其必须还得有一个text field,这个text field的类型为TEXT或TXT。在ABAP DICTIONARY中必须给text field指定一个value table。
  Ø 这两个table的delivery class必须是E或S
  如果没有active implementations,那么由enhancement provider提供的default implementation就会被执行。在badi definition中通过goto->default code就可以创建default implementation。还可以创建一个sample implementation。通过goto->sample code就可以创建。几种增强方法的比较:
  Customer Exit
  BTE
  BADI
  Source code
  +
  +
  +
  Menus
  +
  -
  +
  Screens
  +
  -
  +
  Table
  +
  -
  [+]
  Administration levels
  +
  -
  +
  reusable
  -
  +
  +
  Filter specific
  -
  +
  +
  BADI DEFINITION中的name conventions
  l Badi definition: <badi> or z<badi> or /../<badi>
  l Interface:IF_EX_<badi> or ZIF_EX_<badi> or /../IF_EX_<badi>
  l Methods:any name
  l Generated badi class(adapter class) cl_ex_<badi> or zcl_ex_<badi> or /../cl_ex_<badi>
  BADI IMPLEMENTATION中的name conventions
  l BADI implementation <impl> or z<impl> or /../<impl>
  l Interface: IF_EX_<badi> or ZIF_EX_<badi> or /../IF_EX_<badi>
  l Methods:在badi definition中定义
  l Implementing class:CL_IM_<impl> ZCL_IM_<impl> /../CL_IM_<impl>
  找到badi的方法:
  l 在应用程序中搜索CL_EXITHANDLER
  l REPOSITORY INFORMATION SYSTEM   l 相关component的IMG

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-115152-1-1.html 上篇帖子: SAP SD 模块面试题 下篇帖子: SAP Control framework
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表