登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

原来为了你

我的人生就是要一次次的超越

 
 
 

日志

 
 
 
 

[转]BADI  

2011-05-24 08:44:49|  分类: 增强 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

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:

        Program enhancements:program enhancements是通过interface methods来实现的,SAP程序来调取生成的badi class的interface methods。

        Menu enhancements:同customer exit一样,可以在badi中维护function code。这些menu entry在GUI definition中已经定义就可以在implemented badi看见。

        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,在应用程序中要实现以下步骤:

        生成badi class

        将badi class instance存入到refernce variable中

        将数据传递给badi class

        得到enhancement screen的program name和screen number

        调用screen

在main screen的PAI,需要调用另外一个method把修改后的数据传回给application program。

实现screen enhancement的几个步骤:

        首先通过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.

        然后implementation必须能够access badi instance。也就是说必须把reference variable赋给handler class的一个attribute。然后这个reference variable就会赋给badi class。通过下面的语句来实现这个步骤:CALL MEHTOD cl_exithandler=>set_instance_for_subsdcreens

        为了使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>.

        在执行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 = ..

        调用相应的subscreen,如果没有active implementation,就会显示default empty subscreen。

        如果在离开screen之后向得到Implementation中的data,则需要使用method:CALL METHOD exit->get_data IMPORTING <data>。

Implement badi screen enhancement的步骤如下:

        创建badi的implementation指定包含subscreen的程序名和screen number

        创建指定的program

        Layout指定的subscreen

        Implementing program必须得到badi的instance

        从应用程序传递给badi的数据可以被取得。

        如果想将修改后的数据返回给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扩展性局限于以下几个方面:

        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

        Badi definition: <badi> or z<badi> or /../<badi>

        Interface:IF_EX_<badi> or ZIF_EX_<badi> or /../IF_EX_<badi>

        Methods:any name

        Generated badi class(adapter class) cl_ex_<badi> or zcl_ex_<badi> or /../cl_ex_<badi>

BADI IMPLEMENTATION中的name conventions

        BADI implementation <impl> or z<impl> or /../<impl>

        Interface: IF_EX_<badi> or ZIF_EX_<badi> or /../IF_EX_<badi>

        Methods:在badi definition中定义

        Implementing class:CL_IM_<impl> ZCL_IM_<impl> /../CL_IM_<impl>

找到badi的方法:

        在应用程序中搜索CL_EXITHANDLER

        REPOSITORY INFORMATION SYSTEM

        相关component的IMG

 

1,BADI 对message type 是有限制的,如果你放'E',程序会dump

2,BADI是一个class interface,里面包含多个方法,before update or after update,可以选择具体的method来看他的参数。

3,within classes and interfaces, you can only use "type" to refer to abap dictionary types, not "like" or "structure"; and, the addition occurs is no longer supported in the oo context.use "table

of...initial size"instead; and,tables with headers are no longer supprted in the oo context.

badi对象的信息存储在SXS_INTER, SXC_EXIT, SXC_CLASS 和SXC_ATTR 这四个表中。

  评论这张
 
阅读(1390)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018