SAP ABAP开发详解与高端应用 (第7页)

第 223 页 / 共 377 页

public SAPLogon( String client, //集团

String userid, //用户

String password, //密码

String language, //语言

String ip, //IP

String system_number) //系统编号

{

try {

mConnection = JCO.createClient( client, //集团

userid, //用户

password, //密码

language, //语言

ip, //IP

system_number); //系统编号

mConnection.connect();

mRepository = new JCO.Repository("Lee", mConnection);

System.out.println("SAP连接成功");

mRepository = new JCO.Repository("my_repository", mConnection);

mConnection.disconnect();

} catch (Exception ex) {

ex.printStackTrace();

System.exit(1);

}

}

}

同理,编辑类StartServer,设定属性如图3-177所示。

图3-177

215

第 224 页 / 共 377 页

编辑代码如下:

package TestRFC;

public class StartServer {

public static void main(String[] args) {

SAPLogon mySAP =

new SAPLogon("000", //集团

"yidatec", //用户

"pylgkg", //密码

"1", //语言

"192.168.61.251",//IP

"00"); //系统编号

SAPServer myServer = new SAPServer(mySAP.mRepository);

myServer.start();

}

}

注:将动态链接库 sapjcorfc.dll 拷贝到 D:\MyEclipse 6.5\jre\bin 或操作系统文件夹

C:\WINDOWS\system32中。

步骤五:运行程序,调用RFC,测试编辑结果。

在Java程序所在机器运行类StartServer,如图3-178所示。

图3-178

运行ABAP程序ZRFC_JAVA,如图3-179所示。

图3-179

输入伦理文件名,单击 按钮运行程序,结果如图3-180所示。

图3-180

21 6

第 225 页 / 共 377 页

Web Service后台Log输出如图3-181所示。

图3-181

3.5 BAPI的应用

BAPI业务应用编程接口(Business Application Programming Interfaces)业务应用编程接

口,其作用可分为:

■ 在SAP内部组件及非SAP组件之间的技术整合。

■ 业务数据交换。

■ SAP通过该标准接口把整个系统链接为一个整体。

■ BAPI是SAP中心组件R/3、ECC和BW系统的入口之一。

BAPI基于RFC技术实现,提供的整合扩展到了业务层面,外部程序可以通过BAPI访问

SAP系统中的业务对象、数据、应用。

3.5.1 SAP业务对象

SAP业务对象(Business Object)代表的是实际世界的对象,比如一个采购订单、一个物

料数据等,包含业务数据,并描述了完整的业务过程。

SAP 的面向对象架构通过业务组件、业务对象类型、BAPI 等元素共同完成,每个 SAP

业务组件都提供相对独立的功能,其中包含业务对象类型和实例。

业务过程或业务场景可以在一个业务组件内部或者跨模块/系统实现。跨系统的业务过程

也称为分布式业务过程,其集成通过ALE技术实现。业务对象类型是业务对象的定义和描述,

它是面向对象架构的实现基础,也就是 SAP 系统中的“类”,它封装了业务功能和数据,一

个业务对象即为一个业务实体,其中不仅包含业务对象本身的数据,还包含其功能的实现,

根据业务规则来组织数据和业务过程。

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

■ 最内层:SAP业务对象内核层,包含对象本身的内部数据结构及标准设定。

■ 整合层:包含对象的业务逻辑。

■ 接口层:提供该业务对象类型的外部访问接口,包括属性、方法、BAPI 方法、事

件等。

■ 外部访问层:支持对业务对象数据访问的具体技术、RFC/JCo/NCo等。

217

第 226 页 / 共 377 页

业务对象仓库(Business Object Repository),是SAP业务对象类型和相关BAPI组织中心。

业务对象仓库浏览器的事务代码是SW03,业务对象在业务对象浏览器(SWO1)中定义,使

用业务对象创建器可以浏览业务对象类型的组件。

接口中仅定义属性和方法的名称,但不能包含具体实现,SAP业务对象不支持多重继承,

即一个业务对象类型只能制定唯一的父类型,但一个对象可以实现多个接口。

BAPIs(Business Application Programming Interface)是为 SAP 业务对象提供的特

殊方法,它们被存储在SAP系统的业务对象库中(Business Object Repository (BOR)),用

于实施特殊业务任务。一个业务对象里可以有多个方法,每个方法就是一个 BAPI。

在 SAP 系统中,BAPIs 是具有 RFC 功能的模块,可以在函数编辑器(SE37)中做成。

BAPIs提供标准的业务接口,使得外部应用可以使用SAP的功能和数据。

利用 BAPIs 来访问 SAP 业务对象的客户端程序,可以是同一 SAP 系统的一部分,可以

是外部系统的一部分,也可以是另一SAP系统的一部分。

要查看SAP系统中存在的BAPIs,可以按如下路径寻找。登录SAP菜单→工具→业务框

架→BAPI浏览器,或调用事物代码:BAPI,如图3-182所示。

图3-182

3.5.2 BAPI定义

1.为BAPI定义构造体

BAPI用输入参数定义如图3-183所示。

图3-183

21 8

第 227 页 / 共 377 页

BAPI用输出参数定义如图3-184所示。

图3-184

■ 每个参数必须参照一个构造,必须以BAPI作为头字母,即使这个参数只有一个字段,

它也必须参照一个构造的某个字段。

■ 一般情况下,项目中会对传入/传出的参数以结构形式定义。不推荐使用系统中已经存

在的构造,因为当BAPI被释放后,BAPI用的构造就会被冻结。

在ABAP数据字典(SE11)中建立构造体(具体步骤参见《SAP Dsbs系列教程:ABAP

数据字典》)。

2.定义函数体(具体步骤参见[第11章:函数])

(1)创建函数组

一个业务对象下的所有 BAPI 必须放在同一个函数组中,并且该函数组不能包含其他的

函数,如图3-185所示。

图3-185

219

第 228 页 / 共 377 页

(2)创建函数

属性标签页设定如图3-186所示。

图3-186

注:在属性标签下选中 ,否则这个函数模块不能通过RFC被调用,也不能作

为一个BAPI使用。

输入(Import)标签页设定如图3-187所示。

图3-187

输出(Export)标签页设定如图3-188所示。

图3-188

表(Tables)标签页设定如图3-189所示。

图3-189

22 0

第 229 页 / 共 377 页

■ 每个BAPI必须有RETURN参数,这个参数可能是Export Parameter,也可能是Export

Table。它的类型一般是BAPIRET2或BAPARETURN。

■ BAPI中不可以使用Exceptions,错误消息都放到RETURN中。

■ 所有的Currency字段都参照BAPICURR域。

■ 所有的日期字段都是YYYYMMDD的格式。

源代码如下:

FUNCTION Z_BAPI_GET_TEST.

*"----------------------------------------------------------------------

*"*"Local interface:

*" IMPORTING

*" VALUE(CLASS)、 TYPE ZZCLASS_E DEFAULT '1A'

*" VALUE(YEAR)、 TYPE ZZYEAR_E DEFAULT '2009'

*" EXPORTING

*" VALUE(RETURN)、 TYPE BAPIRETURN

*" TABLES

*" TESTDATA STRUCTURE ZZTEST_S

*"----------------------------------------------------------------------

SELECT * FROM ZZTEST_V

INTO CORRESPONDING FIELDS OF TABLE TESTDATA

WHERE ZZCLASS = CLASS

AND ZZYEAR = YEAR.

IF SY-SUBRC <> 0.

RETURN-TYPE = 'S'.

RETURN-CODE = '10005'.

RETURN-MESSAGE = '没有相关数据!'.

ENDIF.

ENDFUNCTION.

■ BAPI不能执行COMMIT WORK及ROLLBACK 命令(用函数BAPI_TRANSACTION_

COMMIT和BAPI_TRANSACTION_ROLLBACK代替)。

■ BAPI常用于更新数据库和取值。

■ BAPI不可以显示画面,并且BAPI调用的函数也不能显示画面。

(3)保存、有效化并发布函数

发布路径如图3-190所示。

图3-190

221

第 230 页 / 共 377 页

3.创建业务对象(事务代码:SWO1)

步骤一:业务对象制作程序的初始画面。

在“对象/接口类型”栏位中填入业务名称,单击 按钮,如图3-191所示。

图3-191

在相应的栏位填入说明和程序信息,如图3-192所示。

图3-192

单击上图中的 按钮,如图3-193所示。

图3-193

单击上图中的保存按钮 ,如图3-194所示。

图3-194

22 2

第 231 页 / 共 377 页

单击上图中的按钮 。

步骤二:业务对象制作程序的对象编辑画面和添加API的方法。

按照以下路径选中相应菜单项,如图3-195所示。

在“Function Module”栏位中填入已定义函数,如图3-196所示。

图3-195 图3-196

单击上图中的 按钮,如图3-197所示。

图3-197

■ [对话]复选框被选中表明该BAPI包含用户交互对话,否则不包含。

■ [同步]复选框被选中表明该BAPI是同步调用。否则,是异步调用。

■ [独立实例]复选框被选中表明该BAPI是实例非依存的。否则,是实例依存的。

注:比较低的版本有[返回结果]复选框,设定方法将返回一个参数作为结果,在结果类型

中设定值列表,只有同步方法才能设定返回结果。

单击上图中的 按钮,如图3-198所示。

图3-198

223

第 232 页 / 共 377 页

■ 「扩展」复选框被选中表明该参数是传出参数。

■ 「输入」复选框被选中表明该参数是传入参数。

■ 「Mline」复选框被选中表明该参数是一个表。

■ 「Man.」复选框被选中表明该参数是必选的。

■ 创建者必须指定表是传入参数还是传出参数,或者两者都是。

单击上图中的 按钮,如图3-199所示。

图3-199

单击上图中的 按钮,如图3-200所示。

图3-200

步骤三:保存、实现并生成业务对象。

1)单击标准工具栏中的 按钮,如图3-201所示。

图3-201

2)选中画面中的业务对象 ,按照以下路径将其实装,如图3-202所示,其效

果如图3-203所示。

图3-202

图3-203

3)选中方法 ,按照以下路径将其实装,如图 3-204

所示,其效果如图3-205所示。

22 4

第 233 页 / 共 377 页

图3-204

图3-205

注:以上两个步骤缺一不可,开发人员需要注意。

4)单击应用工具栏中的 按钮,生成业务对象,如图3-206所示。

图3-206

步骤四:BAPI确认。

运行事务代码BAPI,确认BAPI生成结果,如图3-207所示。

图3-207

3.5.3 BAPI调用

BAPI是在BOR 中为SAP 业务对象类型或接口类型定义的特殊方法,通过 RFC 支持的

ABAP功能模块实现,和业务对象关联的远程函数模块也称为BAPI函数模块,俗称BAPI。

BAPI支持同步、异步的数据通信过程,通过基于RFC协议实现的BAPI接口,可以从应

用层直接对SAP业务对象进行访问。

BAPI不存在表现层,调用BAPI的第三方负责显示传入BAPI或BAPI返回数据,BAPI

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

通过SAP业务连接器,还支持从Internet直接访问BAPI,可以从BAPI调用中创建XML

225

第 234 页 / 共 377 页

文档,或者将入站XML文档转换为BAPI调用,实现SAP到Internet集成:

■ 集成SAP系统中已存在的业务应用及组件。

■ 集成已实施的SAP R/3、ECC和其他SAP系统。

■ 集成外部应用与SAP系统。

■ 网络应用集成(SAP业务连接器和互联网应用组件)。

■ BAPI 作为系统业务数据导入、导出方式之一,应用于数据传输、ALE 数据分布

过程。

1.BAPI查找

■ 从业务对象创建器查找BAPI(事务代码SWO1)。

■ 通过BAPI浏览器查找BAPI(事务代码BAPI)。

■ 利用BAPI对应的功能模块命名规则查找BAPI_<bo>_<method>(事务代码SE37)。

2.BAPI更新

BAPI内部则通常不包含COMMIT WORK和ROLLBACK WORK,在BAPIs里多数情况

下不使用COMMIT / ROLLBACK WORK语句来修改数据库的数据,而是调用BAPI的Object

BapiService。在BAPI内部,数据库更新操作必须通过同步或异步更新过程实现,BAPI内部

也不触发新的 LUW,因此内部程序代码不包含 CALL TRANSACTION、SUBMIT REPORT

和SUBMIE REPORT AND RETURN。

多个BAPI操作需要遵循以下原则:

■ 当有更新、修改、删除一个业务对象实例时,对实例进行另外读取操作的 BAPI 只能

访问上一个COMMIT WORK 执行后的最新数据。

■ 不允许在一个LUW中创建一个新实例,然后再修改它。

■ 可以创建多个相同对象类型的不同实例。

BAPI事务中的数据库提交和回滚:

■ 必须通过调用SAP 标准业务对象BapiService的BAPI方法bapiservice.transactioncommit

和bapiservice.transactionrollback实现。

■ 利用远程调用函数:bapi_transaction_commit和bapi_transaction_rollback实现。

在外部调用bapiservice.transactioncommi方法前,外部程序调用BAPI并不触发数据库提

交,RFC一旦建立,即外部程序登录SAP系统后,就一直保持连接。

3.BAPI调用特点

BAPI调用完全从属于RFC的调用特性,支持RFC的本地调用及远程调用。

■ 支持Remote Function Call(RFC)。

■ 它被分配为Business Object Repository 中SAP Business Object 的一个方法。

■ 没有Exception 捕捉。

■ BAPI调用是否成功是通过参数RETURN返回有关信息的。RETURN用于BAPI返回

错误和成功的消息,它可以是BAPIRETURN、BAPIRETURN、BAPIRET1、BAPIRET2

和BAPIRET2_FIX中的任意一种类型。

4.BAPI的使用范围

■ 用VB/JAVA/C++等语言编写非SAPGUI程序访问和处理SAP数据。

■ SAP不同部件之间通讯。

22 6

第 235 页 / 共 377 页

■ 通过 SAP Business Connector或 Internet Application Components 与 Internet程序

集成。

5.JCO实例做成

与RFC的Java调用一样,下载SAP JAVA CONNECTORS软件(sapjco.jar)及动态连接库

sapjcorfc.dll,其中DLL文件一定要放到系统路径下,XP系统中一般是C:\WINDOWS\system32。

安装Java开发工具Eclipse,双击快捷图标或按照安装路径启动Java编辑工具。

步骤一:启动Java编辑器,按照以下路径创建Java工程,如图3-208所示。

图3-208

工程属性设定如图3-209所示。

图3-209

227

第 236 页 / 共 377 页

单击 按钮,编译环境设置如图3-210所示。

图3-210

选择Libraries标签页,在配置库中添加JCo组件,单击 按钮,如图3-211

所示。

图3-211

22 8

第 237 页 / 共 377 页

单击对话框中的 按钮,设置结果如图3-212所示。

图3-212

单击 按钮,创建工程后按照以下路径创建Java包,如图3-213所示。

图3-213

229

第 238 页 / 共 377 页

包名设定如图3-214所示。

图3-214

单击 按钮,按照以下路径为包添加Java类,如图3-215所示。

图3-215

23 0

第 239 页 / 共 377 页

Java类属性设定如图3-216所示。

图3-216

单击 按钮,编辑代码如下:

package TestBapi;

import com.sap.mw.jco.IFunctionTemplate;

import com.sap.mw.jco.JCO;

import java.util.Properties;

public class ConnectSAPServer {

public static void main(String[] args) {

/*获得一个到SAP系统的连接 START */

Properties logonProperties = new Properties();

logonProperties.put("jco.client.ashost","192.168.90.12"); //系统的IP地址

logonProperties.put("jco.client.client","000"); //要登录的客户端

logonProperties.put("jco.client.sysnr","00"); //系统编号

logonProperties.put("jco.client.user","bcuser"); //登录用户名

logonProperties.put("jco.client.passwd","minisap"); //用户登录口令

//用上述条件创建一个连接对象

JCO.Client myConnection = JCO.createClient( logonProperties );

/*获得一个到SAP系统的连接 END */

myConnection.connect(); //进行实际连接

//如果连接不为null并且处于活动状态

231

第 240 页 / 共 377 页

if (myConnection != null && myConnection.isAlive()) {

//从连接获得一个逻辑意义上的“仓库”对象(Repository)

JCO.Repository myRepository =

new JCO.Repository("Repository", //只是一个名字

myConnection); //活动的连接

//要调用的SAP函数名称

String strFunc = "Z_BAPI_GET_TEST";

//从“仓库”中获得一个指定函数名的函数模板

IFunctionTemplate ft = myRepository.getFunctionTemplate(strFunc.toUpperCase());

//从这个函数模板获得该SAP函数的对象

JCO.Function function = ft.getFunction();

//获得函数的import参数列表

JCO.ParameterList input = function.getImportParameterList();

/*设定个别参数 START */

//设定一个import参数的值。参数名为“MAX_ROWS”,设定值为10

//input.setValue(10, "MAX_ROWS");

/*设定结构参数 START */

//如果参数是一个结构,用参数名获得一个对应类型的结构对象

JCO.Structure sFrom = input.getStructure("IMPARAM");

//设定结构中的变量。

sFrom.setValue("1A", "CLASS");

sFrom.setValue("2009", "YEAR");

//将处理好的结构赋给该参数

input.setValue(sFrom, "IMPARAM");

/*设定结构参数 END */

/*设定table参数 START */

//用参数名获得一个对应类型的内部表对象

//JCO.Table tDateRange = function.getTableParameterList().getTable("DATE_RANGE");

//新增一条空行

//tDateRange.appendRow();

//定位到第0行

//tDateRange.setRow(0);

//设定该行对应变量

//tDateRange.setValue("I", "SIGN");

//tDateRange.setValue("EQ", "OPTION");

//tDateRange.setValue("20040330", "LOW");

//新增一条空行

//tDateRange.appendRow();

//定位到第1行

23 2

第 241 页 / 共 377 页

//tDateRange.setRow(1);

//设定该行对应变量

//tDateRange.setValue("I", "SIGN");

//tDateRange.setValue("EQ", "OPTION");

//tDateRange.setValue("20040427", "LOW");

//......

/*设定table参数 END */

//执行函数

myConnection.execute(function);

//在执行函数后可用相同方式获得输出结果

JCO.Table tests = function.getTableParameterList().getTable("TESTDATA");

//JCO.Table对象可以直接输出到html文件

tests.writeHTML("C:/function.html");

//也可以如下单独获得表中个别变量

System.out.println("班级" + "\t"

+ "学年" + "\t"

+ "学生番号" + "\t"

+ "姓名" + "\t"

+ "语文成绩" + "\t"

+ "数学成绩" + "\t"

+ "自然成绩" + "\t"

+ "思品成绩");

for (int i = 0; i < tests.getNumRows(); i++) {

tests.setRow(i);

System.out.println(tests.getString("ZZCLASS") + "\t"

+ tests.getString("ZZYEAR") + "\t"

+ tests.getString("ZZSTDNO") + "\t"

+ tests.getString("ZZNAME") + "\t"

+ tests.getDouble("ZZTENKOK") + "\t"

+ tests.getDouble("ZZTENSAN") + "\t"

+ tests.getDouble("ZZTENRIK") + "\t"

+ tests.getDouble("ZZTENSHA"));

}

//断开连接

myConnection.disconnect();

} else {

System.out.println(false);

}

}

}//:~

注:大多数的JCO包的版本密码会被变成大写后再发送到SAP处验证,因为较新版本的

SAP对密码的大小写是敏感的。所以SAP用户的密码如果包含有字母的话,要注意密码的兼

容性,要么全是数字,要么全是大写,才能成功连接。

233

第 242 页 / 共 377 页

步骤二:准备测试数据,如图3-217所示。

图3-217

步骤三:编译并按以下路径运行程序,如图3-218所示。

图3-218

运行结果如图3-219所示。

图3-219

23 4

第 243 页 / 共 377 页

生成htm文件内容如图3-220所示。

图3-220

235

第 244 页 / 共 377 页

第 4 章 增 强

增强(Enhancement)的概念其实很广,SAP标准系统中的所有二次开发都可以理解为增

强。做增强的原因是标准的SAP业务系统不能满足实际需求,所以在标准的系统基础上增加

不同的功能来达到不同企业的要求,换句话说今天开发过程中所有的ADD-ON都可以说是增

强开发。

但开发人员所说的增强主要是标准系统事先预留好的接口,根据不同业务需求来进行开

发,称为增强,又叫出口(EXIT)。

4.1 概述

在 SAP 系统设计中,增强被定义为程序执行到最后必经的一段程序。为什么会有出口呢?

因为正常的业务系统不能满足实际需求,这时可以在出口中增加一些功能,来达到要求。

在SAP中出口就是标准程序最后要调用的一个函数或者功能模块,这个函数或功能模块

的输入已经由SAP定义好了。

用户写的SAP出口程序在系统升级的时候会被保留,而如果更改标准程序在SAP系统升

级的时候则会被覆盖。

下面介绍一下什么时候需要使用出口以及出口的种类:

■ 在业务检查时:比如在某个工厂发货,可以设定在某个库位的出货只能使用某种移动

类型。

■ 在需要界面增强时:比如用户对某个字段要求大写,但是最终用户不按规范操作,这

也可以在出口中自动转换,有些模块甚至能自定义数据库字段,并且可以在出口中增

加字段输入。还有的模块能对输入数据检查,甚至实现自动替代等功能。

■ 有不规则业务时:比如按某种条件定价,可以设定从自己定义的表中按某种条

件取值。

■ 搜索帮助的出口,可以对SAP标准的搜索帮助做权限控制等。

4.1.1 第一代增强

SAP 的增强发展至今已有四代,第一代增强基于源代码,是 SAP 提供一个空代码的子

过程。在这个子过程中用户可以添加自己的代码,控制自己的需求。这类增强都需要修改

SAP 的标准代码,它们在发布的时候都是空的,集中在一些文件名倒数第二个字符为 Z 的

包含程序中。由于是在标准程序中,所以所有程序的全局数据都可以使用,但同时系统升级

时会被新版本覆盖;这种源代码增强和屏幕增强的说明可以从事务码SPRO后台配置中相关

模块的路径里面找到;一般是以 UserExit_打头的子模块,可形象地称其为用户出口,如

图 4-1所示。

23 6

第 245 页 / 共 377 页

图4-1

找到所要增强的程序,查找 UserExit_关键字。例如上图中 MV50AFZ1 里的

user_exit_save_document。大部分SD内的出口都是这种形式的。

查找此类出口的方法:

■ 在增强程序中查找第二个字符为Z的Include包含程序。

■ 在后台查找对应模块增强;在程序中搜索 USEREXIT_打头的关键字子程序;在 SAP

中以PERFORM的形式被调用。

■ 字节列出对象列表“Display Object List”按钮,在子程序列表下查找“UserExit”打头

的子程序,如图4-2所示。

图4-2

这类增强事先要到SAP的Service Market Place申请对象键(Access Key),然后才能修改

子程序,如图4-3所示。

237

第 246 页 / 共 377 页

图4-3

这种出口据说是第一代的用户出口,它们 Include 在 SAP 标准程序的源代码里,可以说

它们是源代码的一部分,更改这种出口就相当于更改SAP标准程序,是需要申请对象键才能

更改的,不需要建立工程。很多以ZZ或者Z结尾的Include标准程序里都有以UserExit_开始

的子程序,例如上面 mv50afz1 里的 user_exit_save_document。大部分 SD 的出口里,都是这

种形式的(Form)。由于子程序中带有关键字UserExit,故被称为User Exits(用户出口)。与

第二代增强相比,User Exit只能在SAP应用程序中添加功能,不能定义自己的菜单、屏幕及

关键字处理。

4.1.2 第二代增强

第二代增强(基于函数模块的增强)用事务SAP 增强管理(事务代码:SMOD)和增强

编辑器(事务代码:CMOD)维护。在SAP发布的版本中,使用Call Customer-Function ‘xxx’

调用函数模块,所以可以通过在程序中搜索Customer-Function来查找第二代增强,第二代增

强函数名构成为 Exit_程序名_’xxx(3 digital number)’。它们在发布的时候只有一句代码

include“zxxxxxxx”,修改时无需像第一代增强一样申请对象键(Access key),直接按两次

<Enter>键就可以了。但同时这种增强以及后面几代的增强都不能像第一代一样随便使用程序

的全局数据,只能使用接口中传递进来的参数。由于带有关键字Customer,故被称为Customer

Exits(客户出口)。

第二代增强主要有4类:

■ E. Ehancement exits:这些出口以Exit_打头,可以在SE37中查看,也可以在数据字典

TFDIR(函数表)中查询Exit_打头的函数。

■ C.GUI codes(GUI增强):用于区域菜单和工具菜单栏的增强。

■ S.Subscreens(屏幕增强):用于子屏幕设计增强。

■ T.include structure增强:用于表结构的增强。

还有一种按照用途分类的标准:

■ 功能模块出口(Function Module Exits):在 SAP 标准事务中添加业务逻辑,一般用

于验证标准事务中的字段。

■ 屏幕出口 (Screen Exits):定义自己的子屏幕用以嵌入应用屏幕,在标准事务中添加

子屏幕。

23 8

第 247 页 / 共 377 页

■ 菜单出口(Menu Exits):定义自己的菜单项或激活屏蔽标准事务中的菜单项。

■ 表出口(Table Exits):与上节中的T型出口一样,属同一类型。

■ 数据元素出口(Data Element Exits):在ABAP/4字典的关键字数据元素中添加文档。

结果是在使用这些数据元素的字段处按<F1>键后会出现自定义的说明文档。

■ 关键字出口(Keyword Exits):在ABAP/4字典中的关键字数据元素更改表示文本。

■ 字段出口(Field Exits):根据ABAP/4字典中域验证某些标准事务的某些屏幕字段。

注:RZ10配置系统参数,并重启应用服务器,如图4-4所示。

图4-4

1.Enhancement比较重要的表

■ MODSAP:这个表里重要的字段增强名(Name)、组件类型(TYPE:ECST)、组件

功能模块名(Member)里面记录了所有Enhancement的增强。

■ TFDIR:所有的函数表、重要字段 FuncName(函数名)、功能模块激活状态 MAND

(如果是C,代表此函数模块激活)。

■ TSDIR:动态程序区 CALL CUSTOMER SUBSCREEN(屏幕增强)。

■ CUATEXTS:修改 GVI 界面,菜单文本被客户改变(GUI 菜单文本增强)。

■ MODSAPA:SAP扩展的属性。

■ MODATTR:SAP增强项目属性。

■ TADIR:资源库对象的目录。

■ TFTIT:函数功能的短文本。

2.查找Enhancement的方法

(1)查找关键字

在程序中搜索 Customer-function,找到后面的 3 位数字后缀,然后出口函数组成就是 Exit_

程序名_3 位数字后缀。

(2)代码查找增强

利用如下代码查找Enhancement(有些Exit并不能找到):

*----------------------------------------------------------------------*

*

239

第 248 页 / 共 377 页

* Program ID :ZENHANCEMENT_FIND_EXIT

* Program Description :增强点查询

* Create User :BCUSER

* Create Date :2011/02/20

*

*----------------------------------------------------------------------*

* Function Overview

* 程序实现以事务代码为参照进行交互式查询.

* 技术点:动态下载报表,结构体嵌套

*

*----------------------------------------------------------------------*

* Change List :

* change NO. Change Date Change User Change Detail

* 0000001 2011/02/20 BCUSER 创建程序

*----------------------------------------------------------------------*

REPORT ZENHANCEMENT_FIND_EXIT

NO STANDARD PAGE HEADING.

*----------------------------------------------------------------------*

* TABLES:

*----------------------------------------------------------------------*

TABLES : TSTC, "SAP 事务代码

TADIR, "资源库对象的目录

MODSAPT, "SAP增强-短文件

MODACT, "修正

TRDIR, "系统表 TRDIR

TFDIR, "功能模块

ENLFDIR. "功能模块的附加属性

TABLES : TSTCT. "事务代码文本

*----------------------------------------------------------------------*

* DATA

*----------------------------------------------------------------------*

* 资源库对象的目录内表

DATA : JTAB LIKE TADIR OCCURS 0 WITH HEADER LINE.

DATA : CURSOR_FIELD(30). "CURSOR字段

* 传输组织器的开发类

DATA : V_DEVCLASS LIKE TADIR-DEVCLASS.

*----------------------------------------------------------------------*

* PARAMETERS

*----------------------------------------------------------------------*

* 事务代码

PARAMETERS : P_TCODE LIKE TSTC-TCODE OBLIGATORY.

*----------------------------------------------------------------------*

*START-OF-SELECTION

*----------------------------------------------------------------------*

START-OF-SELECTION.

* 事务代码取得

24 0

第 249 页 / 共 377 页

SELECT SINGLE * FROM TSTC WHERE TCODE EQ P_TCODE.

* 成功的场合

IF SY-SUBRC EQ 0.

* 资源库对象的目录取得

SELECT SINGLE * FROM TADIR

WHERE PGMID = 'R3TR' "请求和任务中的程序标识

AND OBJECT = 'PROG' "对象类型

AND OBJ_NAME = TSTC-PGMNA."对象目录中的对象名

MOVE : TADIR-DEVCLASS TO V_DEVCLASS.

* 失败场合

* 系统表 TRDIR取得

SELECT SINGLE * FROM TRDIR

WHERE NAME = TSTC-PGMNA.

* 程序类型为函数组的场合

IF TRDIR-SUBC EQ 'F'.

* 功能模块取得

SELECT SINGLE * FROM TFDIR

WHERE PNAME = TSTC-PGMNA.

* 功能模块的附加属性取得

SELECT SINGLE * FROM ENLFDIR

WHERE FUNCNAME = TFDIR-FUNCNAME.

* 资源库对象的目录取得

SELECT SINGLE * FROM TADIR

WHERE PGMID = 'R3TR'

AND OBJECT = 'FUGR'

AND OBJ_NAME = ENLFDIR-AREA.

MOVE : TADIR-DEVCLASS TO V_DEVCLASS.

ENDIF.

ENDIF.

* 资源库对象的目录取得

SELECT * FROM TADIR

INTO TABLE JTAB

WHERE PGMID = 'R3TR'

AND OBJECT = 'SMOD'

AND DEVCLASS = V_DEVCLASS.

* 事务代码文本

SELECT SINGLE * FROM TSTCT

WHERE SPRSL EQ SY-LANGU

AND TCODE EQ P_TCODE.

FORMAT COLOR COL_POSITIVE INTENSIFIED OFF.

* 输出事务代码

241

第 250 页 / 共 377 页

WRITE:/(19) '事务代码:', 20(20) P_TCODE, 45(50) TSTCT-TTEXT.

SKIP.

* 增强信息不为空的场合

IF NOT JTAB[] IS INITIAL.

WRITE:/(95) SY-ULINE.

FORMAT COLOR COL_HEADING INTENSIFIED ON.

* 增强列表表头

WRITE:/1 SY-VLINE,

2 '增强名',

21 SY-VLINE ,

22 '描述',

95 SY-VLINE.

* 增强列表明细

WRITE:/(95) SY-ULINE.

LOOP AT JTAB.

SELECT SINGLE * FROM MODSAPT

WHERE SPRSL = SY-LANGU AND

NAME = JTAB-OBJ_NAME.

FORMAT COLOR COL_NORMAL INTENSIFIED OFF.

WRITE:/1 SY-VLINE,

2 JTAB-OBJ_NAME HOTSPOT ON,

21 SY-VLINE ,

22 MODSAPT-MODTEXT,

95 SY-VLINE.

ENDLOOP.

* 增强列表表尾

DESCRIBE TABLE JTAB.

SKIP.

FORMAT COLOR COL_TOTAL INTENSIFIED ON.

WRITE:/ '增强个数:' , SY-TFILL.

* 增强信息为空的场合

ELSE.

FORMAT COLOR COL_NEGATIVE INTENSIFIED ON.

WRITE:/(95) '没有用户增强。'.

ENDIF.

* 失败的场合

ELSE.

FORMAT COLOR COL_NEGATIVE INTENSIFIED ON.

WRITE:/(95) '事务代码不存在!'.

ENDIF.

*----------------------------------------------------------------------*

* AT LINE-SELECTION

*----------------------------------------------------------------------*

24 2

第 251 页 / 共 377 页

AT LINE-SELECTION.

* 取得光标字段

GET CURSOR FIELD CURSOR_FIELD.

CHECK CURSOR_FIELD(4) EQ 'JTAB'.

SET PARAMETER ID 'MON' FIELD SY-LISEL+1(10).

` CALL TRANSACTION 'SMOD' AND SKIP FIRST SCREEN.

(3)利用系统函数寻找增强

常与出口相关的函数有:

■ DYNP_VALUES_READ。

■ MODX_ALL_ACTIVE_MENUENTRIES(菜单增强)。

■ MODX_FUNCTION_ACTIVE_CHECK(出口函数增强)。

■ MODX_MENUENTRY_ACTIVE_CHECK(菜单增强)。

■ MODX_SUBSCREEN_ACTIVE_CHECK(屏幕增强)。

可以在函数最后设置断点,然后通过运行对应的增强程序就会调用这样的函数,这样就

可以在调试模式下找到对应的增强。

注:出口的应用要在激活的状态下,也就是在 TFDIR 下的 MAND 字段为 C。激活的时

候要同时激活程序和出口函数。一般情况下,知道出口模块可以找到对应的增强,如果未激

活状态需要将其激活。

4.1.3 第三代增强

BADI是一个新的SAP增强技术,是基于ABAP的面向对象技术。它们可以被插入到SAP

系统,以适应用户由于行业的不同需要不同的功能以满足具体要求(包括在标准交付)。SAP

让客户在软件中预先确定这些点。

基于面向对象概念的增强 BADI(Business Add-in),源代码的发布是通过接口的方法调

用来实现使用的。用户增强实际上是实现一个或多个基于这个接口的实现类,因为接口类实

际上是一个抽象类,所以对同一个增强会出现不同的源代码,这些不同的源代码是通过过滤

器(Adapter)来区别用于不同的业务场景的。这种增强是用事务SE18和SE19来实现的。

SAP 预定义了一些接口(Interface),客户可以自行定义实现 Interface 的类(Class),在

标准程序中会使用调用客户自定义类(Class)的实例(Instance),获取实例的过程使用了工

厂模式,因此获取过程对用户是未知的。不过 BADI 也有一些局限性,就是有一些 Interface

是固定的,有的时候会发现需要Mix客户化代码的时候找不到Interface。

业务交易事件(BTE,Business Transaction Events)是SAP的一种增强方式,技术上讲是

介于第二代增强(Customer Exits)和BAdIs之间的产物。

BTE(Business Transaction Events)为会计模块独有的增强,这种增强用于财务会计模块

(Open FI)、总账会计(FI- GL)、应收账款和应付账款(FI-AR/FI-AP)及销售和分销(SD)

的组件。

BTE增强有2种类型,类似于会计凭证验证和替代。

■ Publish and Subscribe Interface:只提供SAP数据源,可以供外部程序使用或者达到数

243

第 252 页 / 共 377 页

据检查的目的。

用于告诉外部软件在SAP标准应用中触发了某些事件,并且把产生的数据提供给它们。

外部软件不能给R/3系统返回任何数据,可以用在以下地方。

● 主数据被创建、修改或锁定。

● 凭证被输入、预制、修改或冲销。

● 项目被清除或重置。

也可以在附加的开发中基于此事件和数据产生附加的处理:

● 启动工作流。

● 产生或修改附加数据。

● 请求通信。

■ Process Interface:可以达到数据修改的目的,用来增强标准的业务流程。

用于控制与标准R/3系统处理方法不同的业务流程,也就是用Process Interface替换标准

处理。它们干预标准流程,并返回数据给SAP应用。

1.第二代增强(Customer exits)和BTE的不同之处

Customer exits只有SAP和Customer两方参与流程,SAP提供软件交付给最终客户,客

户可以用Customer exits对标准功能进行增强;BTE则更面向组件,有多方参与流程。流程中

所有的参与者都可能是增强的用户和提供者。由于Customer exits只能使用一次,不能满足需

求,因此SAP在4.0版本中开发了新的增强技术,并允许重复使用。

Open FI基于以下逻辑,应用程序开发者必须定义某个函数的接口。应用时,一个分配用

的表被读取,被分配的程序被自动调用。

Customer exits这种技术不同于其他增强的是,它只允许有一个实施的增强,但是可以按

照需求和一定顺序调用多个已实现的增强。可以特定行业和特定国家增强,这可以很容易地

通过/定制业务的需求,其中SAP不提供标准的功能,只能通过定制或改进。

BTE即OPEN FI此功能主要是用于FI催款和信用管理,例如在SAP的标准催款功能中,

根据Partner Function发送付款通知,以Partner为基础,根据原始凭证的金额,可以发送相同

的通知文档。

2.BADI和BTE的不同之处

BTE同BADI的技术实现基本上是一致的,然而,这两个增强技术各不相同,体现在以

下几点:

■ Open FI仅限于代码增强,而不能像BADI一样对用户界面进行增强。

■ Open FI只会在3个层面上进行(SAP—合作伙伴—客户),而BADI加载项可以实现

各个软件层的增强。

■ Open FI使用函数进行增强,而BADI则使用面向对象实例化的方法进行增强。

3.BADI的查找方法

BADI的查找方法有以下几种:

■ BADI对象的信息存储在SXS_INTER、SXC_EXIT、SXC_CLASS和SXC_ATTR这4

个表中(参见SECE包)。

■ SAP BADI程序都会调用cl_exithandler=>get_instance来判断对象是否存在,并返回实

例,这个方法实际就是对上面4个表以及视图V_EXT_IMP和V_EXT_ACT进行查询

24 4

第 253 页 / 共 377 页

和搜索的。可以在这个方法处设置断点,获取实例。

■ 它的调用方式是call method(instance),可以通过exit_handler关键词来查找。

■ 基于以上机理使用性能分析器(事务代码ST05)选择“table buffer trace”而不是常用

的“SQL trace”,然后查找上面的几个表和视图找到对应的BADI。

■ 使用SE24进入Class Builder,查看对象CL_EXITHANDLER,进入其get_instance方

法,为get_class_name_by_interface设置断点。Debug需要增强的事务,在断点处查看

class_name即可找到对应的BADI。

■ se18 查找接口,se19 实现接口就可以实现用户增强。

4.BTE的查找方法

BTE的查找方法有以下两种:

■ 运行事务码(例如XK02),选择“System→Status”,双击“Program (screen)”,选中“In

main program”,查找“OPEN_FI_PERFORM”字符串。

■ IMG→财务会计全局设置(新)→工具→客户增强→业务事务事件(FIBF),选择“环境”。

4.1.4 第四代增强

第四代其实是第三代的加强Switch Framework。当SAP进入NetWeaver 7.0以后推出的新增

强体系,将BADI进行了改进,叫新BADI。还新增了Enhancement Spot、Enhancement Section 以

及隐式增强点的概念,基本可以在面向对象的程序里实现处处皆可增强的最高境界。

SAP 应用 Switch Framework 的主要目的是采用标准系统中的一个或多个行业的解决方

案,以简化基于ABAP的系统框架。Switch Framework允许客户通过使用交换机框架,对所

有的行业解决方案中的资源库对象或对象的组件的可见性进行外部控制。客户不再需要安装

一个行业解决方案,可以在需要时激活相关组件。

在程序中查找字符串Enhancement,即可以在指定的位置进行增强。

4.2 第一代增强的应用

User Exits 是 SAP 第一代增强技术,其技术原理就是在程序中预先放 置一个

Form...EndForm的子程序,并在事物运行时Call这个Form。如果这个Form是空的,则不执

行任何操作,否则,执行相应的操作。User Exits的写法和修改标准程序是一致的,要向SAP

申请Access Key才能对这些程序进行修改。它与修改标准程序的区别在于在SAP做升级的时

候,User Exits会自动保留,标准程序如果不做特殊处理,就会被覆盖。

在做这样的增强时,一般把所要添加的代码都写在以 Z 开头的函数中,然后在 Form 中

调用这个函数。由于该方法作用有限,本书不做举例介绍。

4.3 第二代增强的应用

4.3.1 数据元素及关键字

可以在CMOD->GoTo->Text enhancements->Data elements/Keywords路径中做字典文档的

增强,如图4-5所示。

245

第 254 页 / 共 377 页

图4-5

数据元素用以增强与其关联的文档帮助,关键字用于增强数据元素关联的文本标

签。由于客户很少在这个层面上弃用 SAP 的标准功能,作用也比较有限,这里不做举

例说明。

4.3.2 字段增强

字段增强技术基于数据元素(Data Element),如果屏幕的输入框参考了该数据元

素,定义激活字段增强(Field Exit)后,程序响应一块函数代码,可以触发该字段增

强逻辑。

技术上来讲有点像Customer Exits,两者都是通过Function来实现出口的,但是其原理和

用途又有很大不同,而且Field Exits SAP在4.6之后就不再支持了。因此如果要在后续版本中

使用,需要增加系统参数abap/fieldexit = YES,然后重新启动SAP。

■ 可以在SE38里运行程序RSMODPRF来寻找已经存在的Field Exits,同时也可以进入

Field Exits的管理界面。

■ 可以在CMOD界面中输入事务PRFB,也可以进入Field Exits的管理界面。

新建一个Field Exits时,只要有相应的Data Element在数据库中存在,就能建立出针对

这个Data Element的Field Exits。同时会生成一个FIELD_EXIT_开头的Function,用以做相应

的增强。里面有两个参数,Input和Output,这两个参数是固定的,不能修改。Input是将屏幕

字段的值传入出口程序,而Output则是传出。

例如,对用户进行维护(SU01),只允许 SAP* 和 DDIC 实现用户的维护,其他用户没

有权限进行维护。

步骤一:找出用户这个输入字段的数据元素,如图4-6所示。

步骤二:执行程序 RSMODPRF,不输入任何参数,进入字段增强的主界面,如图 4-7

所示。

24 6

第 255 页 / 共 377 页

图4-6

图4-7

步骤三:按照以下路径创建新的字段增强,如图4-8所示。

图4-8

输入要增强的数据元素XUBNAME,如图4-9所示。

图4-9

系统会自动创建一个以FIELD_EXIT_开头的函数,用以做相应的增强,如图4-10所示。

247

第 256 页 / 共 377 页

图4-10

单击 按钮,如图4-11所示。

图4-11

输入函数组及描述,单击 按钮。

FUNCTION FIELD_EXIT_XUBNAME.

*"----------------------------------------------------------------------

*"*"Local interface:

*" IMPORTING

*" REFERENCE(INPUT)

*" EXPORTING

*" REFERENCE(OUTPUT)

*"----------------------------------------------------------------------

DATA: M_STRING TYPE STRING.

CONCATENATE '用户名:' SY-UNAME '无维护权限!'

INTO M_STRING.

IF SY-UNAME <> 'YIDATEC' AND SY-UNAME <> 'DDIC' AND SY-UNAME <> 'SAP*' .

MESSAGE M_STRING TYPE 'A'.

ENDIF.

ENDFUNCTION.

单击标准工具栏上的“保存”按钮 ,如图4-12所示。

图4-12

单击标准工具栏上的“检查”按钮 ,如图4-13所示。

图4-13

24 8

第 257 页 / 共 377 页

单击标准工具栏上的“检查”按钮 ,如图4-14所示。

图4-14

单击标准工具栏上的检查按钮 退回至管理画面,如图4-15所示。

图4-15

步骤四:激活新建的字段增强。

选中新建的字段增强,按照以下路径激活,如图4-16所示,效果如图4-17所示。

图4-16

图4-17

注:上述字段增强是对所有程序的增强,只要程序用到数据元素XUBNAME,那么都会

触发。在这里单击 按钮,可以将增强绑定到某个程序,如图4-18所示。

图4-18

249

第 258 页 / 共 377 页

步骤五:测试新建的字段增强,如图4-19所示。

图4-19

此类出口程序中,以下ABAP语句是受限制的:

■ CALL SCREEN、CALL DIALOG、CALL TRANSACTION、SUBMIT。

■ COMMIT WORK、ROLLBACK WORK。

■ COMMUNICATION RECEIVE。

■ EXIT FROM STEP-LOOP。

■ MESSAGE I、MESSAGE W。

■ STOP、REJECT。

所以也给出口的功能带来了限制。同时,调试在Field Exit会被忽略,这对纠错来说也是

一个不利因素,只能做单元测试,而不能做集成测试。要将 Field Exits 做得更细,那就要给

它分配程序及其对应的屏幕号。

4.3.3 GuiXT增强

在一个事务中,事务变式和屏幕变式是可以一起做的。当制作事务变式的时候,默认也

会做一个事务初始屏幕的变式;但是想改变屏幕的布局,就要用到GuiXT了。

GuiXT是一个第三方的软件,可以用来对SAP的界面进行修改,包括登录界面。

实例:事务SE11用来维护数据字典,现在需要一与之相仿的事务来维护数据库表。

步骤一:处理变式的维护(第一画面)。

通过事务代码SHD0 进入事务和屏幕变式创建工具,如图4-20所示。

图4-20

25 0

第 259 页 / 共 377 页

输入Transaction Code :SE11,Transaction Variant:ZSE11TABLE,然后单击工具栏中的

按钮或者按<F5>键。

注:此处Transaction Variant变式名称必须以Z或Y开头。

图4-21

步骤二:处理变式的维护(第二画面)。

按<Enter>键弹出如图4-22所示的窗口将“Database table”以下的输入项隐藏。

图4-22

注: 用于屏蔽工具栏中的功能菜单。上述设定是将“Database table”以外

的选项去掉,而选项所在文本需将GuiTX Scripts隐藏。

步骤三:处理变式的维护(第二画面)。

单击右下角的 按钮,弹出脚本编辑窗口,填写代码隐藏文本如图4-23所示。

注:上述代码是将“Database table”以外的文本去掉,并改变三个按钮的位置,具体应

用请参照GuiTX Scripts相关资料。

单击 按钮或按<Enter>键。

脚本编辑完并确定后,右上角的GuiXT script已经被勾选,如图4-24所示。

251

第 260 页 / 共 377 页

图4-23

图4-24

步骤四:处理变式的维护(第二画面)。

单击右下角的 按钮,保存GuiTX,如图4-25所示。

图4-25

25 2

第 261 页 / 共 377 页

步骤五:处理变式的维护(第二画面)。

单击标准工具栏中的“保存”按钮 ,保存处理变式,如图4-26所示。

图4-26

单击上图中的“保存”按钮 ,效果如图4-27所示。

图4-27

按<F3>键返回到事务屏幕变式创建屏幕,如图4-28所示。

图4-28

步骤六:处理变式的维护(第一画面)。

按照以下路径创建变式事务,如图4-29所示。

图4-29

编辑事务如图4-30所示,单击 按钮。

步骤七:处理变式的维护(第一画面)。

编辑处理事务如图4-31所示。

253

第 262 页 / 共 377 页

图4-30

图4-31

单击图4-31中的“保存”按钮 ,如图4-32所示。

图4-32

单击图4-32中的“保存”按钮 ,效果如图4-33所示。

25 4

第 263 页 / 共 377 页

图4-33

步骤八:测试事务变式。

在命令栏中输入事务SE11,效果如图4-34所示。

图4-34

4.3.4 表增强

对于透明表及结构的增强,主要有两种,一种是Append Structure,另一种就是Include形式。

Append Structure可以扩展原来的表结构,但并不是在原来的表上加字段,而是再建一个

附加的结构,物理上,数据是保存在两处的。而且,一个Append Structure只能有一张表结构。

如果把有Append Structure结构的表进行复制的话,那么在新的表中,原有的Append Structure

就变成了固定字段,物理表也变成了一张。

Include格式多见于由于增强而自动生成的表字段,比如做屏幕增强的字段。当然,也可

以自定义。相比Append Structure,Include可以包含多张表结构(Include的Data Elements可

以Append Structure)。它不具有Append Structure的复制性能,即使复制,还是会以原结构存

在于新表中。

做完增强后,如果想所加字段也出现在 SM30 表维护中,则需要通过以下路径生成表维

护程序:SE11→进入相应表,并做完增强→Utilities→Table Maintenance Generator。

如果要反复更改增强,比如改变某一字段的长度,那么在减少字段时,需用SE14进行物

理表的修改,否则无法激活。

实例:透明表SFLIGHT08是航班信息表,现在想将飞行员及误餐的信息加进去,增强前

表结构如图4-35所示。

图4-35

255

第 264 页 / 共 377 页

步骤一:ABAP字典(编辑画面)。

显示 SAP 标准表 SFLIGHT08,单击应用工具栏中的 按钮,如图 4-36

所示。

图4-36

单击上图对话框中的 按钮,弹出如下对话框,如图4-37所示。

图4-37

在上图中“Append Name”栏中输入构造体“ZSFLIGHT08”,单击对话框中的 按钮。

步骤二:ABAP字典(编辑画面)。

编辑构造体ZSFLIGHT08,如图4-38所示。

图4-38

注:构造体ID必须以Z 或Y作为头字母。

按照以下菜单路径将其激活,如图4-39所示。

图4-39

25 6

第 265 页 / 共 377 页

弹出以下对话框,如图4-40所示。

图4-40

单击上图中的 按钮,如图4-41所示。

图4-41

选中单选按钮“Can be enhanced(character-type or numeric)”选项并单击 按钮。

注:各选项说明如下:

Cannot be enhanced:该结构必须不被增强。

Can be enhanced or character type:所有的结构组件和它们的增强必须是字符类型(C、N、

D、T)。包括原有的结构和所有增强功能,通过自定义或附加结构受这个限制。

Can be enhanced or character-type or numeric:结构和它的增强必须不包含任何深度的数据

类型(表格、参考文献、字符串)。

Can be enhanced in any way:结构和它的增强可能包含的数据类型可以是任何类型的组件。

Not classified:该类别可以选择,例如对于一个过渡状态。但是,它不能被选择用于创建结构。

步骤三:ABAP字典(编辑画面:保存、检查及有效化)。

单击标准工具栏中的“保存”按钮 ,如图4-42所示。

图4-42

257

第 266 页 / 共 377 页

单击上图中的“保存”按钮 ,效果如图4-43所示。

图4-43

单击应用工具栏中的“检查”按钮 ,如图4-44所示。

图4-44

单击标准工具栏中的“有效化”按钮 ,如图4-45所示。

图4-45

单击上图中的 按钮,如图4-46所示。

图4-46

步骤四:测试新建表增强,使用事务 SE16,单击应用工具栏中的 按钮,显示结果

如图4-47所示。

25 8

第 267 页 / 共 377 页

图4-47

4.3.5 函数增强

函数增强即代码增强,是指利用代码完成某项功能,一般和其他增强共同完成某项业务需要。

实例:事务BC425_08是用来预定航班的,想实现在预定“AA”航班时给出提示信息。

步骤一:SAP增强项目管理器(第一画面)。

在项目处输入要建立的工程名,单击画面中的 按钮,如图4-48所示。

图4-48

编辑工程描述,如图4-49所示。

图4-49

259

第 268 页 / 共 377 页

步骤二:SAP增强项目管理器(第一画面:保存工程)。

单击标准工具栏中的“保存”按钮 ,如图4-50所示。

图4-50

单击上图中的“保存”按钮 ,效果如图4-51所示。

图4-51

步骤三:单击 按钮,编辑增强点,如图4-52所示。

图4-52

步骤四:保存组件。

单击标准工具栏中的“保存”按钮 ,如图4-53所示。

图4-53

步骤五:选中增强点,单击 按钮,编辑增强组件,如图4-54所示

图4-54

26 0

第 269 页 / 共 377 页

步骤六:双击 组件,编辑增强代码,如图4-55所示。

图4-55

双击文件 ,提示警告信息,如图4-56所示。

图4-56

按<Enter>键弹出如下提示窗口,如图4-57所示

图4-57

单击 按钮,如图4-58所示。

图4-58

261

第 270 页 / 共 377 页

单击上图中的“保存”按钮 ,编辑Include文件,如图4-59所示。

图4-59

步骤七:保存、检查及有效化Include文件。

单击标准工具栏中的保存按钮 ,如图4-60所示

图4-60

单击应用工具栏中的“检查”按钮 ,如图4-61所示。

图4-61

单击应用工具栏中的“有效化”按钮 ,如图4-62所示。

图4-62

步骤八:激活工程组件。

单击标准工具栏中的“后退”按钮 ,退回至如图4-63所示画面,单击应用工具栏中的

“有效化”按钮 ,如图4-64所示。

图4-63

图4-64

步骤九:激活工程。

单击标准工具栏中的“后退”按钮 ,退回至第一画面,单击应用工具栏中的“有效化”

按钮 ,如图4-65所示。

图4-65

26 2

第 271 页 / 共 377 页

步骤十:测试增强结果,运行事务代码 BC425_08,输入参数并按<Enter>键,结果如

图4-66所示

图4-66

4.3.6 菜单增强

菜单增强是指利用标准菜单中留下的接口新增相应的其他功能,一般和代码增强共同完

成某项业务需要。

实例:事务BC425_08是用来预定航班的,想实现此画面来查询相关历史信息。

步骤一:SAP增强项目管理器(第一画面)。

在项目处输入要建立的工程名,单击画面上的 按钮,如图4-67所示。

图4-67

编辑工程描述,如图4-68所示。

图4-68

263

第 272 页 / 共 377 页

步骤二:SAP增强项目管理器(第二画面:保存工程)。

单击标准工具栏中的“保存”按钮 ,如图4-69所示。

图4-69

单击上图中的“保存”按钮 。

步骤三:单击 按钮,如图4-70所示。编辑增强点并单击标准工具栏中的“保

存”按钮 保存组件,如图4-71所示。

图4-70

图4-71

步骤四:选中增强点,单击 按钮,编辑增强组件,单击 按钮切换到变更

状态,如图4-72所示。

图4-72

双击 ,编辑菜单如图4-73所示。

26 4

第 273 页 / 共 377 页

图4-73

注:此处的编辑方式与菜单编辑器中的编辑方式一致。

Function text:功能菜单项的文本描述。

Icon:功能菜单项的图标。

Icontext:功能菜单项的图标描述。

Info.text:功能菜单项的提示信息,用于鼠标单击前提示。

单击 按钮,如图4-74所示。

图4-74

输入传输请求,单击 按钮。

步骤五:为菜单项设置功能。

双击 ,编辑菜单赋予的功能代码,如图4-75所示。

图4-75

265

第 274 页 / 共 377 页

双击Include程序 ,提示警告信息如图4-76所示。

图4-76

按<Enter>键弹出如下提示窗口,如图4-77所示。

图4-77

单击 按钮,结果如图4-78所示。

图4-78

单击上图中的“保存“按钮 ,编辑Include文件如图4-79所示。

图4-79

26 6

第 275 页 / 共 377 页

步骤六:保存、检查及有效化Include文件。

单击标准工具栏中的“保存“按钮 ,如图4-80所示。

图4-80

单击应用工具栏中的“检查“按钮 ,如图4-81所示。

图4-81

单击应用工具栏中的“有效化“按钮 ,如图4-82所示。

图4-82

步骤七:激活工程组件。

单击标准工具栏中的“后退”按钮 ,退回至如图4-83所示画面,单击应用工具栏中的

“有效化”按钮 ,如图4-84所示。

图4-83

图4-84

步骤八:激活工程。

单击标准工具栏中的“后退”按钮 ,退回至第一画面,单击应用工具栏中的“有

效化”按钮 ,如图4-85所示。

图4-85

步骤九:测试增强结果,运行事务代码 BC425_08,选中以下增强菜单路径,如图 4-86

所示。

267

第 276 页 / 共 377 页

图4-86

显示结果如图4-87所示。

图4-87

4.3.7 屏幕增强

屏幕增强是指利用标准屏幕中留下的字屏幕新增相应的其他项目,一般和代码增强共同

完成某项业务需要。

实例:事务BC425_08是用来预定航班的,想实现此画面中更多的信息。

步骤一:SAP增强项目管理器(第一画面)。

在“Project”文本框中输入要建立的工程名,单击画面上的 按钮,如

图 4-88所示。

图4-88

编辑工程描述,如图4-89所示。

26 8

第 277 页 / 共 377 页

图4-89

步骤二:SAP增强项目管理器(第二画面:保存工程)。

单击标准工具栏中的“保存”按钮 ,如图4-90所示。

图4-90

单击上图中的“保存”按钮 ,如图4-91所示。

图4-91

步骤三:单击 按钮,如图4-92所示。编辑增强点并单击标准工具栏中的“保

存”按钮 保存组件,如图4-93所示。

图4-92

269

第 278 页 / 共 377 页

图4-93

步骤四:选中增强点,单击 按钮,编辑增强组件,单击 按钮切换到变更状

态,如图4-94所示。

图4-94

双击 ,编辑屏幕如图4-95所示。

图4-95

单击上图中的 按钮,编辑属性页签如图4-96所示。

图4-96

单击 按钮,编辑如图4-97所示。

27 0

第 279 页 / 共 377 页

图4-97

屏幕元素生成如图4-98所示。

图4-98

单击标准工具栏中的“保存”按钮 ,如图4-99所示。

图4-99

单击上图中的“保存”按钮 ,如图4-100所示。

图4-100

双击屏幕字段 ,弹出提示窗口,如图4-101所示。

图4-101

271

第 280 页 / 共 377 页

单击 按钮,如图4-102所示。

图4-102

按<Enter>键或单击上图中的 按钮,如图4-103所示。

图4-103

按<Enter>键或单击上图中的 按钮,创建Include文件,如图4-104所示

图4-104

单击上图中的“保存”按钮 ,如图4-105所示。

图4-105

编辑Include文件,如图4-106所示,并单击标准工具栏中的“保存”按钮 保存文件,

如图4-107所示。

27 2

第 281 页 / 共 377 页

图4-106

图4-107

单击应用工具栏中的“检查”按钮 ,如图4-108所示。

图4-108

单击应用工具栏中的“有效化”按钮 ,如图4-109所示。

图4-109

单击标准工具栏中的“后退”按钮 ,退回至屏幕编辑画面,单击应用工具栏中的

“检查”按钮 ,如图4-110所示。

图4-110

单击应用工具栏中的“有效化”按钮 ,如图4-111所示。

图4-111

步骤五:为屏幕赋值设置功能。

双击 ,编辑屏幕赋值的功能代码,如图4-112所示。

图4-112

273

第 282 页 / 共 377 页

双击Include程序 ,提示警告信息,如图4-113所示。

图4-113

按<Enter>键弹出提示窗口,如图4-114所示。

图4-114

单击 按钮,如图4-115所示。

图4-115

单击上图中的“保存”按钮 ,编辑Include文件,如图4-116所示。

图4-116

步骤六:保存、检查及有效化Include文件。

单击标准工具栏中的“保存”按钮 ,如图4-117所示。

图4-117

27 4

第 283 页 / 共 377 页

单击应用工具栏中的“检查”按钮 ,如图4-118所示。

图4-118

单击应用工具栏中的“有效化”按钮 ,如图4-119所示。

图4-119

步骤七:激活工程组件。

单击标准工具栏中的“后退”按钮 ,退回至如图4-120所示画面,单击应用工具栏中

的“有效化”按钮 ,如图4-121所示。

图4-120

图4-121

步骤八:激活工程。

单击标准工具栏中的“后退”按钮 ,退回至第一画面,单击应用工具栏中的“有效化”

按钮 ,如图4-122所示。

图4-122

步骤九:测试增强结果,运行事务代码 BC425_08,输入查询条件并按<Enter>键,如

图4-123所示。

图4-123

275

第 284 页 / 共 377 页

4.4 第三代增强的应用

BAD(I Business Add-Ins)是SAP在R/3 release 4.6A后增加的增强技术。总的来说,BAdIs

克服了之前出口的所有缺点,并且用最新的面向对象技术实现,可谓是万千宠爱于一身。不

过在项目中,用BAdIs的顾问还是比较少,多数是用Customer Exit和User Exit完成。

其实,BADI就是综合了SAP 之前一些增强技术的优点,在标准程序预留了出口,通过

面向对象的接口技术,使增强更加灵活。一个出口可以有多个实现,但是一个client只有一个

是起作用的。通过实验发现它是按创建的先后顺序及是否 active 来判断的。不过一般一个实

现就够了,只能说SAP的技术架构确实是比较先进。

下面来举个例子说明一下。

4.4.1 BADI增强

实例:事务BC425_CHNG08是用来更改预定航班的,想用BADI增强实现此画面中的更

多信息。

步骤一:按照以下路径新建程序,如图4-124所示。

图4-124

注:此处增强一般有两种方式。

■ 用“Module pool”类型的程序。

■ 用函数组作为增强的程序。

输入文件名并附Top选项如图4-125所示。

图4-125

27 6

第 285 页 / 共 377 页

按<Enter>键或单击上图中的 按钮,创建Top Include文件如图4-126所示。

图4-126

按<Enter>键或单击上图中的 按钮,编辑程序属性如图4-127所示。

图4-127

按<Enter>键或单击上图中的 按钮,如图4-128所示。

图4-128

按<Enter>键或单击上图中的 按钮,如图4-129所示。

277

第 286 页 / 共 377 页

图4-129

步骤二:编辑Top Include文件,保存、检查及有效化Include文件,如图4-130所示。

图4-130

单击标准工具栏中的保存按钮 ,如图4-131所示。

图4-131

单击应用工具栏中的检查按钮 ,如图4-132所示。

图4-132

单击应用工具栏中的有效化按钮 ,如图4-133所示。

图4-133

步骤三:创建屏幕、编辑、保存。

按照以下路径创建屏幕,如图4-134所示。

图4-134

27 8

第 287 页 / 共 377 页

输入屏编号如图4-135所示。

图4-135

按<Enter>键或单击上图中的 按钮,编辑屏幕属性如图4-136所示。

图4-136

编辑屏幕布局如图4-137所示。

图4-137

生成屏幕元素如图4-138所示。

图4-138

279

第 288 页 / 共 377 页

编辑屏幕控制逻辑如图4-139所示。

图4-139

单击标准工具栏中的保存按钮 ,保存编辑屏幕,如图4-140所示。

图4-140

主程序生成如下:

*&---------------------------------------------------------------------*

*& Module Pool ZTESTBADI

*&

*&---------------------------------------------------------------------*

*&

*&

*&---------------------------------------------------------------------*

INCLUDE ZBADITOP . " global Data

INCLUDE ZBADIO01 . " PBO-Modules

INCLUDE ZBADII01 . " PAI-Modules

Top文件源码编辑如下:

*&---------------------------------------------------------------------*

*& Include ZBADITOP Module Pool ZTESTBADI

*&

*&---------------------------------------------------------------------*

PROGRAM ZTESTBADI.

TABLES: SFLIGHT08.

DATA: ZPLIOT LIKE SFLIGHT08-ZPLIOT,"Name of pilot

ZMEAL LIKE SFLIGHT08-ZMEAL."Main meal of a flight

DATA: R_VAR TYPE REF TO IF_EX_BC425_08FLIGHT2."Business Add-In Interface IF_EX_BC425

_99FLIGHT2

28 0

第 289 页 / 共 377 页

PBO模块GET_INSTANCE_0901编辑如下:

*----------------------------------------------------------------------*

***INCLUDE ZBADIO01 .

*----------------------------------------------------------------------*

*&---------------------------------------------------------------------*

*& Module GET_INSTANCE_0901 OUTPUT

*&---------------------------------------------------------------------*

* IF Inintial

*----------------------------------------------------------------------*

MODULE GET_INSTANCE_0901 OUTPUT.

CALL METHOD CL_EXITHANDLER=>GET_INSTANCE_FOR_SUBSCREENS

CHANGING

INSTANCE = R_VAR

EXCEPTIONS

NO_REFERENCE = 1

NO_INTERFACE_REFERENCE = 2

NO_EXIT_INTERFACE = 3

DATA_INCONS_IN_EXIT_MANAGEM = 4

CLASS_NOT_IMPLEMENT_INTERFACE = 5

OTHERS = 6.

IF SY-SUBRC <> 0.

MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

ENDIF.

ENDMODULE. " GET_INSTANCE_0901 OUTPUT

PBO模块GET_DATA_0901编辑如下:

*&---------------------------------------------------------------------*

*& Module GET_DATA_0901 OUTPUT

*&---------------------------------------------------------------------*

* Get Data From PGM

*----------------------------------------------------------------------*

MODULE GET_DATA_0901 OUTPUT.

CALL METHOD R_VAR->GET_DATA

IMPORTING

E_FLIGHT = SFLIGHT08.

ZPLIOT = SFLIGHT08-ZPLIOT.

ZMEAL = SFLIGHT08-ZMEAL.

ENDMODULE. " GET_DATA_0901 OUTPUT

PAI模块PUT_DATA_0901编辑如下:

*----------------------------------------------------------------------*

281

第 290 页 / 共 377 页

***INCLUDE ZBADII01 .

*----------------------------------------------------------------------*

*&---------------------------------------------------------------------*

*& Module PUT_DATA_0901 INPUT

*&---------------------------------------------------------------------*

* Put Data to PGM

*----------------------------------------------------------------------*

MODULE PUT_DATA_0901 INPUT.

SFLIGHT08-ZPLIOT = ZPLIOT.

SFLIGHT08-ZMEAL = ZMEAL.

CALL METHOD R_VAR->PUT_DATA

EXPORTING

I_FLIGHT = SFLIGHT08.

ENDMODULE. " PUT_DATA_0901 INPUT

步骤四:检查并有效化程序。

按照以下路径检查程序,如图4-141所示,其效果如图4-142所示。

图4-141

图4-142

按照以下路径激活程序,如图4-143所示,其效果如图4-144所示。

28 2

第 291 页 / 共 377 页

图4-143

图4-144

步骤五:运行增强实装事务(事务代码:SE19),创建增强实例。

填写要增强的BADI,单击 按钮,如图4-145所示。

图4-145

填写实装实例名称如图4-146所示。

图4-146

283

第 292 页 / 共 377 页

按<Enter>键或单击上图中的 按钮,编辑实例描述,如图4-147所示。

图4-147

单击标准工具栏中的保存按钮 ,保存编辑实例,如图4-148所示。

图4-148

按<Enter>键或单击上图中的 按钮,如图4-149所示。

图4-149

按<Enter>键或单击上图中的 按钮,如图4-150所示。

图4-150

28 4

第 293 页 / 共 377 页

步骤六:编辑增强实例。

选中 标签页,如图4-151所示。

图4-151

双击 方法,编辑如图4-152所示。

图4-152

单击标准工具栏中的保存按钮 ,保存实例方法,如图4-153所示。

图4-153

单击应用工具栏中的检查按钮 ,如图4-154所示。

图4-154

单击应用工具栏中的有效化按钮 ,如图4-155所示。

图4-155

单击应用工具栏中的回退按钮 至实例编辑页面,双击 方法,编辑如图 4-156

所示,并对方法保存、检查及有效化。

285

第 294 页 / 共 377 页

图4-156

选中 标签页,编辑子屏幕属性如图4-157所示。

图4-157

步骤七:保存、检查及有效化增强实例。

单击标准工具栏中的保存按钮 ,如图4-158所示。

图4-158

单击应用工具栏中的检查按钮 ,如图4-159所示。

图4-159

单击应用工具栏中的有效化按钮 ,如图4-160所示。

图4-160

步骤八:测试增强结果,运行事务代码BC425_CHNG08,输入查询条件并按回车键,如

图4-161所示。

图4-161

28 6

第 295 页 / 共 377 页

4.4.2 BTE增强

BTE(Business Transaction Events)是 SAP的一种增强方式,技术上讲是介于Customer

Exits和BADI的产物。

它主要有两种类型的接口:

1.P/S函数模块:

■ 一个事件触发时,允许开始一个或多个附加操作,它们不影响标准的R/3程序。

■ 多个操作相互不影响。

■ 附加开发的组件只能从SAP导入数据。

■ 可能使用附加的检查,例如权限、查重等。

2.处理函数模块:

■ 会发生双向的数据交换,因此限制了一个接口可以附加开发的组件个数。

■ 事件触发时,一个标准处理流程只能被一个外部流程所替换。

■ 对于一个process interface,如果你使用SAP合作伙伴附加开发的组件,运行时会使用它

的增强;如果后来对此process interface使用自己开发的组件,在运行时将会用此增强替

换合作伙伴的。

BTE 增强比较核心的理念是使一个接口重复利用,完成多种实现并且互不干扰。而技术

实现的时候,就采用在标准程序中Call固定的一个function,然后再用这个function动态调用

自己定义的增强function,从而达到预期目的。

这样的接口,在标准程序中常常是以OPEN_FI_PERFORM_或者OUTBOUND_CALL_开

头的函数。由于采用这种技术架构,SAP 就使这些接口分为 Made by SAP、Made by SAP's

Partner和Made by SAP's Customer,三方可以各取所需。

至于Publish and Subscribe Interface和Process Interface的区别,主要还是体现在用途上。

前者是给外部软件提供信息的,而后者主要用于 R/3 流程。不过前者也可以生成或修改一些

additional data。

BTE主要用于总账,应收、应付和销售分销模块。

实例:事务FB01是用来创建凭证的,想用BTE增强实现凭证各项被分配给某个固定字符串。

步骤一:按照以下路径IMG Menu Path:Financial Accounting→Financial Accounting Global

Settings→Business Transaction Events或运行事务:FIBF,如图4-162所示。

图4-162

287

第 296 页 / 共 377 页

按照以下路径查询BTE,如图4-163所示。

图4-163

输入查询条件,单击 按钮,如图4-164所示。

图4-164

选中BTE过程,单击 按钮,如图4-165所示。

图4-165

单击应用工具栏中的拷贝按钮 ,如图4-166所示。

图4-166

弹出如图4-167所示画面。

28 8

第 297 页 / 共 377 页

图4-167

单击上图中的 按钮,如图4-168所示。

图4-168

注:执行此步需先创建函数组,如图4-169所示。

图4-169

编辑新拷贝的函数,单击 按钮,如图4-170所示。

图4-170

编辑代码如图4-171所示,并将其保存、检查至有效化。

289

第 298 页 / 共 377 页

图4-171

步骤二:单击 按钮返回至 BTE 初始画面,按照以下路径定制 BTE 产品,如图 4-172

所示。

图4-172

单击应用工具栏中的 按钮,如图4-173所示。

图4-173

编辑定制BTE产品信息如图4-174所示。

图4-174

29 0

第 299 页 / 共 377 页

单击标准工具栏中的保存按钮 ,如图4-175所示。

图4-175

按<Enter>键或单击上图中的 按钮,如图4-176所示。

图4-176

步骤三:单击 按钮返回至 BTE 初始画面,按照以下路径定制 BTE 过程,如图 4-177

所示。

图4-177

单击应用工具栏中的 按钮,如图4-178所示。

图4-178

编辑定制BTE过程信息如图4-179所示。

图4-179

单击标准工具栏中的保存按钮 ,如图4-180所示。

291

返回ABAP参考资料列表