ABAP中的subroutine和function module


如果我不是一步走到头。那我加个模块化的子程序。
这个模块化的子程序,是个独立的小个体,可以被重复使用。
也就是给它的参数和它给出的参数不一样。

1. 子程序变量(参数)类型

在整个程序里,定义参数变量可以在主程序,也可以在子程序。主程序就是大家都能用,子程序就是只有我自己个能用。
当我在主程序中定义了变量,而我要把主程序的变量传递给子程序啊,我的主程序变量就是实参,子程序的变量就是形参。

DATA: A type ...,
       B type ...,
       C type ....
Perform xyz using A B C.

Form xyz Using P1 type ...
               P2 type...
               P3 type...
Endform.

2020.03.29再来补充:
对于从caller传递实参给子例程形参的方式三种:

  1. by value : 参数值是复制给子例程的。复制完了就跟实参没关系了。我俩是独立自主的了,互不干扰,我改了也不会改你外面的参数。
PERFORM mysub USING myvar1.

FORM mysub USING VALUE(subvar1) TYPE i.
..
ENDFORM.
  1. by reference:这个意思是只把我caller的参数内存地址(parameter memory location)给子例程,那么子例程里做了任何能更改我caller的参数的,都会直接把我改掉。
PERFORM mysub USING [or CHANGING] myvar1.

FORM mysub USING [or CHANGING] subvar1 TYPE i.
..
ENDFORM.
  1. by value&result: 把这个放最下面,其实这个是前两者的混合体可以说。caller会把参数copy给子例程,也就是还是用value(),但是子例程来跑,如果没有错,那么子例程把结果返回给caller并且改掉它的参数。如果有错,那就不改它的参数。所以这里用的是CHANGING。
PERFORM mysub CHANGING myvar1.

FORM mysub CHANGING value(subvar1) TYPE ANY.
..
ENDFORM.

当然传递给子例程的参数的数据类型,是由caller决定的咯。
所以你子例程里面,参数类型要么没有,要么TYPE ANY。要么就是为了看起来方便,给一个TYPE的。

1.1 by value

这种变量的定义语法就是Using VALUE(P1) 变量在VALUE后面的括号里。
就是说只把主程序实参的值拿过来到子程序里用。但是我这里使用的只是实参的值,不会再改回实参里去的。
主程序让我执行一些任务,我需要用它的变量值。

Perform xyz using A B C.
Form xyz Using VALUE(P1) type ...
               VALUE(P2) type...
               VALUE(P3) type...
Endform.

1.2 by value & result

主程序让我来基于一些操作,条件来更改一些值。我需要把更改后的值再传回主程序去。

Perform xyz Using/changing A B C.
Form xyz Changing VALUE(P1) type ...
                  VALUE(P2) type...
                  VALUE(P3) type...
Endform.

或者是这样:用Using,但是没有VALUE和括号

Form xyz Using P1 type ...
               P2 type...
               P3 type...
Endform.

1.3 by reference

这种呢,就是形参直接指向实参,你在子程序里用的形参,实际上会直接分配到实参。

Perform xyz changing A B C.
Form xyz Changing P1 type ...
                  P2 type...
                  P3 type...
Endform.

SAP给的解释是subroutine已经过时了。。。我觉得能看懂还是很必要的。不过也不难。主要就是三种调用方法。
多学点也不吃亏。

INCLUDE ZFBI_TESTTOP                            .    " Global Data

* INCLUDE ZFBI_TESTO01                            .  " PBO-Modules
* INCLUDE ZFBI_TESTI01                            .  " PAI-Modules
INCLUDE ZFBI_TESTF01                            .  " FORM-Routines
*PARAMETERS:pa_01 type int4,
*           pa_02 type int4.
PARAMETERS: o_carrid TYPE S_CARR_ID.
DATA: o_cityfr type S_FROM_CIT.

START-OF-SELECTION.

Perform get_airline_detail
        USING o_carrid  /*就是程序运行正确就改掉*/
        CHANGING o_cityfr. /*这个是地址传递,直接改*/

write: / o_cityfr.
*&---------------------------------------------------------------------*
*& Include          ZFBI_TESTF01
*&---------------------------------------------------------------------*
FORM get_airline_detail
  Using VALUE(v_carrid) type S_CARR_ID
  CHANGING v_cityfr type S_FROM_CIT.

  types: begin of ty_cust.
         INCLUDE STRUCTURE spfli.
  types: CARRNAME type S_CARRNAME,
         end of ty_cust.


  DATA: wa_scarr TYPE SCARR,
        it_scarr type table of SCARR,
        it_cust type table of ty_cust,
        wa_cust type ty_cust.

  select * into CORRESPONDING FIELDS OF table it_scarr from SCARR.
  select * from spfli into CORRESPONDING FIELDS OF table it_cust where carrid = v_carrid.
    LOOP at it_cust into wa_cust.
      read table it_scarr into wa_scarr WITH KEY carrid = wa_cust-carrid.
          if sy-subrc = 0.
          wa_cust-carrname = wa_scarr-carrname.
          endif.
            write: / wa_cust-CITYFROM .
    ENDLOOP.
ENDFORM.

2. function module

也许form过时了,但是function module还没有过时吧。
subroutine一般就是在一个程序内部进行调用,你看到的form一般就放在在这个程序的F的include里面。那么对于一个很大的程序,这么调用是可以的,因为你可能程序中需要调用好几次。或者为了看起来方便,给放到一个include里面去。
但是function module是可以在不同的程序间调用的,哪里你都可以调用啊。

function module是附在一个function group里的。只要是这个SAP 系统里的程序,都可以调用function module。
SAP也提供了大量的function module。
谁call这个function module呢,谁可以提供import进这个function module的数据。export呢就是把结果从function module给export出去。
changing 就是一边导入,一边导出。
table呢和changing是一样的,就是它里面只能是内表。
exceptions就是来rasing error的。

function module可以在SAP系统内部任何程序被调用,同时如果是个可以在程序外调用的function module,那它就是一个remote function call,RFC。
在这里插入图片描述
填完了import和export,在source code里面你就能看到了:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在exceptions里面也填上:
在这里插入图片描述
在这里插入图片描述
好了,来这里激活,死活激活不了了:doesn’t begin with function pool
这鬼玩意还给我报了个ABAP的runtime error,光看这个error message,实在看不懂讲的什么鬼东西。
哎,快下班了,心情急躁的很。
在这里插入图片描述
错误里头还是个德文的:指令缺失,或者是程序类型为include。
反正是不知所云。
在这里插入图片描述
最后才发现了根本原因,因为我是连带功能组一起建的,没激活那个,就来直接激活function module。就激活不起来。
鬼玩意干啥啥都要激活。
在这里插入图片描述
激活还让我找了半天。
在这里插入图片描述
激活后,这个function module就可以被其他的program调用了。
那么怎么调用呢?
调用的话好歹得告诉人家你用什么参数跑吧。
就是这么个调法。写写玩还是很有意思的。代码这玩意,教是教不会的,只能自己去写,去用。
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaomici

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值