以form开始,以endform结束,用perform语句调用,from语句可以在程序内部/外部,perform一定要写在前面
perform.
from.
子程序模块
endform.
perform writedata. "如果写到子程序模块后,这一行会提示 Statement is not accessible 问题:ABAP是编译型语言还是解释性语言
form writedata.
write 'asdfasdf'.
endform. "writedata
或者双击子程序名称,创建子程序
1.在新文件中写子程序,在调用文件中写入包含语句
INCLUDE Z_YZW_STRUC_WRITEDATAF01.
2.如果是在原文件写子程序就写在perfrom语句下面
FROM subr USING p1 TYPE type
VALUE(p2) TYPE type
…
CHANGING p3 TYPE type
VALUE(p4) TYPE type
传参
使用using和changing语句传参, 3种方法
FROM sub USING … VALUE(pi) [TYPE
VALUE子句形参占用自己的单独内存, 调用子程序是,实参值复制到形参中,即使改变形参的值也不户影响实参值
data: gv_val type c length value 'I am value'. "引号内为实参
perform call_byvalue using gv_val. "执行子程序,带参数gv_val
form call_byvalue using value(p_val). "p_val是形参,是局部变量
write p_val. "打印形参,就是打印实参内容
endform.
FROM subr USING … pi [TYPE
FROM subr CHANGGING …pi [TYPE
data: gv_val type c length value '我是实参'.
write / gv_val. "1打印局部变量
perform call_byvref changing gv_val. "3执行子程序,在子程序中修改了局部变量的值 这里比上面少了value关键字,如果不适用value关键字,using和changing语句都属于cal by reference
write / gv_val. "4打印被修改后的局部变量
form call_byvref changing p_val. "2子程序
p_val = 'value is changed'.
endform.
总结:
FORM subr CHANGING .. VALUE(PI) [TYPE
using..value无法更改子程序实参值,changing…value在子程序结束时会更改实参值
data:
gv_val1 type i value ,
gv_val2 type i value ,
gv_sum type i.
perform sum_data using gv_val1 gv_val2 changing gv_sum." using ..changing,下面的子程序结束后,实参gv_sum被更改为p_sum的值
write: / 'result is:', gv_sum.
form sum_data using value(p_val1) value(p_val2) changing value(p_sum). "using .. changeing value 只传值,不能更改实参值
p_sum = p_val1 + p_val2. "三个形参,接收实参值
endform.
最后输出5
定义参数类型
form的形参可以利用type和like语句定义所有的ABAP数据类型,不指定的话默认是Generic类型,集成实参的技术属性
data gv_val type c.
perform call_byvref changing gv_val. "这里传递实参类是c
form call_byvref changing p_val type i. "指定形参数据类型为i, 两种数据类型不能直接转换
p_val = 'xxxx'.
endform.
data gv_val type d.
perform subr changing gv_val.
*形参类型定义方法有3种
*1.直接不指定形参类型,使用默认Generic
*perform subr changing pv_val.
*2.使用相同数据类型
*perform subr changing pv_val type d.
*3.使用相同类型的变量
*perform subr changing pv_val like gv_val.
结构体与形参一样可以使用所有的ABAP数据类型
当结构体作为参数时,可以使用type/like定义,还可以使用structrue语句定义结构体类型
FORM subr USING p_str STRUCTURE str …
FORM subr USING p_str TYPE str …
FORM subr USING p_str LIKE str …
data: begin of gs_str,
col1 value 'A',
col2 value 'B',
end of gs_str.
perform write_data using gs_str.
form write_data using ps_str structure gs_str. "形参使用结构体数据类型
write: ps_str-col1, ps_str-col2.
endform.
子程序参数为内表时也可以使用关键字USING/CHANGING
FROM subr CHANGING …
types: begin of t_str,
col1 type c,
col2 type i,
end of t_str. "定义结构体
types: t_itab type table of t_str."定义内表形式
data: gs_str type t_str,"根据结构体分别定义变量和内表,内表具有两列
gt_itab type t_itab.
gs_str-col1 = 'A'.
gs_str-col2 = .
append gs_str to gt_itab.
gs_str-col1 = 'B'.
gs_str-col2 = .
append gs_str to gt_itab.
perform test_itab using gt_itab. "gt_itab是实参,内表类型
form test_itab using pt_itab type t_itab."形参指定数据类型为内表
read table pt_itab with key col1 = 'A' into gs_str. "read table tabname with key condition into 变量,从表中读取符合条件的数据保存到变量
if sy-subrc = .
write : gs_str-col1, gs_str-col2.
endif.
endform.
types: begin of t_str,
col1 type c,
col2 type i,
end of t_str. "定义结构体
types: t_itab type table of t_str."定义内表形式
data: gs_str type t_str,"根据结构体分别定义变量和内表,内表具有两列
gt_itab type t_itab.
gs_str-col1 = 'A'.
gs_str-col2 = .
append gs_str to gt_itab.
data: gv_name type char10. gv_name = 'COL1'. "
gs_str-col1 = 'B'.
gs_str-col2 = .
append gs_str to gt_itab.
perform test_itab using gt_itab. "gt_itab是实参,内表类型
form test_itab using pt_itab type any table."形参指定为任意表类型, 下面的read要用动态条件,即传值进去,不然动态表找不到列名
read table pt_itab with key (gv_name) = 'A' into gs_str. "read table tabname with key condition into 变量,从表中读取符合条件的数据保存到变量
if sy-subrc = .
write : gs_str-col1, gs_str-col2.
endif.
endform.
使用内表指定参数也有三种方法:
FROM subr CHANGING pt_itab TYPE TABLE.
FROM subr CHANGING pt_itab TYPE ANY TABLE.
FROM subr CHANGING pt_itab TYPE INDEX TABLE.
FROM subr CHANGING pt_itab TYPE STANDARD TABLE.
FROM subr CHANGING pt_itab TYPE SORTED TABLE.
FROM subr CHANGING pt_itab TYPE HASHED TABLE.
FROM subr CHANGING pv_val TYPE i_tab.
FROM subr CHANGING pv_val LIKE gt_itab.
TABLES语句
Rel3.0以前使用tables,可以替代USING与CHANGING语句
调用语法
PERFORM sub.
PERFORM subr(prog) [IF FOUND]. 括号内是外部程序名
data:
gv_val1() type c value 'Enjoy',
gv_val2() type c value 'ABAP',
gv_val3() type c.
perform concate_string using gv_val1 gv_val2 changing gv_val3.
*form concate_string using value(p_val1) value(p_val2) changing value(p_val3).
form concate_string using p_val1 p_val2 changing p_val3.
concatenate p_val1 p_val2 into p_val3 separated by space.
perform write_data using p_val3. "嵌套一个子程序,直接输出不行?
endform.
form write_data using value(p_val).
write: / p_val.
endform.
data:
gv_first() type c value 'External',
gv_second() type c value 'call',
gv_result() type c.
perform concate_string(z_yzw_struc) if found
using gv_first gv_second
changing gv_result.
data:
gv_first() type c value 'External',
gv_second() type c value 'call',
gv_result() type c.
data:
gv_pname() type c value 'Z_YZW_STRUC',"要用大写,不然系统识别不到
gv_subname() type c value 'CONCATE_STRING'."要用大写,不然系统识别不到
perform (gv_subname) in program (gv_pname) if found
using gv_first gv_second
changing gv_result.
利用list调用子程序
PERFORM idx OF subr1 subr2 .. subrn
根据顺序索引调用列出的子程序,只能调用内部子程序,且不能指定参数
do times.
perform sy-index of subr1 subr2.
enddo.
form subr1.
write / '1 subroutine is called'.
endform.
form subr2.
write / '2 subroutine is called'.
endform.
do ~ while
do times.
…
enddo.
while ~ endwhile
while gv_flag = 'X'.
~~
endwhile.
loop ~ endloop
loop at gt_itab to gs_wa.
endloop.
**结束子程序**
* endform, 正常结束
* exit, 直接跳出子程序
* check, 结果为假跳出子程序
parameters: p\_val type char10.
perform end\_subr using p\_val.
form end\_subr using value(p\_val).
case p\_val.
when 'EXIT'. "屏幕输入后系统会转换成大写
write 'subroutine exit'.
exit.
when 'CHECK'.
write 'value check'.
when others.
endcase.
write 'subroutine is normally ended'.
endform. "end\_subr
#### 判断语句
if condition.
elseif codition.
else.
endif.
case variable
when value1.
when value2.
when OTHERS.
endcase.
#### 临时子程序
创建一个程序池,存储子程序
GENERATE Subroutin POOL <itab> NAME <PROG>.
**PERFORM ON COMMIT**
* using perform on cmmit, 遇到commit work时调用子程序
select single \* from scarr into gs\_scarr where carrid ='AA'. "gs\_scarr存储1条数据
perform delete\_data using gs\_scarr. "子程序正常执行
perform insert\_data on commit. "子程序定义时带有选项on commit,遇到commit work才执行
if gv\_flg = 'X'.
commit work. "第二个子程序再这里开始执行
endif.
form delete\_data using value(ps\_scarr) type scarr.
delete scarr from ps\_scarr. "从表scarr中删除符合条件的条目
if sy-subrc = .
gv\_flg = 'X'.
endif.
endform.
form insert\_data.
insert scarr
from gs\_scarr.
endform.
* using perform on rollback, 遇到rollback work时调用子程序
**局部Macro**
减少代码重复,定义如下,但是不能在其他程序中调用
DEFINE macro.
END-OF-DEFINITION.
data:
gv_val1 type c value 'A',
gv_val2 type c value 'B',
gv_val3 type char3.
define conn.
concatenate & & into & separated by space.
dis &. "这里在调用一个define,作为实参传递过去
end-of-definition.
define dis.
write / &. "打印传进来的内容
end-of-definition.
conn gv_val1 gv_val2 gv_val3.
全局MACRO
可以在其他程序中调用,全局MACRO维护在表TRMAC中,可以指定断点时用BREAK语句
手机扫一扫
移动阅读更方便
你可能感兴趣的文章