业务对象和BAPI

业务对象和BAPI59

SAP业务对象(SWO1... 59

业务对象类型的组成... 62

测试业务对象... 66

BAPI68

BAPIABAP OO.. 70

BAPI的查找... 70

通过业务对象创建器SWO1查看BAPI70

通过BAPI浏览器查找BAPIBAPI... 70

直接查找BAPI函数... 71

查找某个事务码相对应的BAPI72

根据BAPI函数查找对应的业务对象... 74

调用BAPI75

事务性... 75

ABAP中调用BAPI函数... 76

BAPI调用成功与否一般通过RETURN参数返回(约定俗成)... 76

实例:通过BAPI修改资产数据

业对象和BAPI

Term/Synonym

Definition

Business object BO

1.      业务对象,封装了与该对象相关的数据与方法;

2.      每个业务对象都必须定义关键字段,用于唯一确定一个特定的业务对象;

3.      业务对象中某些通用的方法具有标准的定义格式(如getlist);

4.      业务对象中定义的方法分为Instancedependent方法与instanceindependent两类。

Business Object Repository

业务对象仓库。

Business Application Programming InterfaceBAPI

1       访问R3中业务对象与业务过程的标准编程接口。

2       BAPIs 定义了BOR中业务对象的方法。

3       BAPIs 通过RFCenable的功能模块实现。

4    用户可以自行开发新的BAPI以满足业务需求。

SAP业务对象(SWO1

业务对象是现实世界中对象在SAP系统中的抽象,其内部封装了业务逻辑,并可以通过BAPI方法从外部进行访问,为SAP系统中的数据和流程提供了面向对象的视图。SAP中业务对象最初是为工作流系统的实现而开发的,但到目前,已广泛应用于整个SAP系统中的各个领域,如ArchiveLink、数据传输、GOSGeneric Object Service)系统等

业务对象通过组件存储信息,包括接口、关键字段、属性、方法和事件等,其中,关键字段和属性对应底层数据库表中的字段,具体的业务对象实例存储在相关的数据库表中。方法分为同步和异步两种,可以通过ABAP代码、事务、函数和报表来实现,通过BAPI函数实现的方法称为BAPI方法。上述组件通过一个ABAP程序与业务对象类型进行集成,在技术上实现SAP业务对象的构架:

image163

 

业务对象类型是业务对象的定义和描述,面向对象架构的实现基础,也就是SAP系统中的“类”,它封装了业务功能和数据,一个业务对象即为一个业务实体,其中不仅包含业务对象本身的数据,还包含其功能的实现,根据业务规则来组织数据和业务过程。例如一个物料业务对象,其数据传输方法和具体业务应用的实现都整合在该对象中

业务对象整体架构包含四层:

l       最内层SAP业务对象内核层,包含对象本身的内部数据结构及标准设定,如一个职员的姓名年龄、地址等

l       整合层,包含对象的业务逻辑。如一个职员的性别属性只能输入特定值、一个销售组织只能将货物销售给已经定义的业务伙伴等

l       接口层,提供该业务对象类型的外部访问接口,包括属性、方法、BAPI方法、事件等,这些方法代表着业务对象的行为,它们可以访问对象的数据,并改变一个对象的当前“状态”

l       外部访问层,定义了支持对业务对象数据访问的具体技术,如RFC\JCo\NCo等位于该层,这些技术通过接口层中定义的接口操作数据对象

image164

 

业务对象仓库浏览器的事务代码是SWO3

image165

业务对象在业务对象浏览器中定义,业务对象创建器SWO1

image166

SWO1中可以根据业务对象类型来查看它所对应的业务对象,知道业务对象后就可以在BAPI浏览器查找了

image167

 

面向对象中的“类”和“对象”的区别在于,一个是抽象化的概念,一个是具体的实例。SAP系统也是如此,系统中每个单独的业务对象即为这类业务对象的实例,包含具体的数据。如物料A01B02均为“物料”类的实例。业务对象类型也是可以继承的,如业务对象类型BUS1001006(标准物料)和BUS1001001(零售物料)的父类型都是BUS1001(物料):

image168

SAP业务对象不支持多重继承,即一个业务对象类型只能制定唯一的父类型,但一个对象可以实现多个接口,如下图中的物料业务对象类型BUS1001就实现了多个SAP接口,这些接口中定义的方法将在该对象类型中重新实现:

image169

接口中仅定义属性和方法的名称,但不能包含具体实现

业务对象类型的组成

业务对象类型组件:SAP对象的接口、属性、方法、事件

l       接口:本身就是一种特殊的业务对象类型,不能生成对象实例,但可以作为其它业务对象类型的接口组件, 其属性和方法或事件会自动添加到实现它的业务对象类型中

l       关键字段:用于唯一确定一个业务对象类型的实例,通常是业务对象底层数据库表的对应主键

l       属性:业务对象的数据部分, 可以是数据表中的字段、运行值(又称虚拟属性, virtual attribute) 或指向其它业务对象的指针(对象引用, object reference)等。其中,对象引用多用于工作流设计过程

l       方法:用于操作业务对象属性,可以通过调用事务、function module report ABAP 代码来完成。方法是外界对业务对象进行访问的接口

l       事件:定义了SAP系统中与该业务对象相关的某种行为,通常是状态的改变。事件往往与工作流系统相关联。可通过事件触发工作流或任务。

image170

 

1)下图为业务对象类型BUS1001的组件列表:

image171

上图中的关键字段Material.Material即为数据库表MARA中的关键字段:

image172

2)在浏览某个业务对象类型基本数据时,可以修改Defaults选项卡中业务对象的默认方法和属性,如果对业务对象访问时没有指定其他具体参数,则将执行默认的方法(具体是这样的吗?如何测试?):

image173

3)在方法列表中,其名称后有绿色标记的方法,表示该方法是通过BAPI实现;如果有“Stop”标识则表示该方法已经过时,有新的替代方法,不应再使用:

image174

4)双击某个方法(GetDetail),可以查看其名称、版本信息,并可以设定方法的一些特性:

image175

上面General选项卡的各个选项的意义如下:

l  Dialog:表示方法中包含用户交互对话,这种类型的方法不能在后台模式中执行

l  Synchronous:设定方法的处理为同步模式;否则为异步模式。在工作流系统中,基于异步方法所创建的任务必须包含至少一个终止事件

l  Result parameter:设定方法将返回一个参数作为结果。可能结果的值列表可以在Result type选项卡中的参照数据字典类型或对象类型来设定。只有同步方法才能够设定返回结果

l  Instance-independent:表示该方法为实例无关的对象类型方法,即并不关联到特定物业的操作,例如Create(创建物料)、Getlist(显示列表)等方法,使用时并不需要指定具体操作的物料代码;而GetDetail等方法就需要在输入参数中设定关键字段,确定所操作的对象实例

Reuslt type选项卡用于设定方法的返回类型,只有选中Result parameter选项后才需要设定该选项卡:
image176

ABAP选项卡中还可以选择业务对象方法的实现方式,具体包括功能模块、BAPI函数、事务、报表等(业务对象方法如果是通过BAPI方法来实现的,则实现方式要选择API function,另外还需要指定对应到的BAPI功能模块,如下图):

image177

双击上图中的BAPI功能函数模块,即可进入到BAPI功能模块的源代码屏幕。该功能模块是一个支持远程调用的功能模块(RFM),其功能是将从数据库中选择物料的数据,并通过表参数返回结果,并在下面第(6)步的业务对象实现程序RBUS1001的方法GetDetail所对应的代码段中调用该BAPI功能函数模块

 

5)把光标放在某方法名上,选择Parameters按钮,可以查看方法的输入输出参数设定。对于同步方法可以设定输入、输出参数、返回值以及异常;而对于异步方法则只能设定输入参数

image178

image179

6)把光标放在某组件上,选择Program按钮,可以查看该组件在业务对象程序中相关代码段。业务对象BUS1001的系统程序名为RBUS1001,业务对象组件中关键字段、属性的定义,以及方法和事件的实现,都在该程序的代码完成。该程序及其中的代码,一部分是在创建业务对象时自动生成的,一部分是通过手工添加进行完善的。下图为方法Material.GetDetail的代码,因为GetDetail是一个BAPI方法,所以图中的代码段将调用BAPI功能模块BAPI_MATERIAL_GET_DETAIL,而普通的方法(非BAPI)不一定需要通过BAPI功能模块实现:

image180

测试业务对象

(1)       通过SWO1界面,输入业务对象 BUS1001,选择image181按钮,进入测试界面,此时业务对象还没被实例化,因此只显示与实例无关的属性和方法(即静态属性与方法):

image182

(2)       如果需要测试与实例相关的方法,则需要点击Instance按钮,指定一个物料业务对象实例,即输入特定的物料号,就可以对实例方法进行测试了:
image183

(3)       选择GetDetail方法后面的image184按钮,并根据需求输入该BAPI方法的Import参数值:

image185

(4)       输入参数后,点击执行,会界面结果屏幕:

image186

image187表示是一个结构可内表

(5)       返回到初始测试页面,并选择Display方法,按同样的步骤进行测试,执行后系统将进入事务MM03界面,该方法不是一个BAPI方法,没有输入输出参数及返回值,而是直接调用一个事务:

image188

BAPI

image189

BAPI是在BOR(业务对象仓库)中为SAP业务对象类型或接口类型定义的特殊方法,通过具有RFC属性的ABAP功能模块(即RFM )来实现,这种和业务对象关联的RFM也称为BAPI功能模块,俗称BAPI。因此,BAPI本意指代业务对象方法,但也常常可以指代其实现的功能模块

 

SAP业务对象的方法可以通过多种方式实现,BAPI实质上是一种特殊的、支持远程调用的业务对象方法,是通过具有“可远程调用”属性的函数实现

 

BAPI作为建立在RFC协议之上的、通过业务对象类型进行组织的系统接口,是在业务级别而不是技术层次定义的,因此可作为任意外部系统或应用访问SAP系统的标准途径,具有开放优点。一旦SAP为对象发布一个BAPI,则保持在后续所有软件版本对该BAPI的支持

 

BAPIBusiness Application Process Interface(业务应用编辑接口)它实质上就是一种特殊的RFC比如修改资产数据的BAPI函数

image190

 

RFCRemote Function Call不仅是一个函数,也是一个数据通信协议,与外部程序调用

 

RFC与普通的本地函数(也就是上面第一项:Normal Function Module)不同的是,RFC所有参数只能是传值Pass Value,原因是因为远程调用时,参数值的传递都是值,而不是引用,因为变量的引用都在本地内存中才能引用并指向

image191

 

与前面介绍的BDCCATTLSMW的应用不同,前三者是通过录制屏幕的方式来实现数据维护,而BAPI则需要通过ABAP程序来调用,只需要向指定的接口中传递数据,即可完成数据的维护操作。当然,不是所业务都提供了BAPI,有的还是需要通过BDC等方式来实现数据的批量维护

 

ü  它实际上是一种特殊的Remote Function Modules (RFC),在SAP内部组件及非SAP组件之间的技术整合与业务数据交换过程中起很大的作用。SAP通过该标准接口把整个系统链接为一个整体。外部程序可以通过BAPI访问SAP系统中的业务对象、数据、应用

ü  它提供的基于企业目标(Business Object业务对象) 技术的接口应用界面

ü  SAP采用了Object-oriented技术,逻辑定义了SAP R/3系统的所有功能目标,并且将所有的目标(Objects) BAPIs存储于企业目标库BOR(Business Objects Repository).

ü  SAP R/3 企业业务对象的对象类型(Object Type) 相当于对象设计语言中类(Class) 的概念,其定义结构由以下几部分组成:基本数据、接口界面、键(Key Fields)、方法(Methods)、特征(Attributes)、事件(Events)

ü  BAPI支持同步、异步的数据通信过程

ü  通过基于RFC协议实现的BAPI接口,可以从应用层直接对SAP业务对象进行访问

ü  BAPI建立在RFC协议基础上,外部语言需要进行RFC调用,即通过外部RFC接口来调用BAPI

ü  在第三方开发环境中,我们既能够直接访问BAPI,也能够通过RFC访问BAPI。在面向对象语言中(如:JavaC++),我们既直接访问BAPI也能够通过RFC访问BAPI,而在非面向对象语言中(如:C),只能利用RFC访问BAPI

BAPIABAP OO

image192

BAPI的查找

通过业务对象创建器SWO1查看BAPI

具体操作可查看前面SAP业务对象中前部分SWO1的讲解

通过BAPI浏览器查找BAPIBAPI

事务码BAPI

image193

image194

Documentation选项卡中的说明文档提供了使用相关BAPI的详细说明。

 

可以通过业务对象名来查找某个业务对象类型(如下图可以直接找出业务对象类型为 Material 的业务对象):

image195

直接查找BAPI函数

BAPI对应的功能模块命名规则BAPI_<bo>_<method><bo>即为业务对象名),因此可以直接在SE37中通过前缀BAPI加对象名称或方法名称作为关键字,快速查找一个BAPI功能模块函数。如检索 BAPI*Material*Get*

image196

查找某个事务码相对应的BAPI

如果只知道事物代码,可以通过下面的方式查询相应的BAPI。例如找创建销售(物料模板根据此方法好像找不出)订单的BAPI,我们知道事物代码是VA01

1.         我们进入VA01 界面,找到system ? status

2.         在事物代码位置上双击注:不是程序上双击),找到PACKAGE  VA

image197image198

3.         SE80打开包 VA ,或点击 Display Object List按钮直接进入到SE80对象列表:

image199

4.         打开业务工程(引擎)——业务对象类型。根据我们的业务需求。我们要找销售订单的创建,所有BUS2032 销售订单的可能性最大。

image200

5.         双击打开业务对象类型BUS2032,寻找和创建销售订单名字相同的方法这里我们要找的就SalesOrder.CreateFromDat2

image201

双击SalesOrder.CreateFromDat2 行,在弹出的窗口中找到 ABAP 选项卡,如果单选按钮是 API功能,则名称一栏即为我们要找BAPI,如果是函数模块即为一个FM,即BAPI_SALESORDER_CREATEFROMDAT2

image202

注:上面是SalesOrder为业务对象名,而BUS2032为业务对象类型名:

image203

根据BAPI函数查找对应的业务对象

BAPI 函数跟业务对象的关系存储在表SWOTLV中,对于一个业务对象,除了函数外,还存储了一些其它信息。这个表的 ABAPNAME 字段存储的就是函数名称,而 LOBJTYPE 字段则存储了业务对象类型名称。这样,当我们找到一个 BAPI 函数后,就可以到这个表里查找它对应的业务对象了:

image204

SAP 在给业务对象命名的时候仅有一部分用了缩写命名法,可以从缩写中猜测到业务对象的作用。接下来就是找表TOJTB,它的 NAME 字段存储了业务对象类型名称,而 EDITELEM 则是业务对象,这个描述就是事务码BAPI 中看到的名称。此外,从它的文本表 TOJTT 中还可以得到关于这个业务对象的详细描述:

image205

调用BAPI

事务性

BAPI功能模块是BAPI方法的具体实现。

 

根据事务的ACID原则,一个独立的BAPI实现必须具有事务性,同时,BAPI事务模型还必须允许开发者在调用多个BAPI时可以将它们绑定到同一个LUW上。因此,如果同时调用几个BAPI,开发者需要在程序中进行的事务控制,决定何时执行数据库提交或回滚操作;而BAPI内部则通常不包含COMMIT WORKROLLBACK WORK命令

 

操作多个BAPI时必须遵循以下原则(注:都是指在外部程序即主调程序中,而非BAPI功能模块内部):

l  如果有更新操作的BAPI,如创建、修改或删除一个业务对象实例,则对该实例进行另外的读取操作的BAPI只能访问上一个COMMIT WORK执行后的最新数据

l  在同一个LUW中,不能对同一个业务对象实例时行超过一次的更新操作。例如,不允许在一个LUW中创建一个新实例,随后就修改它。但可以创建多个相同的类型的不同实例

 

BAPI内部,数据库更新操作必须通过同步或异步的更新过程实现,因为否则可能出现不必要的数据库提交过程,从而破坏了BAPI调用的ACID原则。同样原因,BAPI内部也不能触发新的LUW,因而其内部程序代码中不能包含以下命令:

l  CALL TRANSACTION

l  SUBMIT REPORT

l  SUBMIT REPORT AND RETURN

 

因此,BAPI事务中的数据库提交和回滚必须在主调程序中通过调用SAP标准业务对象BapiService(对象类型为SAP0001)的BAPI方法BapiService.TransactionCommitBAPI方法实际上还是通过调用BAPI函数BAPI_TRANSACTION_COMMIT来实现的)BapiService.TransactionRollback(此BAPI方法实际上还是通过调用BAPI函数BAPI_TRANSACTION_ROLLBACK来实现的)来完成。在R/3 4.5之前,可以使用远程功能模块BAPI_TRANSACTION_COMMITBAPI_TRANSACTION_ROLLBACK完成相同的功能

 

在外部程序调用BapiService.TransactionCommit方法前,外部程序调用BAPI时并不触发数据库提交

 

对于BAPI的操作都要用BAPI_TRANSACTION_COMMIT来提交的,所以要判断BAPI的执行情况的返回值(参数RETURN),如果有错误要用BAPI_TRANSACTION_ROLLBACK取消所做的操作。建议在调用BAPI_TRANSACTION_COMMIT函数进行提交BAPI操作时,加上wait参数(如在该函数调用处后面代码需要读取前面刚提交的数据时),这样会减少某些错误: 

  CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
   
EXPORTING
     
wait = 'X'.

WAITX时,会执行COMMIT WORK AND WAIT语句,否则执行COMMIT WORK语句

ABAP中调用BAPI函数

BAPI调用成功与否一般通过RETURN参数返回(约定俗成)

因为需要支持事务性RFC调用,所以BAPI功能模块中不包含异常处理参数(以及Changing也是没有的,只有ImportExportTables参数)。其成功调用或出错信息通过Export中的特定输出参数RETURN返回。该参数的数据结构可以参照数据字典结构BAPIRETURNBAPIRETURN1BAPIRET1BAPIRET2BAPIRET2_FIX等来定义,各种RETURN结构中的通用字段包括:

l  TYPE,消息类型,如SEWI

l  ID,消息类型

l  NUMBER,消息编号

l  MESSAGE,消息文本

l  MESSAGE_V1MESSAGE_V2MESSAGE_V3MESSAGE_V4,消息变量

image206

 

BAPI返回结果时,必须通过与所调用的BAPIRETURN参数相同类型的程序变量接收该参数返回值,并查看其结果。如果BAPI调用过程成功完成,RETURN字段可能为空,也可能在TYPE字段中包含S值,这需要在调用程序自行判断处理

实例:通过BAPI修改资产数据

BDC录制时,只需要输入资产编号就可以从系统自动抓出该资产分类,而该BAPI有三个参数是必输入的:公司代码、资产编码、资产分类,在调用BAPI时只能通过资产编号与公司代码到相应表(ANLA)中查找分类了。

image207

BAPI的参数结构有个特点:一般会将类似的字段放在同一个结构中,同时,还会存在一个与该结构名类似(后面以X结尾)标识结构,该标识结构中的字段名与赋值的结构中的字段名一致,但是其字段类型只是一个长度为1的字符,用于标识某个字段的数据是否需要通过BAPI来变更,例如:资产中的“一般数据”都通过BAPIGENERALDATA字段来维护,若使用GENERALDATA接口,则需要传递GENERALDATAX结构。如这里要修改资产描述,资产描述对应的字段是GENERALDATA-DESCRIPT,若该字段被赋值,那么必须同时赋值GENERALDATAX-DESCRIPT=X,该字段才会被修改

 

TYPE-POOLS:truxs.
DATA:it_raw TYPE truxs_t_text_data.

DATA: companycode LIKE bapi1022_1-comp_code VALUE '0005',
      asset
LIKE bapi1022_1-assetmaino  VALUE '11000001',
      subnumber
LIKE bapi1022_1-assetsubno VALUE '0',
      generaldata
LIKE bapi1022_feglg001 ,
      generaldatax
LIKE bapi1022_feglg001x,
     
return LIKE bapiret2.

START-OF-SELECTION.
  generaldata
-descript = '资产描述'.
  generaldatax
-descript = 'X'.
  generaldata
-descript2 = '资产主号说明'.
  generaldatax
-descript2 = 'X'.

 
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
   
EXPORTING
     
input  = asset
   
IMPORTING

     
output = asset.

 
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
   
EXPORTING
     
input  = subnumber
   
IMPORTING

     
output = subnumber.

 
CALL FUNCTION 'BAPI_FIXEDASSET_CHANGE'

  
 DESTINATION 'NONE'"根据设定的目标值,可以远程调用,也可本地调用
    EXPORTING
      companycode 
= companycode
      asset       
=
asset
      subnumber   
=
subnumber
      generaldata 
=
generaldata
      generaldatax
=
generaldatax
   
IMPORTING

     
return       = return.
 
IF return-type <> 'S'.
   
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
 
ELSE.
   
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
     
EXPORTING
       
wait = 'X'.
 
ENDIF.

 
WRITE: / return-type , return-message.

image208

posted @ 2015-02-14 12:59  江正军  阅读(6283)  评论(0编辑  收藏  举报