ABAP学习(7):程序类型
ABAP子程序
ABAP子程序,相当于封装的一个方法,执行一段逻辑处理。
子程序内部定义变量只能子程序内部使用,全局变量可以直接使用。
语法:form <子程序名>
[using]
[changing]
[value ( 变量 )]
[changing value (变量)].
程序处理逻辑.
endform.
关键词:using、changing都是传递地址给子程序,using一般不允许子程序修改值,changing允许子程序修改值,如果子程序内修改using传递的参数值这个只是定义上的,程序并没有限定,会报出警告,不影响运行。
关键词:value只传递值,发现没啥用;
关键词:changing value 返回修改值;
注意:changing value 不能和changing同时存在,一般不使用,changing因为传递的地址,直接修改就会修改地址值,一般就使用changing就可以了。
调用子程序:
语法:perform <子程序名>
[using]
[changing]
[value ( 变量 )].
示例:
DATA: num1 type I value 49, num2 type I value 58. DATA: sum type I.
测试1:
"子程序调用 PERFORM multi USING num1 num2. "子过程定义 form multi USING num1 num2. "局部变量 Data : mul type I. "using传入参数,也可重新赋值,但程序会警告 num1 = 10. mul = num1 * num2."可使用全局变量 WRITE :/ num1,'*',num2,'=',mul. ENDFORM.
测试2:
"子程序调用 PERFORM add01 using num1 num2 CHANGING sum. WRITE :/ '主程序:', num1 ,num2, sum. "子过程定义,使用using,changing传地址,一般using是不允许子程序改值。changing,允许子程序改值 form add01 CHANGING num1 num2 sum. WRITE :/ num1 ,num2, sum. "子程序赋值,主程序也跟着修改 num1 = 10. num2 = 20. sum = num1 + num2. WRITE :/ num1 ,num2, sum. ENDFORM.
测试3:
"子程序调用 PERFORM add02 using num1 sum num2. WRITE :/ '主程序:', num1 ,num2, sum. "子过程定义,value()只传值。 form add02 CHANGING num1 sum value(num2). WRITE :/'前',num1, num2, sum. num2 = 40."这个赋值只在局部有效 sum = num1 + num2. WRITE :/ '后',num1,num2,sum. ENDFORM.
测试时发现:使用value(),子程序赋值,仍然会影响主程序值。调用传参顺序和定义子程序时顺序要一致,不然会出现错位现象,不是按照参数名传参赋值,而是根据位置。
测试4:
"子程序调用 PERFORM add03 using num1 num2 CHANGING sum. WRITE :/ '主程序:', num1 ,num2, sum. "子过程定义,返回changing value(). FORM add03 USING num1 num2 CHANGING VALUE(s). WRITE :/ num1,num2,sum. num1 = 20. num2 = 30. s = num1 + num2. WRITE :/ num1, num2, s. ENDFORM. 测试时发现:使用changing value(),子程序赋值,仍然会影响主程序值。
ABAP宏定义
定义一段通用代码,使用&数字,表明传入参数,执行一段逻辑。这段代码可以在主程序中反复调用。
定义宏:
语法:define <程序名>
程序逻辑.
end-of-definition.
调用宏定义代码段:
语法:<程序名> <参数1> [<参数2> ………]
示例:
"宏定义 DATA: sum type I. DATA: num1 type I value 10, num2 type I value 20. "定义宏,两个数求和,并输出 DEFINE addNum. sum = &1 + &2. WRITE :/ &1,'+', &2 ,'=',sum. end-OF-DEFINITION. "调用宏定义代码 addNum num1 num2.
ABAP公共代码块
定义一段公共使用的代码,编译时直接嵌入到调用位置,主程序可以使用公共代码中定义的所有变量、子程序等。
定义公共代码块,选中包名,右键选择create,找include选择就行了。
如果包下有一个includes活页夹,直接选中includes右键create就行了。
在主程序调用,直接将z_test_include中的代码嵌入到主程序调用位置。
示例:
"调用includeProgram INCLUDE z_test_include.
ABAP程序结构
1报表程序结构
Report <name>:宣告程序名称和报表格式;
语法:report <程序名>
[NO STANDARD PAGE HEADING]
[message-id <messageid>]
[line-count <数字>]
[line-size <数字>]
Message-id:指定使用的message
Line-count:指定报表显示列数
Line-siez:显示每页报表宽度
Include语句:宣告使用的公共代码块;
语法:Include <代码块>:包含其他公共代码块
Tables语句:声明程序中使用到的数据库表;
语法:Tables:<数据库表名>[,<数据库表名>].
Types,Data语句:定义变量类型和变量;
Selection screen、option、parameter定义屏幕显示内容;
语法:见屏幕显示;
Initialization语句:执行一些变量初始化;
语法:Initiallization.
At selection-screen语句:选择屏幕运行时触发,主要对查询条件和权限进行校验。
语法:at selection-screen.
[on <parameters名>]:parameters输入时,按enter触发;
[on end of <select-option名>]:select-option,multi-option页面数据填写后,按确认触发;
[on value–request for <parameters名>]:f4帮助,点击输入框小方块,弹出备选值;
[on help-request for <parameters名>]:f1帮助,按f1执行;
[on radiobutton group <按钮组名>]:监听选择按钮组按钮触发事件,按enter键触发;
[on block <模块名>]:监听block触发事件;
[output]:屏幕每次输出时触发
Start-of-selection语句:开始执行程序主逻辑,比如读取数据,处理数据等,类似于java的main()方法;
语法:start-of-selection.
程序主逻辑.
End-of-selection语句:程序执行结束,调用的子程序可以定义在这模块后;
语法:end-of-selection.
子程序form.
Include代码块.
示例:
"宣告程序名,和报表参数 REPORT Z_TEST_REPORT NO STANDARD PAGE HEADING MESSAGE-ID ym LINE-COUNT 20 LINE-SIZE 20. "include语句 "可以包含公共代码块 "tables语句,宣告使用的数据库表 TABLES:spfli. "定义数据类型,数据变量 TYPES:BEGIN OF str_spfli, carrid LIKE spfli-carrid, connid LIKE spfli-connid, cityfrom LIKE spfli-cityfrom, END OF str_spfli. DATA:t_spfli TYPE TABLE OF str_spfli. DATA:wa_spfli LIKE LINE OF t_spfli. DATA:t_spfli_all LIKE TABLE OF spfli. "定义屏幕元素 "parameters PARAMETERS: p_carrid LIKE spfli-carrid. "select option SELECT-OPTIONS s_connid FOR spfli-connid NO-EXTENSION. "selection-screen SELECTION-SCREEN BEGIN OF BLOCK RADIO WITH FRAME TITLE text1 . PARAMETER p1 RADIOBUTTON GROUP GR1. PARAMETER p2 RADIOBUTTON GROUP GR1. PARAMETER p3 RADIOBUTTON GROUP GR1. SELECTION-SCREEN END OF BLOCK RADIO. "初始化 INITIALIZATION. text1 = '选择参数'. "选择屏幕运行时触发,检查参数 "当parameters输入后,enter触发 AT SELECTION-SCREEN ON p_carrid. MESSAGE s000 WITH p_carrid. "select-option的multi-option界面输入后确认时触发 AT SELECTION-SCREEN ON END OF s_connid. MESSAGE s000 WITH s_connid. "按f4触发,或者点击输入框最后的小方框 AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_carrid. MESSAGE s000 WITH p_carrid 'f4帮助'. "按f1触发 AT SELECTION-SCREEN ON HELP-REQUEST FOR p_carrid. MESSAGE s000 WITH p_carrid 'f1帮助'. "屏幕按钮组变化监听 *AT SELECTION-SCREEN ON RADIOBUTTON GROUP gr1. * IF p1 = 'X'. * MESSAGE s000 with 'p1'. * ELSEIF p2 = 'X'. * MESSAGE s000 WITH 'p2'. * ELSE. * MESSAGE s000 WITH 'p3'. * ENDIF. "屏幕模块监听 AT SELECTION-SCREEN ON BLOCK RADIO. IF p1 = 'X'. MESSAGE s000 with 'p1'. ELSEIF p2 = 'X'. MESSAGE s000 WITH 'p2'. ELSE. MESSAGE s000 WITH 'p3'. ENDIF. "屏幕输出时触发,可以检查输入值,检查权限 AT SELECTION-SCREEN OUTPUT. MESSAGE s000 WITH 'output screen'. "程序主逻辑开始 START-OF-SELECTION. WRITE:/ 'hello world'. MESSAGE s000 WITH '程序主逻辑'. "处理GUI-Status自定义的命令 AT USER-COMMAND. "报表中按f2触发,或者双击 AT LINE-SELECTION. "定义报表表头 TOP-OF-PAGE. "打印完最后一页触发 END-OF-PAGE. "报表程序结束,后面定义一下form或者include代码块 END-OF-SELECTION.
2module pool程序结构
Modul pool programs,模块池程序。主要使用screen作为主要操作对象,所有操作围绕屏幕PBO模块,PAI模块操作。
选择项目,项目活页夹上右键->create->Screen,
输入屏幕编号,例如100。
PBO Modules:屏幕输出前执行module模块池方法;
PAI Modules:用户和屏幕输入交互调用module方法;
Screens:我们创建的屏幕;
GUI Status:自定义的工具栏;
GUI Title:显示的标题;
可以看到我们创建的屏幕,点击0100,在右边设计界面可以添加我们的module逻辑代码。
点击Layout可以进入一个图形化界面,我们可以通过拖动组件方式设计我们的页面。
逻辑代码:
PROCESS BEFORE OUTPUT.模块下的module会在屏幕输出之前执行,一般设置屏幕标题,功能字段逻辑在这里。
PROCESS AFTER INPUT.模块下module会响应用户在屏幕上的操作。比如用户点击功能按钮等。
示例:
TABLES: sflight. DATA : OK_CODE like sy-ucomm. DATA : t_carrid like sflight-carrid. DATA : t_connid LIKE sflight-connid. DATA : t_price LIKE sflight-price. *DATA : testTab like sflight OCCURS 10 WITH HEADER LINE, * testLine like sflight. "调用屏幕显示 CALL SCREEN 100. "屏幕输出前,设置工具栏和标题 MODULE STATUS_0100 OUTPUT. "设置GUI STATUS工具栏 SET PF-STATUS 'STS_100'. "设置标题 SET TITLEBAR 'TEST'. ENDMODULE. "用户退出 MODULE USER_EXIT_0100 INPUT. ok_code = sy-ucomm. CLEAR sy-ucomm. if ok_code = 'BACK' or ok_code = 'CANCEL' or ok_code = 'EXIT'. LEAVE PROGRAM. ENDIF. ENDMODULE. "用户点击执行 MODULE USER_COMMAND_0100 INPUT. ok_code = sy-ucomm. CLEAR sy-ucomm. case ok_code . when 'EXC'. select SINGLE connid price into (t_connid,t_price) from sflight where carrid = t_carrid. if sy-subrc <> 0. t_connid = '00'. t_price = '0.000'. ENDIF. endcase. ENDMODULE.
本文来自博客园,作者:渔歌晚唱,转载请注明原文链接:https://www.cnblogs.com/tangToms/p/11824150.html