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.
View Code

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.

 

posted @ 2019-11-09 08:41  渔歌晚唱  阅读(1238)  评论(0编辑  收藏  举报