ABAP 程序间传递数据

ABAP 提供了 IMPORT/EXPORT 和 SET/GET PARAMETER 语句,可对用户内存/服务器内存/数据库进行存储和访问。不过可能很多人对此还不是很了解,下面我们通过实例来测试它们的区别和联系。

1. ABAP Memory

用户登陆后,最多一个系统可以开 6 个窗口,这在 SAP 中称为 External Mode。

而同一个窗口中,运行某程序后,可以通过 CALL TRANSACTION/SUBMIT 或其他代码跳转到其他程序,这个称为 Internal Mode。Internal Mode 的调用栈最多为 9 层。

那么 ABAP Memory,它是属于 Internal Mode 间可以共享的数据,而 External Mode 间无法共享。

 

例子. 创建程序 A,输入:

DATA matnr TYPE matnr.

IMPORT matnr FROM MEMORY ID 'YTEST_MATNR'.

WRITE matnr.

创建程序 B,输入:

DATA matnr TYPE matnr.

matnr = '000000000000001234'.

EXPORT matnr TO MEMORY ID 'YTEST_MATNR'.

SUBMIT y_program_a. "调用程序A

直接运行 B,发现程序 A 从 ABAP Memory 读到了值并输出到 LIST.

说明:

  1. 调试运行 B 到 EXPORT 语句后面,Goto-System Area-ABAP Memory,可以查看到名为 YTEST_MATNR 的一片内存。

  2. 如果 B 和 A 运行在不同的窗口,则 A 将访问不到数据;当用户输入/N 退出当前程序时,内存值也将被清空。

  3. 该语句适用于 CALL TRANSACTION/SUBMIT 过程中的数据共享,也常用于 User Exit,类似于定义全局变量的效果。

2. SAP Memory

上面说了 External Mode,那么它们之间共享数据必须通过 SET/GET PARAMETER 语句,不再是 EXPORT/IMPORT 的模式。

 

例子. 创建程序 A,输入:

DATA matnr TYPE matnr.

GET PARAMETER ID 'YTEST' FIELD matnr.

WRITE matnr.

创建程序 B,输入:

DATA: matnr TYPE matnr.

matnr = '000000000000012345'.

SET PARAMETER ID 'YTEST' FIELD matnr.

在窗口 1 运行程序 B 并关闭后,在窗口 2 运行程序 A,发现程序 A 仍然读到了 SAP Memory 的值。

 

说明:

  1. 调试时,可通过 Goto-System Area-SAP Memory,查看到 YTEST 及其对应的值。

  2. SET/GET PARAMETER 的值与本次登陆有关,当用户注销后才失效。在用户登陆的时候,系统会根据每个用户 User Profile-Own Data-Parameter 下的设置,载入到 SAP Memory。

  3. Data Element 中可以看到 Further Characteristics 下可定义 PARAMETER ID,代表该字段作为屏幕元素时,可读取该 PARAMETER ID 作为默认值。比如 VA03 会自动显示刚刚创建的订单号。

3. SHARED MEMORY/SHARED BUFFER

前面介绍的都是用户内存,那么不同用户间如何实现数据共享呢?可以用 SHARED MEMORY 或 SHARED BUFFER,它们是服务器上的某片所有用户共享的内存。关于 SHARED MEMORY 和 SHARED BUFFER 的区别,可以 F1 查看帮助。如果 EXPORT SHARED BUFFER,则必须 IMPORT SHARED BUFFER 才能读到,用 IMPORT SHARED MEMORY 是读不到的。反过来也是。

 

例子. 创建程序 A,输入:

DATA matnr TYPE matnr.

IMPORT matnr FROM SHARED BUFFER indx(aa) ID 'YTEST_MATNR'.

WRITE matnr.

创建程序 B,输入:

DATA: matnr TYPE matnr.

matnr = '000000000000123456'.

EXPORT matnr TO SHARED BUFFER indx(aa) ID 'YTEST_MATNR'.

先在用户 1 的电脑上运行程序 B,然后在用户 2 的电脑上运行程序 A,发现用户 2 可以读取到值。

 

说明:

  1. 既然是服务器上的所有用户共享空间,那么该值将保存到服务器关机重启为止,除非用户用 DELETE 语句清除它。其实这个跟 ENQUEUE/DEQUEUE 有点相似之处。

  2. 数据库也可共享数据,不过服务器共享肯定速度快些,理论上适合网络游戏,呵呵。

  3. INDX 是系统中存在的符合特定格式要求的表。但这不代表该 EXPORT/IMPORT 语句将在表 INDX 中增加记录,仅仅代表服务器借用了 INDX 的结构来管理该片共享内存。

4. DATABASE

上面说了 SHARED BUFFER 并不访问数据库,而要访问数据库就应该用 DATABASE。

创建一个程序,录入代码:

DATA: matnr TYPE matnr.

matnr = '000000000000004321'.

EXPORT matnr TO DATABASE indx(aa) ID 'YTEST_MATNR'.

执行程序,然后 SE16 查看表 INDX,发现新增了一条 RELID = AA, SRTFD = YTEST_MATNR 的记录。如果 EXPORT 的数据量比较大,则新增的将是多条,这些条目的字段值 SRTF2 从 0 递增。所以 EXPORT DATABASE 与普通数据库操作的不同之处是,它适合大数据量的操作,系统自动将其拆分成多条记录并存储到数据库中,比如图片或文档。而用 IMPORT DATABASE 的过程则相反,系统将把这些条相关记录又自动组合起来成为一个整体。

5.程序跳转

  • SET PARAMETER语句赋值,使用CALL TRANSACTION语句跳转屏幕

    • SET PARAMETER ID 'AUN' FIELD '111'.
      CALL TRANSACTION 'VA03' AND SKIP FIRST SCREEN.
  • MM03指定跳转到某个页签

    • SET PARAMETER ID 'MXX' FIELD I_PSTAT.
      SET PARAMETER ID 'MAT' FIELD I_MATNR.
      SET PARAMETER ID 'WRK' FIELD I_WERKS.
      SET PARAMETER ID 'LAG' FIELD I_LGORT.
      SET PARAMETER ID 'BWT' FIELD I_BWTAR.
      CALL TRANSACTION 'MM03' AND SKIP FIRST SCREEN.
    • 其中根据维护状态“PSTAT”判定显示哪个页签。

      维护状态 (K,E,D,B,L,A)

      A Work scheduling
      B Accounting
      C Classification
      D MRP
      E Purchasing
      F Production resources/tools
      G Costing
      K Basic data
      L Storage
      P Forecasting
      Q Quality management
      S Warehouse management
      V Sales
      X Plant stocks
      Z Storage location stocks

  • 事务代码MIGO无法使用“SET PARAMETER”的跳转。

    因为有些字段是没有parameter ID的,这时要通过调用函数MIGO_DIALOG进行跳转。

    操作可以在 MIGO 事务中执行“GOACTION”:

    A01 收货
    A02 返回交货
    A03 取消
    A04 显示
    A05 下达收货冻结库存
    A06 后续交货
    A07 发货
    A08 转移过帐
    A09 出库
    A10 入库
    A11 后续调整

    参考凭证-事务 MIGO“REFDOC”:

    R01 采购订单
    R02 物料凭证
    R03 交货单
    R04 内向交货
    R05 外向交货
    R06 传送
    R07 运输标识代码
    R08 订单
    R09 预留
    R10 其他

    • CALL FUNCTION 'MIGO_DIALOG'
        EXPORTING
          I_ACTION            = 'A04'
          I_REFDOC            = 'R02'
      *   I_NOTREE            = 'X'
      *   I_NO_AUTH_CHECK     =
      *   I_SKIP_FIRST_SCREEN = 'X'
      *   I_DEADEND           = 'X'
      *   I_OKCODE            = 'OK_GO'
      *   I_LEAVE_AFTER_POST  =
      *   I_NEW_ROLLAREA      = 'X'
      *   I_SYTCODE           =
      *   I_EBELN             =
      *   I_EBELP             =
          I_MBLNR             = '4900000174'
          I_MJAHR             = '2013'
      *   I_ZEILE             =
      *   I_TRANSPORT         =
      *   I_ORDER_NUMBER      =
      *   I_ORDER_ITEM        =
      *   I_TRANSPORT_MEANS   =
      *   I_TRANSPORTIDENT    =
      *   I_INBOUND_DELIV     =
      *   I_OUTBOUND_DELIV    =
      *   I_RESERVATION_NUMB  =
      *   I_RESERVATION_ITEM  =
      *   EXT                 =
        EXCEPTIONS
          ILLEGAL_COMBINATION = 1.
  • 调用别的程序的ALV数据并返回

  •   TYPES:BEGIN OF ty_alv,
              9000  TYPE pc2b6-anzhl,  "实际出勤小时数
              9014  TYPE pc2b6-anzhl,
              9015  TYPE pc2b6-anzhl,
            END OF ty_alv .
    
      DATA:lt_alv TYPE TABLE OF ty_alv,
           ls_alv TYPE ty_alv.
      
      DATA: lo_data TYPE REF TO data.
      FIELD-SYMBOLS: <lt_data> TYPE table,
                     <l_data>  TYPE data.

           "设置调用 alv 不显示屏幕"
          cl_salv_bs_runtime_info=>set( display = '' metadata = '' data = 'X' ).

    "调ZHRR008程序 将返回的ALV数据进行处理
        SUBMIT zhrr008
          WITH pnptimed EQ lv_pnptimed
          WITH pnpbegda EQ lv_datum
          WITH pnppernr IN r_pernr
          WITH p_h EQ 'X'
           AND RETURN.
        cl_salv_bs_runtime_info=>clear_all).
        TRY.
            cl_salv_bs_runtime_info=>get_data_ref(
                   IMPORTING
                     r_data = ls_data
            ).
            ASSIGN lo_data->* TO <lt_data>.
          CATCH cx_salv_bs_sc_runtime_info.
            MESSAGE 'UNABLE TO RETRIEVE ALV DATA' TYPE 'E'.
        ENDTRY.
    
        READ TABLE <lt_data> ASSIGNING <l_data> INDEX 1.
        IF sy-subrc EQ 0.
          MOVE-CORRESPONDING <l_data> TO ls_alv.
          "正班小时
          gs_data-z9000 = ls_alv-9000.
          "平时加班小时
          gs_data-z9014 = ls_alv-9014.
          "周末加班小时
          gs_data-z9015 = ls_alv-9015.
          "出勤总小时 = 正班小时+平时加班小时+周末加班小时
          gs_data-sum_anzhl = gs_data-z9000 + gs_data-z9014 + gs_data-z9015.
        ENDIF.  
    cl_salv_bs_runtime_info=>clear_all).
  • 转载于:https://www.cnblogs.com/hhelibeb/articles/5799606.html

 

posted @ 2022-08-04 12:36  阿胖的阿多  阅读(498)  评论(0编辑  收藏  举报