平时在 ‘ 工地搬砖 ’,很少关注基础技能,闲来无事,拿起来复习一下 !
实际在项目中用到的非常之少,所以说学编程,先学框架,在学细节 !,因为细节太多,学不完 !
‘模块化’这个词在各各领域几乎能看到,喜欢看汽车之家的朋友,应该能听到,国内某某汽车厂,怎么了一下,‘模块化了’开发效率提升了;在电子设备领域、建筑设计领域也能常听到这个词。
‘模块化’ 解决什么问题呢?
1 可复用性,比如:设计一个通用接口,谁想用谁用
2 可扩展性,
3 可以并行开发,多个团队同时作业
4 可容错性,一个模块出问题了,不影响到另一个模块
5 可独立开发和独立测试,更容易发现问题
6 易于理解和维护,等等吧
那么我们在面试时,经常会碰到不懂技术的业务线领导,说一堆牛逼的技术,对方未必知道,如果说出“模块化”这三个字,那么一定程度上是同频率了 !
也可以说我们在做解决方案时,要把这三个词摆在PPT上,牛逼一吹,成单了 !
ABAP领域对模块化设计了什么内容呢 ?
1 宏的定义和调用
DEFINE <macro>.
<statements>
END-OF-DEFINITION.
<macro> [<p1><p2> ... <p9>].
实战过程中的代码长这样子:
DATA:lv_position TYPE i VALUE 1.
CLEAR: lv_position.
lv_position = lv_position + 1.
DEFINE df_fieldcat.
CLEAR gs_fieldcat_lvc.
gs_fieldcat_lvc-col_pos = lv_position."ALV 控制: 输出列
gs_fieldcat_lvc-scrtext_m = &1."中字段标签
gs_fieldcat_lvc-fieldname = &2."ALV 控制: 内部表字段的字段名称
gs_fieldcat_lvc-no_zero = &3."ALV 控制: 为输出隐藏零
gs_fieldcat_lvc-checkbox = &4."ALV 控制: 作为复选框输出
gs_fieldcat_lvc-edit = &5."设置可编辑模式
gs_fieldcat_lvc-outputlen = &6."输出长度
gs_fieldcat_lvc-ref_table = &7.
gs_fieldcat_lvc-ref_field = &8.
gs_fieldcat_lvc-datatype = &9.
APPEND gs_fieldcat_lvc TO gt_fieldcat_lvc.
ADD 1 TO lv_position.
END-OF-DEFINITION.
df_fieldcat:
'物料编号' 'MATNR' 'X' '' '' '18' 'MARA' 'MATNR' '',
'物料描述' 'ZWLCMS' 'X' '' '' '40' '' '' '',
2 使用包含程序
INCLUDE <incl>.
实战过程中的代码长这样子:,做过JAVA的朋友们,可以理解为 : import java.util.List;,或者说引进一个包的概念.
REPORT zmm029.
INCLUDE zmm029_top.
INCLUDE zmm029_sel.
INCLUDE zmm029_frm.
INCLUDE zmm029_pbo.
INCLUDE zmm029_pai.
3 调用子程序
有4种,项目中有用到的就前面2种
调用内部子程序 , PERFORM <subr> [<pass>].
调用外部子程序 , PERFORM <subr>(<prog>) [<pass>] [IF FOUND].
运行时指定子程序名 ,PERFORM (<fsubr>) [IN PROGRAM (<fprog>)] [<pass>] [IF FOUND].
从列表中调用子程序 ,PERFORM <idx> OF <form1><form2> ....<formn>.
PERFORM get_data.
PERFORM set_catalog.
PERFORM display_alv.
4 通过参数进行数据传递
语句,3中传参数的方式 :
FORM <subr> [TABLES <formal table list>]
[USING <formal input list>]
[CHANGING <formal output list>]....
PERFORM <subr>[(<prog>)] [TABLES <actual table list>]
[USING <actual input list>]
[CHANGING <actual output list>]....
通过参考传递:
通过参考值在调用程序和子程序之间进行数据传递
PERFORM... [USING <ai1> ... <ain>] [CHANGING <ao1> ... <aon>] ...
FORM ..... [USING <fi1> ... <fin>] [CHANGING <fo1> ... <fon>] ...
就是说 PERFORM --> FORM
PERFORM get_data.
FORM get_data .
SELECT
mara~zwlcms,
mara~matnr, "物料描述
mara~mtart, "物料类型
mara~meins, "单位
marc~werks,
marc~ekgrp,
marc~dismm,
marc~dispo,
marc~sfcpf,
marc~fevor,
mvke~vkorg, "销售组织
mbew~vprsv, "价格控制
mbew~mlast "物料价格确定: 控制
INTO CORRESPONDING FIELDS OF TABLE @gt_data
FROM mara
LEFT JOIN marc ON marc~matnr = mara~matnr
LEFT JOIN mvke ON mvke~matnr = mara~matnr AND mvke~dwerk = marc~werks
LEFT JOIN mbew ON mbew~matnr = mara~matnr AND mbew~bwkey = marc~werks
WHERE
mara~matnr IN @so_matnr
AND marc~werks IN @so_werks
.
ENDFORM.
通过值传递:
PERFORM... USING .......<aii> ..
FORM ..... USING ...VALUE(<fii>) ..
通过值和结果进行传递:
PERFORM... CHANGING .......<aii> ..
FORM ..... CHANGING ...VALUE(<fii>) ..
5 在子程序中定义局部数据类型和对象
定义动态局部数据类型和对象:
可以用 TYPES 和 DATA 语句,按照创建数据对象和数据类型中的说明,在子程序内创建局部数据类型和数据对象
定义静态局部数据类型和对象:
如果想在退出子程序后保留局部数据对象之值,必须使用 STATICS 语句而非 DATA 语句进行声明。
显示定义全局数据对象:
LOCAL <f>.避免全局数据对象值在子程序内被更改
6 调用功能模块
CALL FUNCTION <module>
[EXPORTING f1 = a1 .... fn = an]
[IMPORTING f1 = a1 .... fn = an]
[CHANGING f1 = a1 .... fn = an]
[TABLES f1 = a1 .... fn = an]
[EXCEPTIONS e1 = r1 .... en = rn [OTHERS = ro]].
(1)EXPORTING 选项允许将实参数 ai 传递给形式输入参数 fi。在功能模块中,必须将形式参数声明为输入参数。
(2)IMPORTING 选项允许将形式输出参数 fi 传递给实参数 ai。在功能模块中,必须将形式参数声明为输出参数。
(3)CHANGING 选项允许将实参数 ai 传递给形式参数 fi,并在处理功能模块后,系统将(更改过的)形式参数 fi 传递回实参数 ai。在功能模块中,必须将形式参数声明为更改参数。
(4)TABLES 选项允许在实参数和形式参数间传递表格。借助该选项,内表总是通过参考值传递。
EXPORTING :为输入参数 ,IMPORTING:为输出参数 ;一定要反过来理解 ,据说是模块化过程中,工程师之间的沟通,一方吵架没吵赢 ! EXPORTING :为输入参数 ,即是被掉函数的输入参数
例子:
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
i_callback_program = sy-repid "这里是调用这个ALV的程序名
i_callback_pf_status_set = 'PF_STATUS' "设置ALV状态栏的函数
i_callback_user_command = 'USER_COMMAND' "获取用户事件的函数
is_layout_lvc = ls_layout "显示的布局
it_fieldcat_lvc = gt_fieldcat_lvc "设置显示的字段以及字段的功能
i_save = 'A'
TABLES
t_outtab = gt_data
EXCEPTIONS
program_error = 1.