PERFORM参数传递

90 篇文章 0 订阅
1 篇文章 0 订阅

PERFORM参数传递

参数

实参:子例程调用期间用PERFORM语句指定的参数;
形参:子例程定义期间用FORM语句定义的参数。

数据传输方法

引用调用;值调用;值传并返回结果。

参考链接:https://www.cnblogs.com/jiangzhengjun/p/7264657.html#_Toc410466862

Form、Function中的TABLES参数,TYPE与LIKE后面只能接标准内表类型或标准内表对象,如果要使用排序内表或者哈希内表,则只能使用USING(Form)与CHANGING方式来代替。当把一个带表头的实参通过TABLES参数传递时,表头也会传递过去,如果实参不带表头或者只传递了表体(使用了[]时),系统会自动为内表参数变量创建一个局部空的表头

不管是以TABLES还是以USING(Form)非值、CHANGE非值方式传递时,都是以引用方式(即别名,不是指地址,注意与Java中的传引用区别:Java实为传值,但传递的值为地址的值,而ABAP中传递的是否为地址,则要看实参是否是通过Type ref to定义的)传递;

但如果USING值传递,则对形参数的修改不会改变实参,因为此时不是引用传递;但如果CHANGE值传递,对形参数的修改还是会改变实参,只是修改的时机在Form执行或Function执行完后,才去修改。

Form中通过引用传递时,USING与CHANGING完全一样;但CHANGING为值传递方式时,需要在Form执行完后,才去真正修改实参变量的内容,所以CHANGING传值与传引用其结果都是一样:结果都修改了实参内容,只是修改的时机不太一样而已

FORM subr [TABLES t1 [{TYPE itab_type}|{LIKE itab}|{STRUCTURE struc}] 
t2 []] 

        [USING { VALUE(p1)|p1 } [ { TYPE generic_type } 

        | { LIKE <generic_fs>|generic_para }
        | { TYPE {[LINE OF] complete_type}|{REF TO type} } 
        | { LIKE {[LINE OF] dobj} | {REF TO dobj} }
        | STRUCTURE struc] 

        { VALUE(p2)|p2 } []] 

        [CHANGING{ VALUE(p1)|p1 } [ { TYPE generic_type } 

        | { LIKE <generic_fs>|generic_para }  

        | { TYPE {[LINE OF] complete_type} | {REF TO type} } 
        | { LIKE {[LINE OF] dobj} | {REF TO dobj} } 
        | STRUCTURE struc] 

        { VALUE(p2)|p2 } []] 

        [RAISING {exc1|RESUMABLE(exc1)} {exc2|RESUMABLE(exc2)} ...].

generic_type:为通用类型

complete_type:为完全限制类型

<generic_fs>:为字段符号变量类型,如下面的 fs 形式参数

generic_para:为另一个形式参数类型,如下面的 b 形式参数

DATA: d(10) VALUE'11'.
    FIELD-SYMBOLS: <fs> LIKE d.
    ASSIGN d TO <fs>.
    PERFORM aa USING <fs> d d.
    FORM aa USING fs like <fs>  a like d  b like a.
    WRITE:fs,/ a , / b.
ENDFORM.

如果没有给形式参数指定类,则为ANY类型

如果TABLES与USING、CHANGING一起使用时,则一定要按照TABLES、USING、CHANGING顺序声明

值传递中的VALUE关键字只是在FORM定义时出现,在调用时PERFORM语句中无需出现,也就是说,调用时值传递和引用传递不存在语法格式差别。

例如:

PERFORM frm_ref2 USING dref ."传递的内容为地址,属于别名引用传递
FORM frm_ref2 USING p_i TYPE REF TO i ."p_i为实参dref的别名,类似C++中的引用参数传递(传递的内容为地址,并且属于别名引用传递)
ENDFORM.
DATA : i TYPE i VALUE 100.
WRITE: / 'frm_ref===='.
PERFORM frm_ref USING i .
FORM frm_ref  USING  p_i TYPE i ."C++中的引用参数传递:p_i为实参i的别名
ENDFORM.
WRITE: / 'frm_val===='.
i = 100.
PERFORM frm_val USING i .
WRITE: / i."100

FORM frm_val  USING   value(p_i)."传值:p_i为实参i的拷贝
WRITE: /  p_i."100
  p_i = 300."由于是传值,所以不会修改主调程序中的实参的值
ENDFORM.

TABLES:把内表传入form中,内表值可以有变化

Extras:

  1. … TABLES itab1 itab2 …
  2. … USING a1 a2 …
  3. … CHANGING a1 a2 …
*&---------------------------------------------------------------------*
*& Report ZTEST_FORM_LHY
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT ztest_form_lhy.
PARAMETERS: p_carr TYPE sflight-carrid.
            "p_conn TYPE sflight-connid.

DATA sflight_tab TYPE STANDARD TABLE OF sflight.

PERFORM select_sflight TABLES sflight_tab
                       USING  p_carr.
ULINE.
WRITE:'调用程序修改之后:'.
 LOOP AT sflight_tab ASSIGNING FIELD-SYMBOL(<fs_flight1>).
      IF <fs_flight1>-carrid = 'AA' AND <fs_flight1>-fldate = '20230706'.
        WRITE:/,<fs_flight1>-carrid,<fs_flight1>-connid,<fs_flight1>-fldate,<fs_flight1>-price,<fs_flight1>-seatsmax.
      ENDIF.
ENDLOOP.
FORM select_sflight TABLES flight_tab LIKE sflight_tab
                    USING  f_carr TYPE sflight-carrid.
  SELECT *
         FROM sflight
         WHERE carrid = @f_carr
         INTO TABLE @flight_tab.
  "cl_demo_output=>display( flight_tab )."只是输出工作区没有内容
    WRITE:'调用程序:'.
    LOOP AT flight_tab ASSIGNING FIELD-SYMBOL(<fs_flight>).
      IF <fs_flight>-carrid = 'AA' AND <fs_flight>-fldate = '20230706'.
        <fs_flight>-seatsmax = 1000000000.
        WRITE:/,<fs_flight>-carrid,<fs_flight>-connid,<fs_flight>-fldate,<fs_flight>-price,<fs_flight>-seatsmax.
      ENDIF.
    ENDLOOP.
ENDFORM.

程序输出如下:

表明,传递TABLES的时候,如果对其进行修改,是会影响到实参的!!!

程序名:ZTEST_FORM_LHY

*&---------------------------------------------------------------------*
*& Report ZTEST_FORM_LHY
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT ztest_form_lhy.
PARAMETERS: p_carr TYPE sflight-carrid.
            "p_conn TYPE sflight-connid.

DATA sflight_tab TYPE STANDARD TABLE OF sflight.

*PERFORM select_sflight TABLES sflight_tab
*                       USING  p_carr.
PERFORM select_sflight2 USING sflight_tab p_carr.
*ULINE.
*WRITE:/, '调用程序1修改之后:'.
* LOOP AT sflight_tab ASSIGNING FIELD-SYMBOL(<fs_flight1>).
*      IF <fs_flight1>-carrid = 'AA' AND <fs_flight1>-fldate = '20230706'.
*        WRITE:/,<fs_flight1>-carrid,<fs_flight1>-connid,<fs_flight1>-fldate,<fs_flight1>-price,<fs_flight1>-seatsmax.
*      ENDIF.
*ENDLOOP.
ULINE.
WRITE:/, '调用程序2修改之后:'.
LOOP AT sflight_tab ASSIGNING FIELD-SYMBOL(<fs_flight2>).
      IF <fs_flight2>-carrid = 'AA' AND <fs_flight2>-fldate = '20230706'.
        WRITE:/,<fs_flight2>-carrid,<fs_flight2>-connid,<fs_flight2>-fldate,<fs_flight2>-price,<fs_flight2>-seatsmax.
      ENDIF.
ENDLOOP.
FORM select_sflight TABLES flight_tab LIKE sflight_tab
                    USING  f_carr TYPE sflight-carrid.
  SELECT *
         FROM sflight
         WHERE carrid = @f_carr
         INTO TABLE @flight_tab.
  "cl_demo_output=>display( flight_tab )."只是输出工作区没有内容
    WRITE:/,'调用程序1:'.
    LOOP AT flight_tab ASSIGNING FIELD-SYMBOL(<fs_flight>).
      IF <fs_flight>-carrid = 'AA' AND <fs_flight>-fldate = '20230706'.
        <fs_flight>-seatsmax = 1000000000.
        WRITE:/,<fs_flight>-carrid,<fs_flight>-connid,<fs_flight>-fldate,<fs_flight>-price,<fs_flight>-seatsmax.
      ENDIF.
    ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form select_sflight2
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> SFLIGHT_TAB
*&---------------------------------------------------------------------*
FORM select_sflight2  USING    VALUE(p_sflight_tab) LIKE sflight_tab
                               p_carr  TYPE sflight-carrid.
  SELECT *
         FROM sflight
         WHERE carrid = @p_carr
         INTO TABLE @p_sflight_tab.
  "cl_demo_output=>display( flight_tab )."只是输出工作区没有内容
    WRITE:/,'调用程序2:'.
    LOOP AT p_sflight_tab ASSIGNING FIELD-SYMBOL(<fs_flight>).
      IF <fs_flight>-carrid = 'AA' AND <fs_flight>-fldate = '20230706'.
        <fs_flight>-seatsmax = 9999999.
        WRITE:/,<fs_flight>-carrid,<fs_flight>-connid,<fs_flight>-fldate,<fs_flight>-price,<fs_flight>-seatsmax.
      ENDIF.
    ENDLOOP.
ENDFORM.

这里是传值:
在这里插入图片描述

执行结果如下:
在这里插入图片描述

所以用using或者changing来传递表类型

  • 26
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值