ABAP 辨析ON INPUT|REQUEST|CHAIN-INPUT|CHAIN-REQUEST

2023-02-21 21:01:49

1、邏輯流

在螢幕開發中,存在如下邏輯流:

PBO(Process Before Output):螢幕輸出之前觸發

PAI(Process After Input):使用者在螢幕中執行操作觸發

POH(Process On Help-Request):檢視幫助資訊觸發(F1)

POV(Process On Value-Request):查詢搜尋幫助觸發(F4)

其中PBO為輸出流,PAI為輸入流,POH和POV可籠統理解為輸入流

2、語句控制傳遞FIELD

在螢幕開發中,系統會自動將螢幕的值傳遞到程式中與之同名的全域性欄位中。

但是如果使用語句控制語法FIELD,則FIELD指定的欄位的值,將會出現賦值延遲,資料不是自動同步到ABAP程式,而是在執行FIELD語句時,對應的欄位值會傳遞到程式中。

例如:在螢幕中新增物料和物料描述兩個欄位

 邏輯流如下:

PROCESS BEFORE OUTPUT.
  MODULE status_9000.

PROCESS AFTER INPUT.
  MODULE get_text."獲取物料描述
  FIELD makt-matnr.
  MODULE get_text."獲取物料描述

GET_TEXT

MODULE get_text INPUT.
  IF makt-matnr IS NOT INITIAL.
    SELECT SINGLE
      maktx
    FROM makt
    INTO makt-maktx
    WHERE matnr = makt-matnr
      AND spras = sy-langu.
  ELSE.
    CLEAR:makt-maktx.
  ENDIF.
ENDMODULE.

使用FIELD,導致螢幕中MAKT-MATNR必須執行到FIELD makt-matnr.時,makt-matnr才有值。第一個get_text查詢不到物料描述,第二個get_text才能查到。

3、模組條件呼叫語法

3.1 單一欄位條件呼叫

3.1.1 ON INPUT

FIELD makt-matnr MODULE get_text ON INPUT.
1.當Field語句的欄位為非初始值(非空值或零)時,才呼叫MOD;
例如輸入物料號,改變了欄位非初始值狀態,則會呼叫MOD查詢到物料描述

2.使用者將欄位值改為初始值,則不觸發MOD

例如把物料號置空,並沒有執行清空物料描述的邏輯

 3.如果使用者不輸入,而是直接在程式碼中為物料賦值,也等同於改變了初始值,則會觸發MOD

makt-matnr = '000000010000000002'.
CALL SCREEN '9000'.

3.1.2 ON REQUEST

FIELD makt-matnr MODULE get_text ON REQUEST.

1.只有當用戶輸入值時,才呼叫MOD。任何形式手工輸入,都可以觸發;

系統按照如下方式設定欄位,也被視為手工輸入:

  • 通過SET PARAMETER欄位輸入(手工和自動)
  • 通過HOLD DATA功能設定欄位輸入(System→User Profile→Hold data中設定)
  • 用於事務呼叫時的引數輸入(CALL TRANSACTION...USING)
  • 用於整個客製化系統的全域性欄位

例如輸入物料號,則會呼叫MOD查詢到物料描述

 2.如果清空物料號,也等同輸入操作,則執行了清空物料描述的邏輯

 3.如果使用者不輸入,而是直接在程式碼中為物料賦值,則不會觸發MOD

makt-matnr = '000000010000000002'.
CALL SCREEN '9000'.

3.2 組合欄位條件呼叫

3.2.1 ON CHAIN-INPUT|REQUEST

如果螢幕中多個欄位滿足條件就要呼叫該MOD,則需要用CHAIN和ENDCHAIN將FIELD包裹起來,並使用ON CHAIN-INPUT|REQUEST,形成組合
PROCESS AFTER INPUT.

  CHAIN.
    FIELD:marc-werks,makt-matnr.
    MODULE check_matnr ON CHAIN-INPUT.
    MODULE get_text.
  ENDCHAIN.

  MODULE user_command_9000.

檢查物料在工廠下是否存在

MODULE check_matnr INPUT.
  SELECT SINGLE
    *
  FROM marc
  INTO @DATA(ls_marc)
  WHERE werks = @marc-werks
    AND matnr = @makt-matnr.

  IF ls_marc IS INITIAL.
    MESSAGE '物料在工廠下不存在' TYPE 'E'.
  ENDIF.
ENDMODULE.

其中使用的ON CHAIN-INPUT 和 ON CHAIN-REQUEST的使用與ON INPUT和ON REQUEST幾乎相同。

區別就是,組合欄位中如果使用了ON CHAIN-INPUT|REQUEST,有任意欄位能符合INPUT與REQUEST同理的要求,就會觸發MOD。
例如按照以上程式碼只輸入了工廠,但是已經改變了工廠的初始值,符合INPUT條件,所以就呼叫MOD
而get_text則始終會被呼叫
當出現錯誤時,組合欄位則要求重新輸入,其他非組合欄位則置灰不可輸入

但是在CHAIN語句中,同樣可以只使用ON INPUT將條件的觸發,限制在特定的欄位中,

例如如下程式碼:此時輸入工廠,並不會觸發get_text,只有輸入物料,才會觸發get_text。

  CHAIN.
    FIELD:marc-werks.
    FIELD:makt-matnr MODULE get_text ON INPUT.
  ENDCHAIN.

而下列程式碼:使用ON CHAIN-INPUT無論輸入工廠還是物料,都會觸發get_text。這就是ON INPUT|REQUEST 和 ON CHAIN-INPUT|REQUEST的區別

  CHAIN.
    FIELD:marc-werks.
    FIELD:makt-matnr MODULE get_text ON CHAIN-INPUT.
  ENDCHAIN.