SAP开发规范.docx
《SAP开发规范.docx》由会员分享,可在线阅读,更多相关《SAP开发规范.docx(27页珍藏版)》请在冰豆网上搜索。
SAP开发规范
SAP开发规范
1说明
1.1内容说明
开发规范总的包含了以下三方面的内容
《SAP开发规范》,即本文档,主要内容为:
说明开发中要注意的事项
代码编写的规范
开发中要遵循的规则
性能有关的例子
《SAP开发命名规范》,主要为开发过程中涉及的命名规则
涉及开发中的命名,统一命名规则,方便程序的沟通、阅读
1.2规范目的
提高SAP项目中开发的效率、质量,实现标准化管理
1.3使用说明
在客户有开发规范的情况下,请按照客户的开发规范进行开发
如客户未有现成的开发规范,请按照公司的开发规范进行开发
请确保在开发的时候遵循了以下规则,如模糊不清时,请及时重新查阅。
如有冲突的地方,请与项目上的开发负责人进行确认
1.4使用对象
任何在SAP系统进行开发的人员
初学ABAP开发者
2一般规则
以下为开发过程必须遵守的一般规则,请遵守。
请严格按照《SAP开发命名规范》进行相关命名
请遵循《SAP项目管理流程》来进行开发及开发管理
在开发完成后,在开发系统中清除不需要的对象
不可随便修改SAP源代码,除非是客户化字段、用户出口等
若确实需修改SAP源代码,请与技术负责人确认,并进行严格记录、测试
在程序中不要遗留下没有使用的变量,可以使用”ExtendedProgramCheck”进行检查
当有文本输出时,通过维护文本符号来实现。
使用文本符号方便翻译
使用常数来代替固定数值或固定字符
常数必须定义为全局的。
优点:
可重复使用,只需修改一个地方
请不要在代码中对组织架构(公司代码、工厂、采购组织等)的数据赋予固定值,组织架构的值可通过参数(Parameter)、选择范围(Select-options)、变式等方式来传值
不要使用TABLES语句定义的数据结构,使用专门定义的工作区
TABLES语句只用于Select-options需要的时候
尽可能不要使用MOVE-CORRESPONDING语句,因为比较耗时
在SQL语句执行完成后、内表操作语句执行完成、调用完函数等之后,检查返回码sy-subrc的值,并做判断处理
一般情况下为一个程序创建一个对应的请求,以防传输时混乱
慎用ABAP中的宏,因为宏不易维护且不可调试
所有的开发的程序必须分配对应的事务代码,从而可避免给用户分配SA38或SE38的权限
原则上一个程序的代码不能超过2000行,超过2000行请使用includeprogram确保可读性
3代码管理
在创建一般报表时,请拷贝报表模板程序,并在模板程序的基础上进行代码编写。
模板程序主要包括了程序标题格式、事件关键字等内容。
方便程序编写并统一规范。
3.1程序标题
每个程序标题必须包括了程序名称、程序名、开发日期、开发者、概要、变更记录(日期、变更者、传输请求号、修正内容)。
请参考以下例子:
例子
*----------------------------------------------------------------------*
* 程序名称:
程序名称
* 程序名:
ZZZ*_*
* 开发日期:
2012/MM/DD
* 创建者:
张三
* 申请者:
李四
*----------------------------------------------------------------------*
*概要:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
* XXXXXXXXXXXXXXXXXXXXXXXX
*----------------------------------------------------------------------*
* 变更记录
* 2012/ins-day By 张三(Hand) DEVK90000
* Description:
* 1.初始开发
*
* 2012/ins-day By 张三(Yahua) DEVK90010
* Description:
* 1.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
* 2.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*
*----------------------------------------------------------------------*
REPORT ZZZ*_*
NO STANDARD PAGE HEADING
LINE-SIZE 255
LINE-COUNT 65.
注意:
请将可能详细的维护好程序标题。
3.2子程序、模块标题
在子程序定义前面必须进行注释说明。
说明内容包含:
包括子程序名称、子程序功能描述、参数功能等。
模块与子程序类似。
子程序例子
*--------------------------------------------------------------------------------*
*FormGET_COMPANY_CODE_DESCRIPTION*
*---------------------------------------------------------------------------------*
*通过传入的公司代码,得到公司代码描述
*
*---------------------------------------------------------------------------------*
* 传入参数:
fu_bukrs为公司代码
*---------------------------------------------------------------------------------*
FORMget_company_code_descriptionUSINGfu_bukrsCHANGINGfu_butxt.
模块例子
*----------------------------------------------------------------------------------*
*MODULESET_PFSTATUSOUTPUT*
*----------------------------------------------------------------------------------*
*设置屏幕100的GUI状态*
*-----------------------------------------------------------------------------------*
MODULESET_PFSTATUSOUTPUT.
注意:
请将可能详细的维护子程序、模块的标题信息。
另:
原则上一个FORM的长度不能超过300行,如果超过300行,请尽量拆分为多个FORM,确保程序的可读性。
如:
要从10个表中取数,我们可以将其拆分为多个FORM,其中取文本表的单独一个FORM,当从某个表取字段过多(或者取出即有部分处理逻辑)时,我们甚至可以将其单独一个FORM。
3.3编辑器设置
为了使原代码更易于解读,规定对编辑器进行设置。
设置路径为:
SE38->实用程序(U)->设置(E)
编辑器:
设置使用新的编辑器、每行最长72个字符长(注:
抓图为ECC6.0例子,其它版本请以实际为主)
“规范化打印机(prettyprint)”设置:
缩进、关键字大写
3.4代码格式
3.4.1使用规范化打印机
要求在代码编写完成后,点
来格式化代码,使代码自动缩进、关键字大写等,在编写代码过程中使用该按钮,也有助于发现输入错误的语句。
注意:
如果规范化打印机不可用,则手工的调整代码,使代码结构化。
3.4.2查询SQL语句的写法
OpenSQL请按如下格式对齐,有助于阅读和查看
SELECTfield1“xxx
field2“xxx
INTOTABLEit_mara
FROMMARA
WEREmatnr=wa_tab-matnr.
SELECT,INTO,FROM等缩进两空格
WHERE缩进一空格
字段field1,field2每个都进行换行,并在字段名后注释其意义
3.5变更记录管理
当程序传到生产机之后,开始进行变更管理。
变更管理开始后,进行程序的修改时要注意以下:
在程序的开始处的变更记录上记录以下内容
日期修改者传输请求号修改内容及原因
例子
*----------------------------------------------------------------------*
* 变更记录
* 2012/ins-day By 张三(Hand) DEVK90000
* Description:
* 1.初始开发
*
* 2012/ins-day By 张三(Yahua) DEVK90010
* Description:
* 1.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
* 2.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*
*----------------------------------------------------------------------*
在修改的程序代码处,要通过类似如下注释包括起修改的内容
****2012/01/08张三 规格变更 Chg 修改开始
* 修改原因:
*
****2012/01/08 张三 规格变更 Chg 修改结束
例子1
****2012/01/08 张三 规格变更 Ins 修改开始
* 修改原因:
*
****2012/01/08 张三 规格变更 Ins 修改结束
例子2
****2012/01/08 张三 规格变更 Del 修改开始
* 修改原因:
*
****2012/01/08 张三 规格变更 Del 修改结束
修改标识
意义
Ins
新增
Chg
修改
Del
删除
注意:
在删除代码时,只是注释,不要实际物理的删除代码。
3.6代码注释
数据声明和程序的逻辑部分必须要有注释,逻辑部分的注释尽量控制在整个程序代码的10%~20%左右。
特殊的标记字段要在注释中说明其用法
根据项目语言使用情况选择用中文或英文进代码注释和文档说明
在初次提交的代码中不要保留初注释掉的代码行
在涉外的开发项目中,注释和说明要用英文
3.7子程序与函数模块
程序中的代码要尽量实现模块化,即如果程序中多个地方将会用到相同的代码,那么将这些代码封装在子程序中,以便可以随时调用,同时也增加了程序的可读性和可维护性
当相同的功能的代码可以被多个程序使用时,最好定义成函数模块
避免调用外部程序中的子程序
3.8其它注意事项
在每一个程序行中,最多只有一个语句,避免一条程序行中包含多条语句的写法。
4数据库查询
在使用SELECT语句中,尽可能把握以下几个原则:
尽可能的在Where条件中包含多的索引字段作为条件
Where条件中的索引字段按表中的索引顺序排列
尽可能的在Where条件中包含多的条件,即使字段不是索引的
4.1不要在Loop循环中使用Select语句
在循环中使用Select语句将会频繁的访问表,尽量减少数据库访问的操作。
以下语句是不建议的。
LOOPATit_tabINTOwa_tab.
SELECT*
FROMMARA
INTOTABLEit_mara
WEREmatnr=wa_tab-matnr.
ENDLOOP.
4.2取数的时候不能使用Select……Endselect语句循环操作
例:
错误
正确
SELECT*
FROMdbtab
MOVE-CORRESPONDINGdbtabTOit_ab
APPENDit_tab
ENDSELECT.
SELECT*
FROMdbtab
INTOTABLEitab.
注意:
必须避免嵌套的Select,因为每条记录将连接一次数据库。
4.3尽量多使用内表
为了提高程序的性能,通常先把数据库表中的数据取到内表中,在内表进行数据处理。
减少重复访问相同数据表的情况。
例:
(错误)(正确)
4.4Select与Select*比较
尽可能使用SELECT来代替SELECT*,减少数据传输量,当数据量大时,前者速度会明显更快。
例:
不建议写法
建议写法
SELECT*
FROMdbtab
INTOTABLEit_tab
WHERE.
SELECTfield1
field2
FROMdbtab
INTOTABLEit_tab
WHERE.
仅用于某种特殊情况时,如表的字段数很少或数据记录不多
当表中包含的大量字段时
使用Select虽然会增加代码的工作量,但会减少内存的使用及网络的负担
4.5外部检查
尽可能避免使用SelectCOUNT(*)来确认表存在的记录数,因为该语句将会对表进行全扫描。
4.6Selectsingle语句使用注意
当使用SelectSingle时,要求在where条件语句中包含所有的关键字
当不能确定所有关键字而能确定只有一条记录匹配时,可使用'Select...upto1rows'来查询
4.7Select语句中排序与ABAP语句中排序比较
对数据排序有两种方式:
一种为在数据库服务器中排序;一种为在应用服务器中排序。
不建议写法
建议写法
SELECTfield1
field2
FROMdbtab
INTOTABLEit_tab
WHERE.
ORDERBYfield1.
SELECTfield1
field2
FROMdbtab
INTOTABLEit_tab
WHERE.
SORTit_tabBYfield1.
应用服务器排序更快
4.8Selectdistinct语句使用
不建议写法
建议写法
SELECTDISTINCTfield
FROMdbtab
INTOTABLEit_tab
WHERE.
SELECTfield
FROMdbtab
INTOTABLEit_tab
WHERE.
SORTit_tabBYfield1.
DELETEADJACENTDUPLICATESFROMit_tabCOMPARINGfield.
需要在数据库服务器进行排序,且会影响整个系统性能如果没有合适的索引
使用DISTINCT语句时,数据库服务器经常不访问缓存
.尽可能避免在SELECT语句中使用GROUPBY,ORDERBY,DISTINCT等功能。
4.9批量更新数据库表
在更新数据库数据时,可以一条一条记录的更新,也可批量的更新多条记录。
当更新记录数较多时,请采用批量更新的方式,有助于性能的提高。
不建议写法
建议写法
LOOPATit_tabINTOwa_tab.
……
UPDATEdbtabSETfield01=wa_tab-field01
WHEREfield2=wa_tab-field2.
ENDLOOP.
LOOPATit_tabINTOwa_tab.
……
ENDLOOP.
UPDATEdbtabFROMTABLEit_tab.
执行完成更新语句后,会有两个比较有用的系统变量值返回:
SY-SUBRC
为0时则所有记录都成功更新。
SY-DBCNT
该值为成功更新的记录数。
4.10ForAllEntries语句
说明:
ForAllEntries后紧跟的内表称为驱动内表。
在使用该语句时,驱动内表不能为空,若为空,则等价于无此条件,可能造成全表的检索。
所以,在使用ForAllEntries时,要先对驱动内表是否为空进行判断
在使用该语句前,尽可能保持少的驱动内表条目数,尽可能使驱动内表中的条目为唯一的(可先进行删除重复行等操作)。
这样可避免在数据库中进行了不必要的读取
避免使用该语句读取小的数据库表(如配置表),对于小的数据库表使用单独的SELECT语句将会更好
使用该语句时,尽可能的连接数据库表中的索引,否则将会重复的全表扫描,并注意按数据库表中的索引顺序来写Where语句
驱动内表与INTO后的内表不可以是同一个内表
4.11OpenSQL与NativeSQL比较
开发人员不准使用NativeSQL,如果非得使用,请与项目组技术负责人确认。
4.12表连接
表连接取数是在数据库服务器里进行的,可以减少数据在网络上的传输。
但是有一个缺点是表连接不使用应用服务器的缓存。
例子
SELECTvbak~auartvbap~matnr
INTOTABLEit_tab
FROMvbakASvbak
INNERJOINvbapASvbap
ONvbak~vbeln=vbap~vbeln
WHEREvbelnINs_vbeln.
vbak为主表
vbap为副表
在where条件中必须有主表的关键字或索引
在where条件中尽可能的指定跟主表有关的条件
在某种情况下可以考虑建立对应的视图来代替表连接的使用
5内表使用注意
5.1内表定义
在定义内表时,建议先定义对应的类型,再定义内表。
TYPES:
BEGINOFty_company,
bukrsTYPEt001t-bukrs,“公司代码
txtnaTYPEt001t-txtna,“公司代码描述
ENDOFty_company.
DATA:
it_companyTYPESTANDARDTABLEOFty_company,
wa_companyTYPEty_company.
注意:
请避免使用带表头的内表,SAP将会废弃此荐功能,目前在面向对象编程中不支持带表头的内表。
5.2内表使用
5.2.1修改内表中的字段值
使用MODIFYit_tabTRANSPORTINGfield...WHERE
将可加快修改内表记录集的速度。
特别是在内表行中有嵌套内表时,该写法将可明显增加速度。
通过LOOP处理来修改所有的组件
内表的大量修改必须通过在LOOP循环中来实现
5.2.2把一个内表附加到另一个内表后面
例:
说明:
内表it_tab01和内表it_tab02有相同的行结构且包含一定的记录集。
错误写法
正确写法
LOOPATit_tab01INTOwa_tab.
APPENDwa_tabTOit_tab02.
ENDLOOP.
APPENDLINESOFit_tab01TOit_tab02.
通过LOOP循环实现内表的附加
通过APPENDLINESOF语句批量附加内表
5.2.3删除内表中重复行
先对一个内表按删除时比较的字段进行排序,再通过以下语句删除重复行。
DELETEADJACENTDUPLICATESFROMit_tabCOMPARINGfield...
5.2.4根据条件删除内表中的行
错误写法
正确写法
LOOPATit_tabINTOwa_tab.
IFwa_tab-filed=value.
DELETEit_tabINDEXsy-tabix.
ENDIF.
ENDLOOP.
DELETEit_tabWHEREfiled=value.
通过LOOP循环进行删除
通过WHERE语句进行删除
5.2.5内表是否为空的判断
错误写法
正确写法
DESCRIBETABLEit_tabLINESl_lines.
IFl_lines=0.
*内表为空
ENDIF.
IFit_tab[]ISINITIAL.
*内表为空
ENDIF.
5.2.6读取内表行
关键字读取
READTABLEit_tabINTOwa_tabWITHKEYfield=value.
关键字二分搜索读取
READTABLEit_tabINTOwa_tabWITHKEYfield=valueBINARYSEARCH.
索引读取
READTABLEit_tabINTOwa_tabWITHKEYfield=valueINDEXl_index.
*注意:
在使用二分搜索读取内表时,要先按关键字对内表进行排序
性能比较:
类型
性能比较
索引读取
最快
关键字二分搜索读取
较快
关键字读取
慢
使用原则:
当可以通过指定索引读取内表时,用指定索引读取
如若不能,则通过二分搜索进行读取
例:
不建议写法
LOOPATit_tab01INTOwa_tab01.
READTABLEit_tab02INTOwa_tab02WITHKEYfield=wa_tab01-field.
CHECKsy-subrc=0.
ENDLOOP.
通过内表关键字来连接两个表
建议写法
SORTit_tab02BYfield.
LOOPATit_tab01INTOwa_tab01.
READTABLEit_tab02INTOwa_tab02WITHKEYfield=wa_tab01-fieldBINARYSEARCH.
CHECKsy-subrc=0.
ENDLOOP.
通过使用关键字二分搜索来连接两个表
要对内表it_tab02先按字段field进行排序
5.2.7通过LOOPATit_tabASSIGNING循环内表
由于字符变量指向内存地址,此种方式比LOOPATit_tabINTOwa_tab方式快
适合于数据量大、需要循环处理的内表
在READ语句中也可以使用类似的字符变量。
注意:
使用此种方式请确保对字符变量有充分理解
在此种方式的内表循环中,不要再使用ASSIGN语句给指定其它的值
通过此种方式修改内表行的数据时,不要使用MODIFY语句
5.2.8通过平行光标来连接两个内表
方法一:
建议写法
SORTit_tab01BYfi