目录
前言:
每个SAP项目都会制定对应的开发规范以提高开发质量,同时也便于后续的运维、复用和升级工作。一个良好的开发习惯是我们每个码农应该具备的职业行为,可养成良好开发习惯的前提是你在每个项目上沉淀的一行行代码。所以每个项目都应具备全面、完善、尽可能相同的开发规范。这样对每个SAP开发从业者,每个项目,从长远来看,都有着巨大的益处。
1、公共标识符
一些公共标识符用在程序(对象)命名标准中。公共标识符以及它所附带的有效值将在以下列表中被规定。如果在命名程序中要用到公共标识符请在本节中查找。所有自定义的对象,都应用Z开头
1.1 SAP功能模块/应用
功能模块/应用 | 标识符 |
---|---|
财务会计 | FI |
管理会计 | CO |
资产管理 | AM |
资金管理 | TR |
物料管理 | MM |
销售与分销 | SD |
项目管理 | PS |
人力资源管理 | HR/HCM |
质量管理 | QM |
工厂维护/设备管理 | PM |
生产计划 | PP |
仓库管理 | WM |
运输管理 | TM |
客户服务 | CS |
合并报表 | BPC |
环境、健康、安全管理 | EHS |
产品生命周期 | PLM |
国际贸易管理 | GTM |
投资管理 | IM |
主数据治理/管理 | MDG |
扩展/高级仓库管理 | EWM |
详细排程 | PPDS |
治理、风险、合规 | GRC |
国际贸易服务/合规 | GTS |
客户关系管理 | CRM |
中央财务 | CFIN |
供应商管理 | SRM |
1.2 常用对象类型
对象类型 | 标识符 |
---|---|
报表 | RP |
WebService接口 | WS |
函数 | FM |
函数组 | FG |
透明表 | T |
结构 | S |
数据元素 | E |
数据域 | D |
表类型 | TT |
视图 | V |
CDS | CDS |
虚拟表(Virtual Table) | VT |
投影视图 | PV |
搜索帮助 | SH |
锁对象 | EZ开头 |
隐式增强 | EHI |
业务对象/类 | CL |
BADI | BADI |
Web Dynpro应用 | WD |
BSP应用 | BSP |
SMARTFORMS表单 | SF |
SMARTFORMS表单样式 | SFT |
AdobeForm表单 | AF |
AdobeForm界面 | AFS |
工作流 | WF |
ODATA | OD |
AMDP | AMDP |
文件模板 | TPL |
2、命名规范
2.1 事务代码
事务代码:SE93,对事务代码进行命名,名称和主程序名称保持一致。
X | XXXX | XXX |
---|---|---|
Z | 模块名 | 流水码 |
示例:ZMM0001
2.2 package
事务代码:se80,按模块区分,每个项目相关的开发使用模块统一的开发包
X | XXXXX |
---|---|
Z | 项目名 |
示例:ZHUAW1
2.3 消息类
事务代码:se91,按模块区分,每个模块相关的开发使用模块统一的消息类
X | XXXX |
---|---|
Z | 模块名 |
2.4 函数组
事务代码:se80,对函数组进行命名
X | XX | XXXX | XXXX |
---|---|---|---|
Z | FG | 模块名 | 流水码 |
示例:ZFGMM0001
2.5 函数
事务代码:se37,对函数进行命名,命名要反映函数的功能用途
X | XX | XXXX | XXXX |
---|---|---|---|
Z | FM | 模块名 | 流水码 |
2.6 SMARTFORMS表单 / 表单样式
事务代码:SMARTFORMS,对表单进行命名
X | XX | XXXX | XXX |
---|---|---|---|
Z | SF | 模块名 | 流水码 |
示例:ZFRMM001
对表单样式进行命名
X | XXX | XXXX | XXX |
---|---|---|---|
Z | SFT | 模块名 | 流水码 |
示例:ZSFTMM001
2.7 透明表
事务代码:se11,对透明表进行命名
X | X | XXXX | XXXX |
---|---|---|---|
Z | T | 模块名 | 流水码 |
示例:ZTMM0001
2.8 视图
事务代码:se11,对视图进行命名
X | X | XXXX | XXX |
---|---|---|---|
Z | V | 模块名 | 流水码 |
示例:ZVMM0001
2.9 CDS View
ADT中创建,对CDS View进行命名
X | XXX | XXXX | XXX |
---|---|---|---|
Z | CDS | 模块名 | 流水码 |
示例:ZCDSMM001
Extent CDS命名
N | XXX |
---|---|
CDS View Name | EXT |
示例:ZCDSMM001EXT
SQLView命名
X | XXX | XXXX | XXX |
---|---|---|---|
Z | SQL | 模块名 | 流水码 |
示例:ZSQLMM001
2.10 结构
事务代码:se11,对结构进行命名
X | X | XXXX | XXX |
---|---|---|---|
Z | S | 模块名 | 流水码 |
示例:ZSMM001
2.11 表类型
事务代码:se11,对表类型进行命名
X | XX | XXXX | XXX |
---|---|---|---|
Z | TT | 模块名 | 流水码 |
示例:ZTTMM001
2.12 搜素帮助
事务代码:se11,对搜素帮助进行命名
X | XX | XXXX | XXX |
---|---|---|---|
Z | SH | 模块名 | 流水码 |
示例:ZSHMM001
2.13 锁对象
事务代码:se11,对锁对象进行命名
XX | XXXX | XXX |
---|---|---|
EZ | 模块名 | 流水码 |
示例:EZMM001
2.14 数据元素
事务代码:se11,对数据元素进行命名
X | X | XXXXXXX |
---|---|---|
Z | E | 字段名(如自定义字段,不含开头Z) |
示例:ZEVBELN
2.15 数据域
事务代码:se11,对数据域进行命名
X | X | XXXXXXX |
---|---|---|
Z | D | 字段名(如自定义字段,不含开头Z) |
示例:ZDVBELN
2.16 自定义字段
事务代码:se11,透明表、结构、表类型等自定义字段命名
X | XXXXX | XX(可选) |
---|---|---|
Z | 字段名 | 流水码(可选) |
示例:ZDMBTR / ZDMBTR01
2.17 BADI
事务代码:se18 / se19,对BADI的命名
X | XXXX | N |
---|---|---|
Z | BADI(如实施对象为标准BADI,且标准以“BADI”开头,此项不必添加) | BADI功能描述(如实施对象为标准BADI,则按标准BADI名称,此项不必添加) |
示例:SO增强 ZBADI_SD_SALES_ITEM (BADI_SD_SALES_ITEM为标准BADI)
2.18 Adobe Form表单 / 界面
事务代码:sfp,对Adobe Form表单进行命名
X | XX | XXXX | XXX |
---|---|---|---|
Z | AF | 模块名 | 流水码 |
示例:ZAFMM001
对Adobe Form界面进行命名
X | XXX | XXXX | XXX |
---|---|---|---|
Z | AFS | 模块名 | 流水码 |
示例:ZASMM001
2.19 BSP应用
事务代码:se80,对BSP应用进行命名
X | XXX | XXXX | XXX |
---|---|---|---|
Z | BSP | 模块名 | 流水码 |
示例:ZBSPMM001
2.20 Web Dynpro 应用
事务代码:se80,对Web Dynpro应用进行命名
X | XX | XXXX | XXX |
---|---|---|---|
Z | WD | 模块名 | 流水码 |
示例:ZWDMM001
2.21 业务对象/类
事务代码:se24,对业务对象/类进行命名
X | XX | XXXX | XXX |
---|---|---|---|
Z | CL | 模块名 | 流水码 |
示例:ZCLMM001
2.22 隐式增强
事务代码:se38,对隐式增强进行命名
X | XXX | N | XX |
---|---|---|---|
Z | EHI | 增强所在程序名 | 流水码 |
示例:ZEHIMV45AFZZ01
2.23 投影视图
事务代码:se11,对投影视图进行命名
X | XX | XXXX | XXX |
---|---|---|---|
Z | PV | 模块名 | 流水码 |
示例:ZPVMM001
2.24 WebService接口
事务代码:se80,对WebService接口进行命名
X | XX | XXXX | XXX |
---|---|---|---|
Z | WS | 模块名 | 流水码 |
示例:ZWSMM001
2.25 报表
事务代码:se38,对报表进行命名
X | XX | XXXX | XXXX |
---|---|---|---|
Z | RP | 模块名 | 流水码 |
示例:ZRPMM0001
2.26 工作流
事务代码:swdd,对工作流进行命名
X | XX | XXXX | XXX |
---|---|---|---|
Z | WF | 模块名 | 流水码 |
示例:ZWFMM001
2.27 请求号
事务代码:se10,对请求号进行命名
XXXX | X | N | X | XXXXXXXXXXXX | X | XXXXXXXX |
模块名 | _ | 描述 | _ | 用户名 | _ | 年月日 |
示例:MM_采购订单增强_ABAP001_20230222
2.28 自定义事务代码
事务代码:se93,对自定义事务代码进行命名
X | XXXX | XXX |
---|---|---|
Z | 模块名 | 流水码 |
示例:ZMM001
2.29 ODATA
事务代码:segw,对ODATA进行命名
X | XX | XXXX | X | N |
---|---|---|---|---|
Z | OD | 模块名 | _ | 业务实体名称 |
示例:ZODSD_SALESORDER
2.30 AMDP
ADT中创建,对AMDP进行命名
X | XX | XXXX | XXX | XXXX |
---|---|---|---|---|
Z | CL | 模块名 | 流水码 | AMDP |
示例:ZCLMM001AMDP
2.31 文件模板
事务代码:smw0,对文件模板进行命名
N | X | XXXXX | X | XXX | X |
---|---|---|---|---|---|
程序名 | _ | 文件类型 | _ | TLP | 流水码 |
示例:ZRPMM001_EXCEL_TLP1
2.32 虚拟表 Virtual Table
ADT中创建,对虚拟表进行命名
X | XX | XXXX | XXX |
---|---|---|---|
Z | VT | 模块名 | 流水码 |
示例:ZVTMM001
3、编码规范
ABAP中使用DATA关键字声明变量名称时最多支持30个字符,选择屏幕和参数最多支持8个字符。当自定义变量有对应的SAP字段、数据元素时,应使用与之相同的名称。尽量参考使用SAP标准字段。
3.1 一般变量
描述 | 前缀 | 示例 |
---|---|---|
子程序(FORM) | FRM_<C>, Where C = description | FRM_GET_DATA |
全局内表(Internal table) | GT_<C>, Where C = description | GT_DATA |
局部内表 | LT<C>, Where C = description | LT_DATA |
全局工作区(Work area) | GW_<C>, Where C = description | GW_HEADER |
局部工作区 | WA_<C>, Where C = description | LW_HEADER |
常量(Constant) | CV_<C>, Where C = description | CV_NAME |
全局变量(Global variable) | GV_<C>, Where C = description | GV_MENGE |
选择屏幕选项(Select option) | S_<C>, Where C = description | S_MATNR |
选择屏幕参数(Parameters) | P_<C>, Where C = description | P_WERKS |
单选按钮(radio button) | R_<C>, Where C = description | R_ALV |
复选框 (check box) | C_<C>, Where C = description | C_LIST |
按钮 (Button) | B_<C>,Where C = description | B_SHOW |
区间范围(Range) | RA_<C>,Where C = description | RA_WERKS |
局部变量(Local Variables) | LV_<C>,Where C = description | LV_TEXT |
FORM中的变量 | PV_<C>,Where C = description | PV_MENGE |
FORM中的常量 | PC_<C>,Where C = description | PC_MENGE |
类型(Types) | TY_<C>,Where C = description | TY_EQUI |
函数的输入变量(Importing) | IV_<C>,Where C = description | IV_VBELN |
函数的输出变量(Exporting) | EV_<C>,Where C = description | EV_MENGE |
函数的更改变量(changing) | CV_<C>,Where C = description | CV_TAB |
函数的表(Table,输入) | IT_<C>,Where C = description | IT_TAB |
函数的表(Table,输出) | ET_<C>,Where C = description | ET_TAB |
函数的例外(Exception) | ER_<C>,Where C = description | ER_NO_AUTH |
3.2 其他细节
Screen No.屏幕号 | 4个字符,要求在9000-9999之间,屏幕增量为100 |
GUI Status | NNNN_XXX 8个字符,前4个为字符屏幕号,当一个状态被多个屏幕使用时,则加上后面XXX三位进行说明 |
PBO/PAI modules | XXXX_YYY_<C> X为屏幕号,Y为PBO/PAI,C为描述 |
Area Menu 区域菜单 | 6-8个字符,ZA_<C>,<C>为模块名或描述,最多为4位 |
Logical Database 逻辑数据库 | 8个字符,Z<F><C>,F为功能区域,C为描述 |
Memory Id 存储器地址 | 8-10个字符,ZMID_<C>,C为描述 |
Special Variables 特殊变量 | OKCODE |
Text Element 文体说明 | TEXT-XXX,X为流水码 |
Batch Job name | 20个字符以内,<S><A><F><C>;<S>表示系统,如开发:D,测试:Q,生产:P;<A>表示用户CLIENT端;<F>表示模块名;<C>表示描述 |
消息类型 | E:错误,W:警告,I:信息(弹窗),A:异常终止,S:成功 |
3.3 程序头
所有程序必须利用程序头作为程序的模版,描述程序的用途与需求提出者等,并维护程序被更改与维护的历史。示例:
***********************************************************************
* Program Name : *
* Program Title : *
* Application : *
* Description : *
* Func Spec ID : *
* Requested by : *
* Author : *
* Req Date : *
***********************************************************************
* MODIFICATIONS (latest entry at the top) *
* ------------------------------------------------------------------- *
* DATE NAME (COMPANY) DESCRIPTION TASK-NO *
* ---- ---- --------- ----------- ------- *
* *
* 20151022 XXX(IBM) 对运行效率进行优化 ZLDK914587 *
* 20151023 XXX(COFCO) 增强内表排序, ZLDD913025 *
* 删除重复记录 *
***********************************************************************
3.4 程序结构化
对于程序按逻辑功能分为不同的处理块,放在不同的事件代码中。报表大致为:
*&------------------------------------------------------------------*
*& INITIALIZATION
*&------------------------------------------------------------------*
initialization. 对程序输入变量初始化
*&------------------------------------------------------------------*
*& AT SELECTION-SCREEN
*&------------------------------------------------------------------*
at selection-screen. 对输入部分进行检查或权限检查部分
*&------------------------------------------------------------------*
*& START-OF-SELECTION
*&------------------------------------------------------------------*
start-of-selection. 程序主体,进行相关取数或逻辑运算部分
*&------------------------------------------------------------------*
*& END-OF-SELECTION
*&------------------------------------------------------------------*
end-of-selection. 进行输出部分
3.5 子程序模块
对于处理逻辑相对一致或可在程序内复用代码段来说,特别是多重IF语句的嵌套,应当运用Form。请使用如下结构:
*----------------------------------------------------------------------*
* FORM XXX_XXXXXX
*----------------------------------------------------------------------*
* & -> p1 text
* & <- p2 text
*
* Description
*----------------------------------------------------------------------*
FORM XXX_XXXXX using p1 changing p2.
ENDFORM. ‘XXX_XXXXXXX
3.6 Include程序
包含(Include程序)用于将大功能程序分解成多个小段,使得它更容易被维护和重用,Include程序命名遵从报表程序的规则。
3.7 定义段
数据定义建议按照如下的顺序:
- 表Tables
- 信息类型Infotypes
- 串定义和引入缓存Cluster definitions and import buffers
- 控制(只用于dialogue流程)Controls (for dialogue processing only)
- 类型组Type-groups
- 类型Types
- 常量Constants
- 简单数据类型Data (simple fields)
- 结构数据Data (structures)
- 内表以及其索引字段Data (internal tables and their index fields)
- 范围Ranges
- 字段符号Field-symbols
- 字段组Field groups (followed by INSERT into field-groups)
- 选择屏幕数据Selection screen data (for list processing only)
3.8 注释要求
3.8.1 定义的注释
定义变量、内表、工作区时,应注释其含义 或 用途
DATA: gw_filt TYPE lvc_s_filt . "ALV control: Filter structure
DATA: gt_filt TYPE lvc_t_filt. "ALV 控制: 筛选器条件表
DATA: BEGIN OF gw_output,
vbeln LIKE vbak-vbeln, "销售订单单号
posnr LIKE vbap-posnr, "销售订单行
ebeln LIKE ekpo-ebeln, "ISTO号
ebelp LIKE ekpo-ebelp, "ISTO行项目
matnr LIKE vbap-matnr, "订单行物料编码
kwmeng LIKE vbap-kwmeng, "订单数量
zdeliveryqty LIKE lips-lfimg, "已发货数量
zordertype(2) TYPE c, "单据类型
zbzirk LIKE t171t-bztxt, "销售区域
zvkbur LIKE tvkbt-bezei, "国家描述
zlag_pl LIKE ztsd083-zlag_pl_desc, "大产线
zyjqy(2) TYPE c, "一级区域
kunnr LIKE kna1-kunnr, "客户编码
k_name1 LIKE kna1-name1, "客户描述
dispo(22) TYPE c, "MRP控制者
zperid TYPE zperid, "实际货物移动年月
mtype LIKE t179t-vtext, "产品型号
END OF gw_output,
gt_output LIKE TABLE OF gw_output.
3.8.2 屏幕的注释
屏幕的控件应注释其对应的描述
SELECTION-SCREEN BEGIN OF BLOCK blk1 WITH FRAME TITLE TEXT-001. "搜素项
SELECT-OPTIONS: s_erdat FOR vbak-erdat. "创建日期
SELECT-OPTIONS: s_aedat FOR vbak-aedat. "更新日期
SELECT-OPTIONS: s_vbeln FOR vbak-vbeln. "订单号
SELECTION-SCREEN END OF BLOCK blk1.
3.8.3 ALV Fieldcatalog注释
ALV显示的字段描述,当使用了文本时,应在后面注释文本对应的描述
PERFORM fm_add_fieldcat USING 'ZOPID' TEXT-002 '' 'ZOPID' 'ZIOPT0001' '' '' '' '' ''. "Opportunity ID
PERFORM fm_add_fieldcat USING 'ZOPNAME' TEXT-003 '' 'ZOPNAME' 'ZIOPT0001' '' '' '' '' ''. "Opportunity Name
PERFORM fm_add_fieldcat USING 'ZOPTYPENAME' TEXT-004 '' 'ZOPTYPENAME' 'ZIOPT0001' '' '' '' '' ''. "Opportunity Type
3.8.4 程序的修改
当对现有程序作出修改时,请按照以下规则:
1. 在程序抬头的版本控制中添加一行修改日
***********************************************************************
* MODIFICATIONS (latest entry at the top) *
* ------------------------------------------------------------------- *
* DATE NAME (COMPANY) DESCRIPTION TASK-NO *
* ---- ---- --------- ----------- ------- *
* *
* 20090720 XXX(IBM) 对运行效率进行优化 LSDK914587 *
* 20090721 XXX(L&S) 增强内表排序, LSDK913025 *
* 删除重复记录 *
***********************************************************************
2. 当修改的内容含多行时,请使用以下方式进行注释,注意需要标注修改时使用的请求号:
* Start by 用户名 on 日期 for DEVK902007
Move v_discount to v_new_discount
WRITE: ...........….yyyyyyy……
WRITE: ………….xxxxxxx……
WRITE: ‘End of Report’
* End by 用户名 on 日期 for DEVK902007
3. 当对单行进行修改时,在代码后面标注对应的行为,标注使用的用户名、日期和请求号如下:
Move v_discount to v_new_discount " Added by 用户名 on 日期 for DEVK902007
WRITE: ...........….yyyyyyy…… " Modified by 用户名 on 日期 for DEVK902007
WRITE: ………….xxxxxxx…… " Added by 用户名 on 日期 for DEVK902007
WRITE: ‘End of Report’ " Deleted by 用户名 on 日期 for DEVK902007
3.8.6 Memory ID
如果在程序中有使用到Memory ID,需要注明提供方和消费方的程序 和 用途
1. 提供方
* 增强内调用BAPI修改PO时,不再触发邮件
FREE MEMORY ID 'ZPO_POSTD'. "该MEMORY ID被PO增强点:ZXM06U44消费
EXPORT a = 'X' TO MEMORY ID 'ZPO_POSTD'.
2. 消费方
* 增强内调用BAPI修改PO时,不再触发邮件
DATA: lv_flag_po_postd TYPE c.
CLEAR: lv_flag_po_postd.
IMPORT a = lv_flag_po_postd FROM MEMORY ID 'ZPO_POSTD'. "该MEMORY ID取自PO增强出口:ZCL_IM_ME_PURCHDOC_POSTED
FREE MEMORY ID 'ZPO_POSTD'.
3.9 代码的格式化
统一使用GUI端的程序美化器设置对应的代码格式化
3.10 ALV Fieldcatalog的参考表、字段
输出ALV的字段,应在Fieldcatalog指定引用/参考的表和字段
PERFORM fm_add_fieldcat USING 'ZOPID' TEXT-002 '' 'ZOPID' 'ZIOPT0001' '' '' '' '' ''. "Opportunity ID
PERFORM fm_add_fieldcat USING 'ZOPNAME' TEXT-003 '' 'ZOPNAME' 'ZIOPT0001' '' '' '' '' ''. "Opportunity Name
PERFORM fm_add_fieldcat USING 'ZOPTYPENAME' TEXT-004 '' 'ZOPTYPENAME' 'ZIOPT0001' '' '' '' '' ''. "Opportunity Type
4、代码质量规范
4.1 性能要求
- 使用SELECT查询数据表时,最多使用3个JOIN;
- 不在循环中嵌套使用SELECT语句;
* 不推荐 Loop at int_cntry. Select single * from zfligh into int_fligh where cntry = int_cntry-cntry. Append int_fligh. Endloop. * 推荐 IF int_cntry[] is not initial. Select * from zfligh into table int_fligh For all entries in int_cntry Where cntry = int_cntry-cntry. ENDIF.
- 不使用SELECT.....END SELECT语句;
* 不推荐 Maxnu = 0. Select * from zflight where airln = ‘LF’ and cntry = ‘IN’. Check zflight-fligh > maxnu. Maxnu = zflight-fligh. Endselect. * 推荐 Select max( fligh ) from zflight into maxnu where airln = ‘LF’ and cntry = ‘IN’.
- 不适用EXEC SQL.....END EXEC语句;
- 使用内表的SORT BY代替SQL的ORDER BY;
- 避免使用SELECT DISTINCT语句,使用ABAP SORT + DELETE ADJACENT DUPLICATES 代替;
- 除HR/HCM模块开发,尽可能少用逻辑数据库;
- WHERE条件应与数据表内的字段顺序一致,且尽可能使用主键、索引;
- EQ已经被证明比=号更高效;
- 逻辑处理过程中尽量使用局部变量,以减少内存的占用;
- 尽量减少在程序中对数据库的操作次数;
- 尽量不适用SELECT *;
- 尽量避免在WHERE时使用LIKE;
- 当逻辑结束时,使用EXIT跳出循环;
- 对于条件确定的逻辑,使用CASE语句替代重复的IF语句;
- 值传递的两个结构,如果所需传递的字段数量在10个以下且结构字段数在30个以上时,不建议使用MOVE-CORRESPONDING(两个结构完全一致除外);
- 使用READ TABLE时应使用BINARY SEARCH(注意先对表进行排序);
* 不推荐 Read table int_fligh with key airln = ‘LF’. * 推荐, 注意Read之前需要按Key 排序 Sort int_fligh by airln. Read table int_fligh with key airln = ‘LF’ binary search.
- A、B两个表结构相同,A表数据往B表添加时,使用APPEND LINES OF ITAB1 TO ITAB2;
* 不推荐 Loop at int_fligh1. Append int_fligh1 to int_fligh2. Endloop. * 推荐 Append lines of int_fligh1 to int_fligh2.
- LOOP.....WHERE比LOOP内CHECK要快;
- DO循环要指定具体的循环次数 或 有必然的退出条件,并有EXIT语句进行处理,不然将会造成死循环;
- 在 S4 系统里增加前导 0 或删除前导 0,不能使用 ECC 里的函 数:CONVERSION_EXIT_ALPHA_OUTPUT 和 CONVERSION_EXIT_ALPHA_INPUT,使用 S4 的新语法: X = |{ X ALPHA = OUT }| 和 X = |{ X ALPHA = IN }|;
- 有除法运算时,被除数应先判断不能为0;
- 使用新语法LOOP AT....GROUP BY代替AT NEW、AT END;
LOOP AT gt_output INTO gw_output GROUP BY ( matnr = gw_output-matnr ) INTO DATA(group1). CLEAR: lw_out,lw_data. REFRESH: lw_out-mt_bom_from_sap-data. LOOP AT GROUP group1 INTO DATA(lw_matnr). lw_data-matnr = lw_matnr-matnr. lw_data-werks = lw_matnr-werks. lw_data-andat = lw_matnr-andat. lw_data-aedat = lw_matnr-aedat. lw_data-idnrk = lw_matnr-idnrk. lw_data-z_parent = lw_matnr-z_parent. lw_data-menge = lw_matnr-menge. lw_data-meins = lw_matnr-meins. lw_data-dumps = lw_matnr-dumps. APPEND lw_data TO lw_out-mt_bom_from_sap-data. CLEAR: lw_data. ENDLOOP. ENDLOOP.
- 当一个程序运行超过10秒,则应考虑通过:1)增加输入条件;2)把运算放到后台程序并保存静态数据,报表查询已保存的静态数据;3)优化程序处理逻辑;等方法来进行优化处理;
- 尽量不要嵌套循环;
* 不推荐 LOOP AT lt_splif INTO DATA(lw_splif). LOOP AT lt_sflight INTO DATA(ls_sflight) WHERE carrid = ls_splif-carrid and connid = ls_splif-connid. ...... ENDLOOP. ENDLOOP. * 推荐 LOOP AT lt_splif INTO DATA(lw_splif). READ TABLE lt_sflight TRANSPORTING NO FIELDS WITH KEY carrid = ls_splif-carrid and connid = ls_splif-connid. IF sy-subrc = 0. DATA(lv_tabix) = sy-tabix. LOOP AT lt_sflight INTO DATA(ls_sflight) FROM lv_tabix. IF ls_sflight-carrid <> ls_splif-carrid OR ls_sflight-connid <> ls_splif-connid. EXIT. ENDIF. ...... ENDLOOP. ENDIF. ENDLOOP.
- 使用批量修改内表代替逐行修改;
* 不推荐 Loop at int_fligh. If int_fligh-flag is initial. Int_fligh-flag = ‘X’. Endif. Modify int_fligh. Endloop. * 推荐 Int_fligh-flag = ‘X’. Modify int_fligh transporting flag where flag is initial.
4.2 数据一致性规范
- 使用FOR ALL ENTRIES时,需要先判断内表不为空,且所使用的表字段在内表里没有重复;
- 所定义的变量 或 内表字段,在后续的值传递过程中,应使用相同的数据类型、长度;
- 操作数据表进行数据的增、删、改时,应先对数据表进行加锁处理(注意在循环内加锁需要谨慎,会把应用层锁占满,影响系统稳定性);
- 应充分考虑系统的LUW;
- 所有的CASE,应有WHEN OTHERS来捕获并处理意外的情况;
- 不能在增强内部使用CHECK,COMMIT WORK,ROLLBACK WORK等影响程序执行和数据更新机制的语句;
- 如没有特殊要求,所有的金额字段应为2位小数,数量字段应为3位小数;
- 应尽量避免用户无意录入的无效数据,建议保存前增加录入数据的有效性检验逻辑;
- 尽量避免进行字符串比较、判断的逻辑处理,因为用户录入的字符串可能会有含空格、特殊字符、全角输入法等情况出现;
- 如果用户需要双语或多语使用环境,要在对应的环境下进行开发,切勿修改对象的源语言;
- 不允许直接对SAP标准数据表进行增、删、改操作;
- 原则上不允许对表数据进行删除操作,应当使用删除标记,且应记录修改者、修改日期、修改时间等冗余字段值;
- 尽量不要在循环内使用COMMIT WORK、ROLLBACK WORK;
- 具备交互的ALV列表,在接收USER_COMMAND时,应使用ALV的刷新机制更新内表数据,以保持内表与用户操作的数据一致;
4.3 可读性规范
- 使用CLEAR语句初始化内表的Work-Area;
- 使用REFRESH语句删除表内容,释放所有页空间;
- 使用FREE释放对象;
- 数据表尽量不保存前导零;
- 定义内表时,不使用WITH HEADER LINE,OCCURS;
- 不要把具体的取数逻辑和数据处理逻辑写到SMARTFORMS里,FORM只做数据展示;
4.4 易用性规范
- 所有用于交互的输入控件,应都具备对应的搜素帮助以供查询;
- 建议CDS加上@Analytics : {dataCategory:#FACT,dataExtraction.enabled: true}注解,加了之后才能被BW系统发现;
4.5 安全性规范
- 增强的开发需要有增强开关设计;
- 避免在程序中循环创建动态内表(SAP最多支持单进程36个动态对象,超过会dump);
- 调用函数时应使用与函数参数完全一致的参数(包括变量、结构、表);
- 使用RANGE作为查询条件时,RANGE的条目数不能太多(100条以下),超过限制会dump,建议使用FOR ALL ENTRIES代替;
- 当内表处理的数据量有可能达到100万或以上时,应考虑分批处理方式,以免超出SAP单进程内存最大值造成dump;
- 一个函数建一个函数组,以免函数之间互相影响;
- 展示或下载个人信息、薪资信息等敏感信息时,应做相应的脱敏处理;
4.6 标准程序的修改
在标准的SAP ABAP程序规定中,原则上不允许修改。如果变更一定而且有必要,要认真的检查与分析这次的修改逻辑及与相关的程序的关联影响。同时需经对开发组长申请,得到允许后方可进行修改,并按统一模板进行记录。必须在修改的程序头中加入修改记录在实际修改的代码中,应该加入修改目的,修改人与日期等。不要从源程序中删除任何原代码。删除部分用*注释说明。如果因为主要的程序代码被重写,脱离原代码保留原来的注释,这样会干预到程序的可读性,因此需删除的部分原代码和相应的注释,用*进行统一注释。
不要关闭GUI的代码助手
5、EXCEL导入/导出
- 每个需要使用模板的程序都建议增加导出模板的功能按钮;
- 如果是批量导入的程序,在输出内表应增加BOX(选择项)、LIGHT(指示灯)、MSG(消息)字段,用于后续操作和直观提示用户交互结果;
TYPES:BEGIN OF ty_out. TYPES: box, light(10), msg(100). TYPES: kunnr TYPE vbak-kunnr, "客户编码 vkorg TYPE vbak-vkorg, "销售组织 vtweg TYPE vbak-vtweg, "分销渠道 spart TYPE vbak-spart, "产品组 bzirk TYPE knvv-bzirk, "销售地区 vkbur TYPE vbak-vkbur, "销售办事处 waers TYPE bkpf-waers, "货币码 zflag(1) TYPE c. "操作标识 TYPES:END OF ty_out.
- 导出时,文件应保存到用户可选择的本地路径,尽量避免默认保存到具体某个路径;
- 导出的文件名后面应带有时间戳,避免多次下载造成覆盖;
- 导入EXCEL的内表避免与输出内表为同一个;
- 导入的数据,应检查其有效性,并按业务要求校验必填信息;
- 导入EXCEL模板数据时,确认每个字段的最大长度,如果有字段超过50个字符,则需要对标准的导入函数进行增强处理(标准默认50个字符);
- 操作OLE对象完成后,应及时释放;
FREE: gw_excel,gw_workbook,gw_sheet,gw_cell.
- 如果需要把内表数据里的多行输出到EXCEL时,避免逐个单元格操作,应使用剪贴板;
lv_separator = cl_abap_char_utilities=>horizontal_tab."#号 LOOP AT gt_out INTO DATA(lw_out) WHERE box = 'X'. MOVE-CORRESPONDING lw_out TO lw_excel. DO 18 TIMES. ADD 1 TO lv_index. ASSIGN COMPONENT lv_index OF STRUCTURE lw_excel TO <fs>. WRITE <fs> TO lv_value. CONDENSE lv_value. IF lv_index = 1. CONCATENATE lw_data lv_value INTO lw_data. ELSE. CONCATENATE lw_data lv_value lv_separator INTO lw_data."加#换列 ENDIF. ENDDO. APPEND lw_data TO lt_data. CLEAR:lw_data,lv_index,lw_excel. ENDLOOP. CALL METHOD cl_gui_frontend_services=>clipboard_export IMPORTING data = lt_data[] CHANGING rc = lv_rc.
6、GUI界面设计规范
用户界面设计原则应该是界面直观、简洁、易用。设计良好的界面能够引导用户完成相应的操作,起到向导作用,相反由于界面设计失败,会让用户操作有挫败感。我们在设计界面时,尽量参考SAP标准屏幕、图标、快捷键及各种风格,使自定义开发程序与标准程序界面及操作风格保持一致。且应充分考虑每个用户所需交互的输入框、按钮等控件的光标位置,应合乎用户的业务操作逻辑顺序。
PS. HR/HCM的界面应尽量使用报告类进行开发。
6.1图标的使用
- 由于图标可能会造成歧义的需在按钮图标后加上文字,文字应该尽量简洁;
- 对于保存、回退、退出等SAPGUI标准操作,应优先使用SAP默认的功能;
- 不同的程序界面相同或类似的功能图标应顺序一致;
描述 | 图标 | 值 | 快捷键 |
---|---|---|---|
新建 | ICON_CREATE | F5 | |
删除 | ICON_DELETE | Shift-F2 | |
修改 | ICON_CHANGE | F6 | |
显示 | ICON_DISPLAY | F7 | |
明细视图 | ICON_DETAIL | Shift-F4 | |
概览 | ICON_OVERVIEW | Shift-F4 | |
标题; 基本数据 | ICON_HEADER | Shift-F1 | |
层次 | ICON_TREE | Shift-F6 | |
前一节点 | ICON_PREVIOUS_NODE | ||
下一节点 | ICON_NEXT_NODE | ||
关闭 | ICON_CLOSE | ||
检查 | ICON_CHECK | Ctrl-Shift-F3 | |
其他 <对象> | ICON_OTHER_OBJECT | Shift-F5 | |
刷新 | ICON_REFRESH | Ctrl-Shift-F12 | |
执行 | ICON_EXECUTE_OBJECT | F8 | |
测试 | ICON_TEST | F8 | |
生成 | ICON_GENERATE | Shift-F5 | |
保存 | ICON_SYSTEM_SAVE | Ctrl-S | |
释放 | ICON_RELEASE | Shift-F7 | |
完成; 没有错误 | ICON_COMPLETE | Ctrl-F12 | |
显示日志 | ICON_PROTOCOL | ||
查找 | ICON_SEARCH | Ctrl-F | |
查找下一个 | ICON_SEARCH_NEXT | ||
返回 | ICON_SYSTEM_BACK | F3 | |
退出 | ICON_SYSTEM_END | Shift-F3 | |
取消 | ICON_SYSTEM_CANCEL | F12 | |
复制 <对象> | ICON_COPY_OBJECT | Shift-F11 | |
复制 | ICON_SYSTEM_COPY | Ctrl-F12 | |
剪切 | ICON_SYSTEM_CUT | Ctrl-F11 | |
粘贴 | ICON_SYSTEM_PASTE | Ctrl-Shift-F11 | |
撤消 | ICON_SYSTEM_UNDO | Shift-F8 | |
插入行 | ICON_INSERT_ROW | Ctrl-F10 | |
插入多行 | ICON_INSERT_MULTIPLE_LINES | ||
删除行 | ICON_DELETE_ROW | Ctrl-F9 | |
创建文本 | ICON_CREATE_TEXT | ||
替换 | ICON_REPLACE | Shift-F4 | |
切换 | ICON_INTERCHANGE | Shift-Ctrl-0 | |
计算 | ICON_CALCULATION | Ctrl-F7 | |
锁定 | ICON_LOCKED | F6 | |
解锁 | ICON_UNLOCKED | F7 | |
时间 | ICON_TIME | ||
日期 | ICON_DATE | ||
打印 | ICON_PRINT | ||
第一页 | ICON_FIRST_PAGE | Shift-F9 | |
前一页 | ICON_PREVIOUS_PAGE | Shift-Ctrl-0 | |
下一页 | ICON_NEXT_PAGE | Shift-F11 | |
最后一页 | ICON_LAST_PAGE | Shift-F12 | |
全选 | ICON_SELECT_ALL | F5 | |
取消全选 | ICON_DESELECT_ALL | F6 | |
选择块 | ICON_SELECT_BLOCK | ||
按升序列排 | ICON_SORT_UP | Shift-F6 | |
按降序列排 | ICON_SORT_DOWN | Shift-F7 | |
设置过滤器 | ICON_FILTER | ||
上载 | ICON_IMPORT | Ctrl-F11 | |
下载 | ICON_EXPORT | Ctrl-F12 | |
传输 | ICON_TRANSPORT | Ctrl-Shift-F9 | |
激活 | ICON_ACTIVATE | Ctrl-F3 | |
连接 | ICON_CONNECT | ||
断开连接 | ICON_DISCONNECT | ||
绿灯; 继续; 好的 | ICON_GREEN_LIGHT | ||
黄灯; 注意 | ICON_YELLOW_LIGHT | ||
红灯; 停止; 错误 | ICON_RED_LIGHT | ||
绿色LED;前进;正常 | ICON_LED_GREEN | ||
红色LED;停止;错误 | ICON_LED_RED | ||
黄色 LED; 注意 | ICON_LED_YELLOW | ||
图形 | ICON_GRAPHICS | ||
确定;继续;选择<值> | ICON_OKAY | ||
取消 | ICON_CANCEL | F12 | |
后台作业 | ICON_BACKGROUND_JOB | ||
设置状态 ; 审批 | ICON_SET_STATE | ||
全部展开 | ICON_EXPAND_ALL | Ctrl-F2 | |
全部折叠 | ICON_COLLAPSE_ALL | Ctrl-F3 | |
开启; 存在 | ICON_PRESENCE | ||
关闭; 缺少 | ICON_ABSENCE |
6.2 Dialog界面设计规范
- 对于必输内容或重要输入内容,需高亮提示用户;
- 字段描述左对齐,各行对齐到同列;
- 文本描述要设置As label on left;
- 金额、数量字段,长度应满足最大值显示,其后紧随货币、重量单位;
- 内容为金额、数量字段等字段需允许处理负数;
- 单值输入、数据较少的字段或需要限制输入的字段,可使用下拉框;
- 控件位置控制在一个屏幕内(1024*768),即不应出现屏幕纵向或横向滚动条(控件内部不限制,如ALV、Table Control等);
- 全局功能应在Tool Bar显示,功能过多应在Menu显示;
- 文本控件的显示长度小于输入长度时,须设置可滚动标识;
- 同一界面上的控件数最好不要超过20个,多于20个的可考虑使用分页控制(TABSTRIP);
- 按功能将界面划分为各区域块,用Group BOX框括起来,并且有功能说明或标题;
- 控件位置遵循从上到下,从左到右原则,抬头或全局数据应该放置在屏幕上端,明细或其他放在下方;
- 同一功能或任务的元素放在集中位置,减少鼠标移动距离;
- 子屏幕整个位置应该在主屏幕中间显示;
- 若屏幕较多、操作较多,标题应随功能变换而改变;
- 所有用于交互的输入控件,应都具备对应的搜素帮助以供查询;
7、报表程序结构
*&---------------------------------------------------------------------*
*& Program ID : <程序需求编号> *
*& Program Name : XXXXXXXXX *
*& T-CODE : <事物代码> *
*& Program Type: <报表/表单/数据转换/接口/功能> *
*& Description : 采购订单报表 *
*&---------------------------------------------------------------------*
*& Date Created : <YYYY/MM/DD> *
*& Created By : <创建者> *
*&---------------------------------------------------------------------*
*& Edit Log : *
*& Version Date Author Remark *
*& <YYYYMMDDnnn> <YYYY/MM/DD> <修改人> <修改理由/内容> *
*&---------------------------------------------------------------------*
REPORT xxxxxxxx MESSAGE-ID xxxxxxxx
LINE-SIZE xxx
LINE-COUNT xxx
NO STANDARD PAGE HEADING.
INCLUDE xxxxxxxx.
*----------------------------------------------------*
* GLOBLE-DEFINATION *
*----------------------------------------------------*
DATA: xxxxxxxx.
*----------------------------------------------------*
* SELECTION-SCREEN *
*----------------------------------------------------*
SELECTION-SCREEN BEGIN OF xxxxxxxx.
PARAMETERS: xxxxxxxx.
SELECT-OPTIONS: xxxxxxxx.
SELECTION-SCREEN END OF xxxxxxxx.
*----------------------------------------------------*
* INITIALIZATION *
*----------------------------------------------------*
INITIALIZATION.
PERFORM FRM_xxxxxxxx.
*--------------------------------------------------- *
* AT SELECTION-SCREEN *
*----------------------------------------------------*
AT SELECTION-SCREEN.
PERFORM FRM_xxxxxxxx.
*----------------------------------------------------*
* START-OF-SELECTION *
*----------------------------------------------------*
START-OF-SELECTION.
PERFORM FRM_xxxxxxxx.
*-----------------------------------------------------*
* END-OF-SELECTION *
*-----------------------------------------------------*
END-OF-SELECTION.
*&----------------------------------------------------*
*& Form FRM_xxxxxxxx
*&----------------------------------------------------*
* Text
*-----------------------------------------------------*
* <- p1 text
* -> p2 text
*-----------------------------------------------------*
FORM FRM_xxxxxxxx.
ENDFORM.