业务对象和BAPIweb
测试业务对象api
BAPI浏览器
BAPI与ABAP OO数据结构
BAPI的查找架构
BAPI调用成功与否通常经过RETURN参数返回(约定俗成)
Term/Synonym |
Definition |
Business object (BO) |
1. 业务对象,封装了与该对象相关的数据与方法; 2. 每一个业务对象都必须定义关键字段,用于惟一肯定一个特定的业务对象; 3. 业务对象中某些通用的方法具备标准的定义格式(如getlist); 4. 业务对象中定义的方法分为Instance-dependent方法与instance-independent两类。 |
Business Object Repository |
业务对象仓库。 |
Business Application Programming Interface(BAPI) |
1 访问R3中业务对象与业务过程的标准编程接口。 2 BAPIs 定义了BOR中业务对象的方法。 3 BAPIs 经过RFC-enable的功能模块实现。 4 用户能够自行开发新的BAPI以知足业务需求。 |
业务对象是现实世界中对象在SAP系统中的抽象,其内部封装了业务逻辑,并能够经过BAPI方法从外部进行访问,为SAP系统中的数据和流程提供了面向对象的视图。SAP中业务对象最初是为工做流系统的实现而开发的,但到目前,已普遍应用于整个SAP系统中的各个领域,如ArchiveLink、数据传输、GOS(Generic Object Service)系统等
业务对象经过组件存储信息,包括接口、关键字段、属性、方法和事件等,其中,关键字段和属性对应底层数据库表中的字段,具体的业务对象实例存储在相关的数据库表中。方法分为同步和异步两种,能够经过ABAP代码、事务、函数和报表来实现,经过BAPI函数实现的方法称为BAPI方法。上述组件经过一个ABAP程序与业务对象类型进行集成,在技术上实现SAP业务对象的构架:
业务对象类型是业务对象的定义和描述,面向对象架构的实现基础,也就是SAP系统中的“类”,它封装了业务功能和数据,一个业务对象即为一个业务实体,其中不只包含业务对象自己的数据,还包含其功能的实现,根据业务规则来组织数据和业务过程。例如一个物料业务对象,其数据传输方法和具体业务应用的实现都整合在该对象中
业务对象总体架构包含四层:
l 最内层SAP业务对象内核层,包含对象自己的内部数据结构及标准设定,如一个职员的姓名年龄、地址等
l 整合层,包含对象的业务逻辑。如一个职员的性别属性只能输入特定值、一个销售组织只能将货物销售给已经定义的业务伙伴等
l 接口层,提供该业务对象类型的外部访问接口,包括属性、方法、BAPI方法、事件等,这些方法表明着业务对象的行为,它们能够访问对象的数据,并改变一个对象的当前“状态”
l 外部访问层,定义了支持对业务对象数据访问的具体技术,如RFC\JCo\NCo等位于该层,这些技术经过接口层中定义的接口操做数据对象
业务对象仓库浏览器的事务代码是SWO3:
业务对象在业务对象浏览器中定义,业务对象建立器SWO1:
在SWO1中能够根据业务对象类型来查看它所对应的业务对象,知道业务对象后就能够在BAPI浏览器查找了:
面向对象中的“类”和“对象”的区别在于,一个是抽象化的概念,一个是具体的实例。SAP系统也是如此,系统中每一个单独的业务对象即为这类业务对象的实例,包含具体的数据。如物料A01、B02均为“物料”类的实例。业务对象类型也是能够继承的,如业务对象类型BUS1001006(标准物料)和BUS1001001(零售物料)的父类型都是BUS1001(物料):
SAP业务对象不支持多重继承,即一个业务对象类型只能制定惟一的父类型,但一个对象能够实现多个接口,以下图中的物料业务对象类型BUS1001就实现了多个SAP接口,这些接口中定义的方法将在该对象类型中从新实现:
接口中仅定义属性和方法的名称,但不能包含具体实现
业务对象类型组件:SAP对象的接口、属性、方法、事件
l 接口:自己就是一种特殊的业务对象类型,不能生成对象实例,但能够做为其它业务对象类型的接口组件, 其属性和方法或事件会自动添加到实现它的业务对象类型中
l 关键字段:用于惟一肯定一个业务对象类型的实例,一般是业务对象底层数据库表的对应主键
l 属性:业务对象的数据部分, 能够是数据表中的字段、运行值(又称虚拟属性, virtual attribute) 或指向其它业务对象的指针(对象引用, object reference)等。其中,对象引用多用于工做流设计过程
l 方法:用于操做业务对象属性,能够经过调用事务、function module、 report 或ABAP 代码来完成。方法是外界对业务对象进行访问的接口
l 事件:定义了SAP系统中与该业务对象相关的某种行为,一般是状态的改变。事件每每与工做流系统相关联。可经过事件触发工做流或任务。
(1)下图为业务对象类型BUS1001的组件列表:
上图中的关键字段Material.Material即为数据库表MARA中的关键字段:
(2)在浏览某个业务对象类型基本数据时,能够修改Defaults选项卡中业务对象的默认方法和属性,若是对业务对象访问时没有指定其余具体参数,则将执行默认的方法(具体是这样的吗?如何测试?):
(3)在方法列表中,其名称后有绿色标记的方法,表示该方法是经过BAPI实现;若是有“Stop”标识则表示该方法已通过时,有新的替代方法,不该再使用:
(4)双击某个方法(GetDetail),能够查看其名称、版本信息,并能够设定方法的一些特性:
上面General选项卡的各个选项的意义以下:
l Dialog:表示方法中包含用户交互对话,这种类型的方法不能在后台模式中执行
l Synchronous:设定方法的处理为同步模式;不然为异步模式。在工做流系统中,基于异步方法所建立的任务必须包含至少一个终止事件
l Result parameter:设定方法将返回一个参数做为结果。可能结果的值列表能够在Result type选项卡中的参照数据字典类型或对象类型来设定。只有同步方法才可以设定返回结果
l Instance-independent:表示该方法为实例无关的对象类型方法,即并不关联到特定物业的操做,例如Create(建立物料)、Getlist(显示列表)等方法,使用时并不须要指定具体操做的物料代码;而GetDetail等方法就须要在输入参数中设定关键字段,肯定所操做的对象实例
Reuslt type选项卡用于设定方法的返回类型,只有选中Result parameter选项后才须要设定该选项卡:
ABAP选项卡中还能够选择业务对象方法的实现方式,具体包括功能模块、BAPI函数、事务、报表等(业务对象方法若是是经过BAPI方法来实现的,则实现方式要选择API function,另外还须要指定对应到的BAPI功能模块,以下图):
双击上图中的BAPI功能函数模块,便可进入到BAPI功能模块的源代码屏幕。该功能模块是一个支持远程调用的功能模块(RFM),其功能是将从数据库中选择物料的数据,并经过表参数返回结果,并在下面第(6)步的业务对象实现程序RBUS1001的方法GetDetail所对应的代码段中调用该BAPI功能函数模块
(5)把光标放在某方法名上,选择Parameters按钮,能够查看方法的输入输出参数设定。对于同步方法能够设定输入、输出参数、返回值以及异常;而对于异步方法则只能设定输入参数:
(6)把光标放在某组件上,选择Program按钮,能够查看该组件在业务对象程序中相关代码段。业务对象BUS1001的系统程序名为RBUS1001,业务对象组件中关键字段、属性的定义,以及方法和事件的实现,都在该程序的代码完成。该程序及其中的代码,一部分是在建立业务对象时自动生成的,一部分是经过手工添加进行完善的。下图为方法Material.GetDetail的代码,由于GetDetail是一个BAPI方法,因此图中的代码段将调用BAPI功能模块BAPI_MATERIAL_GET_DETAIL,而普通的方法(非BAPI)不必定须要经过BAPI功能模块实现:
(1) 经过SWO1界面,输入业务对象 BUS1001,选择按钮,进入测试界面,此时业务对象还没被实例化,所以只显示与实例无关的属性和方法(即静态属性与方法):
(2) 若是须要测试与实例相关的方法,则须要点击Instance按钮,指定一个物料业务对象实例,即输入特定的物料号,就能够对实例方法进行测试了:
(3) 选择GetDetail方法后面的按钮,并根据需求输入该BAPI方法的Import参数值:
(5) 返回到初始测试页面,并选择Display方法,按一样的步骤进行测试,执行后系统将进入事务MM03界面,该方法不是一个BAPI方法,没有输入输出参数及返回值,而是直接调用一个事务:
BAPI是在BOR(业务对象仓库)中为SAP业务对象类型或接口类型定义的特殊方法,经过具备RFC属性的ABAP功能模块(即RFM )来实现,这种和业务对象关联的RFM也称为BAPI功能模块,俗称BAPI。所以,BAPI本意指代业务对象方法,但也经常能够指代其实现的功能模块
SAP业务对象的方法能够经过多种方式实现,BAPI实质上是一种特殊的、支持远程调用的业务对象方法,是经过具备“可远程调用”属性的函数实现
BAPI做为创建在RFC协议之上的、经过业务对象类型进行组织的系统接口,是在业务级别而不是技术层次定义的,所以可做为任意外部系统或应用访问SAP系统的标准途径,具备开放优势。一旦SAP为对象发布一个BAPI,则保持在后续全部软件版本对该BAPI的支持
BAPI:Business Application Process Interface(业务应用编辑接口),它实质上就是一种特殊的RFC,好比修改资产数据的BAPI函数:
RFC(Remote Function Call)不只是一个函数,也是一个数据通讯协议,与外部程序调用
RFC与普通的本地函数(也就是上面第一项:Normal Function Module)不一样的是,RFC全部参数只能是传值Pass Value,缘由是由于远程调用时,参数值的传递都是值,而不是引用,由于变量的引用都在本地内存中才能引用并指向:
与前面介绍的BDC、CATT、LSMW的应用不一样,前三者是经过录制屏幕的方式来实现数据维护,而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。在面向对象语言中(如:Java,C++),咱们既直接访问BAPI也可以经过RFC访问BAPI,而在非面向对象语言中(如:C),只能利用RFC访问BAPI
具体操做可查看前面SAP业务对象中前部分SWO1的讲解
事务码BAPI:
Documentation选项卡中的说明文档提供了使用相关BAPI的详细说明。
能够经过业务对象名来查找某个业务对象类型(以下图能够直接找出业务对象类型为 Material 的业务对象):
BAPI对应的功能模块命名规则BAPI_<bo>_<method>(<bo>即为业务对象名),所以能够直接在SE37中经过前缀BAPI加对象名称或方法名称做为关键字,快速查找一个BAPI功能模块函数。如检索 BAPI*Material*Get*
若是只知道事物代码,能够经过下面的方式查询相应的BAPI。例如找建立销售(物料模板根据此方法好像找不出)订单的BAPI,咱们知道事物代码是VA01:
1. 咱们进入VA01 界面,找到system ? status
2. 在事物代码位置上双击(注:不是程序上双击),找到PACKAGE VA
3. 用SE80打开包 VA ,或点击 Display Object List按钮直接进入到SE80对象列表:
4. 打开业务工程(引擎)——业务对象类型。根据咱们的业务需求。咱们要找销售订单的建立,全部BUS2032 销售订单的可能性最大。
5. 双击打开业务对象类型BUS2032,寻找和建立销售订单名字相同的方法这里咱们要找的就是SalesOrder.CreateFromDat2:
双击SalesOrder.CreateFromDat2 行,在弹出的窗口中找到 ABAP 选项卡,若是单选按钮是 API功能,则名称一栏即为咱们要找BAPI,若是是函数模块即为一个FM,即BAPI_SALESORDER_CREATEFROMDAT2:
注:上面是SalesOrder为业务对象名,而BUS2032为业务对象类型名:
BAPI 函数跟业务对象的关系存储在表SWOTLV中,对于一个业务对象,除了函数外,还存储了一些其它信息。这个表的 ABAPNAME 字段存储的就是函数名称,而 LOBJTYPE 字段则存储了业务对象类型名称。这样,当咱们找到一个 BAPI 函数后,就能够到这个表里查找它对应的业务对象了:
SAP 在给业务对象命名的时候仅有一部分用了缩写命名法,能够从缩写中猜想到业务对象的做用。接下来就是找表TOJTB,它的 NAME 字段存储了业务对象类型名称,而 EDITELEM 则是业务对象,这个描述就是事务码BAPI 中看到的名称。此外,从它的文本表 TOJTT 中还能够获得关于这个业务对象的详细描述:
BAPI功能模块是BAPI方法的具体实现。
根据事务的ACID原则,一个独立的BAPI实现必须具备事务性,同时,BAPI事务模型还必须容许开发者在调用多个BAPI时能够将它们绑定到同一个LUW上。所以,若是同时调用几个BAPI,开发者须要在程序中进行的事务控制,决定什么时候执行数据库提交或回滚操做;而BAPI内部则一般不包含COMMIT WORK和ROLLBACK WORK命令
操做多个BAPI时必须遵循如下原则(注:都是指在外部程序即主调程序中,而非BAPI功能模块内部):
l 若是有更新操做的BAPI,如建立、修改或删除一个业务对象实例,则对该实例进行另外的读取操做的BAPI只能访问上一个COMMIT WORK执行后的最新数据
l 在同一个LUW中,不能对同一个业务对象实例时行超过一次的更新操做。例如,不容许在一个LUW中建立一个新实例,随后就修改它。但能够建立多个相同的类型的不一样实例
在BAPI内部,数据库更新操做必须经过同步或异步的更新过程实现,由于不然可能出现没必要要的数据库提交过程,从而破坏了BAPI调用的ACID原则。一样缘由,BAPI内部也不能触发新的LUW,于是其内部程序代码中不能包含如下命令:
l CALL TRANSACTION
l SUBMIT REPORT AND RETURN
所以,BAPI事务中的数据库提交和回滚必须在主调程序中经过调用SAP标准业务对象BapiService(对象类型为SAP0001)的BAPI方法BapiService.TransactionCommit(此BAPI方法实际上仍是经过调用BAPI函数BAPI_TRANSACTION_COMMIT来实现的)和BapiService.TransactionRollback(此BAPI方法实际上仍是经过调用BAPI函数BAPI_TRANSACTION_ROLLBACK来实现的)来完成。在R/3 4.5以前,可使用远程功能模块BAPI_TRANSACTION_COMMIT和BAPI_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'.
WAIT为X时,会执行COMMIT WORK AND WAIT语句,不然执行COMMIT WORK语句
由于须要支持事务性RFC调用,因此BAPI功能模块中不包含异常处理参数(以及Changing也是没有的,只有Import、Export、Tables参数)。其成功调用或出错信息经过Export中的特定输出参数RETURN返回。该参数的数据结构能够参照数据字典结构BAPIRETURN、BAPIRETURN1、BAPIRET1、BAPIRET2或BAPIRET2_FIX等来定义,各类RETURN结构中的通用字段包括:
l TYPE,消息类型,如S、E、W、I
l ID,消息类型
l NUMBER,消息编号
l MESSAGE,消息文本
l MESSAGE_V1、MESSAGE_V2、MESSAGE_V3、MESSAGE_V4,消息变量
在BAPI返回结果时,必须经过与所调用的BAPI中RETURN参数相同类型的程序变量接收该参数返回值,并查看其结果。若是BAPI调用过程成功完成,RETURN字段可能为空,也可能在TYPE字段中包含S值,这须要在调用程序自行判断处理
在BDC录制时,只须要输入资产编号就能够从系统自动抓出该资产分类,而该BAPI有三个参数是必输入的:公司代码、资产编码、资产分类,在调用BAPI时只能经过资产编号与公司代码到相应表(ANLA)中查找分类了。
BAPI的参数结构有个特色:通常会将相似的字段放在同一个结构中,同时,还会存在一个与该结构名相似(后面以X结尾)标识结构,该标识结构中的字段名与赋值的结构中的字段名一致,可是其字段类型只是一个长度为1的字符,用于标识某个字段的数据是否须要经过BAPI来变动,例如:资产中的“通常数据”都经过BAPI的GENERALDATA字段来维护,若使用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.