Messages消息處理


Messages

消息維護

所有的消息都是存儲在T100表里的,可以使用SE91事務碼來維護:

image483

00系統消息ID(8占位符)

MESSAGE e001(00) WITH 'No local currecny maintained for company:' p_bukrs.

上面的00為系統預定義的消息類,如下:

image484

從上面可以看出,001這條消息可以傳遞8個參數。

語法規則

使用全局的Message Class

以下程序定義語句后面可以加上選項:...MESSAGE-ID<id>.

image485

這樣在這些類型的的程序里可以這樣來使用MESSAGE語句:

MESSAGE<t><num>[WITH<f1>... <f4>][RAISING<exc>].

REPORT zjzj_test1 MESSAGE-ID 00.
MESSAGE s002.

靜態的指定Message

MESSAGE   <t><nnn>(<id>)  [WITH<f1>... <f4>][RAISING<exc>].

MESSAGE s002(00).

這里在語句中指定了消息ID,如果程序開頭指定了消息Class,則這里也會將它覆蓋,使用此語句中的消息ID

動態的指定Message

MESSAGE ID    <id>         TYPE       <t>           NUMBER           <n>                      [WITH<f1>...<f4>]   [RAISING<exc>].

DATA: t(1) VALUE 'S',
     
id(2) VALUE '00',
      num
(3) VALUE '002'.
MESSAGE ID id TYPE t NUMBER num.

INTO msgtext DISPLAY LIKE dtype選項

這兩個選項對於以上3個(使用全局的Message Class靜態的指定Message動態的指定Message)都有效。

 

使用MESSAGE … INTO…可以很方便拼接BDC執行返回結果:

data: gt_messtab type table of bdcmsgcoll with header line .

call transaction  'VA02' using bdcdata
*                       MODE   'A'

                      
mode   p_runtp
                      
update 'S'

                       messages
into gt_messtab.

  loop at gt_messtab .
   
message id gt_messtab-msgid type gt_messtab-msgtyp number gt_messtab-msgnr
                  
with gt_messtab-
msgv1
                   gt_messtab
-
msgv2
                   gt_messtab
-
msgv3
                   gt_messtab
-
msgv4
                  
into l_msg.

 
endloop.

DATA mtext TYPE string.
CALL FUNCTION ... EXCEPTIONS error_message = 4.
IF sy-subrc = 4.
 
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-
msgno
         
INTO
msgtext
         
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.

 

INTO msgtext選項與Message Type沒有關系(不管是什么類型,即使是X類型,也會將消息存入到msgtext變量中),這不像RAISING選項。

 

DISPLAY LIKE dtype

對於原先就以dialog box方式顯示的消息,仍然還是顯示在dialog box中。

如果dtypeA或者是I類型時,EW類型的消息(除開PBOLOAD-OF-PROGRAM)將會在dialog box中顯示。

不管dtype類型為什么,S類型的消息都會顯示在狀態欄中,PBOLOAD-OF-PROGRAM中的I類型消息也是這樣。

X類型消息總會引起運行時錯誤。

注:此種方式不會影響到消息本身的性為處理,只是改變了消息的顯示類型(圖標),如下面只是改變了S類型消息在狀態欄中以錯誤圖標來顯示:

 MESSAGE  msg  TYPE 'S' DISPLAY LIKE 'E'.

直接顯示消息常量,不引用消息ID與消息號

MESSAGE msgtext TYPE c

MESSAGE 'aaaa' TYPE 'S'.

選項">RAISING <exc>選項:消息以異常形式拋出(是否以異常形式拋出還要看主調函數是否捕獲了)

該選項對於以上4個(使用全局的Message Class靜態的指定Message動態的指定Message直接顯示消息常量)都有效。

  MESSAGE ID 'SABAPDEMOS' TYPE MESSAGE_TYPE NUMBER '777'
         
WITH
MESSAGE_TYPE MESSAGE_PLACE MESSAGE_EVENT
 
RAISING MESS.

RAISING 后面接的是異常名(如下面的MESS異常)只有在FunctionClass中定義的異常,才能用在RAISING選項的后面,具體使用過程如下:

image486

image487

image488

當使用該選項后,並且如果在調用的地方(CALL FUNCTION或者是 CALL METHOD的地方)使用了EXCEPTION選項來捕獲RAISING拋出的異常,則不再以MESSAGE的原有形式來顯示消息,而是被主調捕獲后進一步處理或者是程序DumpAEIWS類型都能被捕獲到,但X類型的Message不會走到被主調者捕獲這一步,因為在被調程序中就宕掉了);反過來,當主調者未使用EXCEPTION選項(或者使用了但未捕獲到所拋出的異常),則RAISING選項會被忽略MESSAGE語句會按照無RAISING選項時那樣運行(彈框還是在狀態欄中顯示、以及程序是否終止等性為)

下面程序中,第一次調用時中會彈出消息框(因為沒有使用EXCEPTIONS選項捕獲),而第二次不會彈出消息框,也不會在狀態欄中顯示,而是被后繼程序捕獲后輸出:

CLASS c1 DEFINITION.
 
PUBLIC SECTION.
   
CLASS-METHODS
m1 EXCEPTIONS exc1.
ENDCLASS.
CLASS c1 IMPLEMENTATION.
 
METHOD m1.
   
MESSAGE 'Message in a Method' TYPE
'I' RAISING exc1.
 
ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
c1
=>m1( ).
c1
=>m1
( EXCEPTIONS exc1 = 4 ).
IF sy-subrc = 4.
 
write: / '被捕獲'.
ENDIF.

 

下面也不會顯示錯誤消息,E類型消息(注:不是異常,是消息)被error_message所捕獲了

FUNCTION ZJZJ_FUNC1.
 
MESSAGE id '00'  TYPE 'E' NUMBER 001 WITH '1' '2'.
ENDFUNCTION.

REPORT  ZJZJTEST.
CALL FUNCTION 'ZJZJ_FUNC1'
 
EXCEPTIONS

   
error_message = 4.
if sy-subrc <> 0.
 
WRITE: / '被捕獲'.
ENDIF.

 

 

RAISING異常后,與消息相關的信息分別存儲到相應系統字段中:
SY-MSGID 消息類
SY-MSGNO消息號
SY-MSGTY 消息類型
SY-MSGV1 ... SY-MSGV4 
消息參數

CLASS c1 DEFINITION.
 
PUBLIC SECTION.
   
CLASS-METHODS m1 EXCEPTIONS exc1.
ENDCLASS.
CLASS c1 IMPLEMENTATION.
 
METHOD m1.
   
MESSAGE id '00'  TYPE 'I' NUMBER 001 WITH '1' '2' RAISING exc1.
 
ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  c1
=>m1( EXCEPTIONS exc1 = 4 ).
 
IF sy-subrc = 4.
   
write: / SY-MSGID.
   
write: / SY-MSGNO.
   
write: / SY-MSGTY.
   
write: / SY-MSGV1.
   
write: / SY-MSGV2.
 
ENDIF.

00
001
I
1
2

CALL FUNCTION[error_message]

CALL FUNCTION func ...[EXCEPTIONS[exc1= n1    exc2= n2 ...]
[
others= n_others] ].
[
error_message = n_error]

exc1exc2...OTHERS異常只能捕獲到MESSAGE...RAISING選項或RAISE語句拋出的異常,即MESSAGE...RAISINGRAISE拋出的異常只能被exc1exc2...OTHERS異常所捕獲,而error_message是無法捕獲MESSAGE...RAISINGRAISE拋出的異常的。

error_message為系統內置的隱式性異常,主用來捕獲那些未使用RAISING選項的A、E兩類消息(注:error_message的作用是用來捕獲消息,而不是針對MESSAGE...RAISINGRAISE拋出的異常)

在主調程序中使用error_message來捕獲Message請參考:在主調程序中捕獲Message

MESSAGE中的RAISING<exc1...exci>拋出異常時,如果在Call FunctionException列表中有exc1...exciothers異常,則會優先exc1...exciothers捕獲到;否則RAISING選項將直接被忽略掉,MESSAGE會被error_message所捕獲(前提是在CALL FUNCTION時,加上了error_message異常,且不管MESAGGE為任何類型,此時都不會再顯示MESSAGE,具體請參考在主調程序中捕獲Message中的12兩點說明):

image489

REPORT  ZJZJTEST.
CALL FUNCTION 'ZJZJ_FUNC1'
 
EXCEPTIONS
    ERROR_MESSAGE
= 5
    "如果注釋掉下面E類型異常捕獲列表,則會輸出2
    "
否則,像這里就會輸出1
        E
= 4
       D
= 6.
if sy-subrc = 4.
 
WRITE: / '1'.
ENDIF.
if sy-subrc = 5.
 
WRITE: / '2'.
ENDIF.

RAISE語句(觸發異常)

Function Module里有兩種方式觸發異常(注:下面二種也只能在Function Module使用):

l  RAISE <except>.

l  MESSAGE..... RAISING <except>.

這些語句的作用依賴於主調程序中是否處理<except>異常。如果異常<except>或者others出現在了CALL FUNCTION語句中的EXCEPTIONS選項中,<except>異常將會被主調程序所捕獲。如果主調程序沒有捕獲<except>異常,則:

l  RAISE 語句會終止程序並且切換到debug模式

l  MESSAGE ..... RAISING語句會根據message type來像MESSAGE語句那樣正常顯示消息(前提條件是要在CALL FUNCTION 語句中使用error_message來捕獲消息)

一旦主調程序捕獲了異常,以上兩種觸發異常的方式都會返回到主調程序,並且不會返回值Function Module參數輸出)。MESSAGE ..... RAISING語句也不會再顯示消息,而是將相關的信息填充到SY-MSGID, SY-MSGTY,SY-MSGNO, and SY-MSGV1 to SY-MSGV4這些系統變量中(即使是I,S,W三種消息類型也會設置這些系統變量

 

RAISE [RESUMABLE] EXCEPTION { { TYPE cx_class [EXPORTING p1 = a1 p2 = a2 ...]} | oref }.

cx_class為異常ClassEXPORTING為構造此異常類的構造參數,oref可以是已存在的異常Class引用,如:

DATA oref TYPE REF TO cx_root.
DATA:text TYPE string , result TYPE i.
TRY .
   
TRY.
        result
= 1 / 0.
     
CATCH cx_sy_zerodivide INTO oref.
       
text = oref->get_text( ).

       
RAISE EXCEPTION oref."捕獲后繼續向外層拋出在函數里不需Exception選項,請參考下面示例(可能拋出是non-class-based exceptions,而不是class-based exceptions吧?
   
ENDTRY.
 
CATCH cx_root INTO oref.
   
text = oref->get_text( ).
   
WRITE: / text.
ENDTRY.

RAISE EXCEPTION語句一般用來拋出基於Class的異常類class-based exceptions,而RAISE一般是直接用來拋出 non-class-based exceptions,如:

image490

FUNCTION ZJZJ_FUNC1.
 
RAISE e.
ENDFUNCTION.

 

REPORT  ZJZJTEST.
CALL FUNCTION 'ZJZJ_FUNC1'
 
EXCEPTIONS
   
OTHERS = 4.
if sy-subrc = 4.
 
WRITE: / '1'.
ENDIF.

 

RESUMABLE選項

表示可恢復的異常,可以在CATCH塊里使用RESUME語句直接跳到拋出異常語句后面繼續執行,RESUME后面語句不再被執,CLEANUP塊也不會被執行。該選項只能用於BEFORE UNWIND類型的CATCH塊中:

DATA oref TYPE REF TO cx_root.
DATA text TYPE string.
DATA i TYPE i.
TRY .
   
RAISE RESUMABLE EXCEPTION TYPE cx_demo_constructor
     
EXPORTING

        my_text
= sy-repid.
   
i = i + 1.
   
WRITE: / i
.
CATCH BEFORE UNWIND cx_demo_constructor INTO oref .
   
text = oref->get_text( ).
   
IF i < 1.

     
RESUME.
   
ENDIF.
   
WRITE:/ '--'.
ENDTRY.

結果只輸出 1

 

Message Types

 

 

X

Exit

退出

Nomessageis displayed,andtheprogramterminateswitha shortdump. Programterminationswithashortdumpnormallyonlyoccurwhena runtimeerroroccurs.MessagetypeX allowsyoutoforceaprogram termination.TheshortdumpcontainsthemessageID.

消息不會顯示,程序會終止並伴隨着shortdump.信息。程序終止一般是由於運行時錯誤,但X消息允許你強迫終止程序。運行時會產生錯誤,屏幕顯示異常的堆棧信息

 

A

Abend

終止

Themessageappearsinadialogbox,andtheprogramterminates.Whentheuserhasconfirmedthemessage,controlreturnstothenext- highestareamenu.

此種消息只能以模式對話框來顯示,並且會終止當應用程序。當用戶確認后,控制權返回到最高層區域菜單所在屏幕,即“SAP Easy Access”初始屏幕:程序被取消

image491

 

E

Error

錯誤

Depending ontheprogram context, an errordialogappearsorthe programterminates.

依賴於程序上下文(可能顯示在對話框中或狀態欄),顯示錯誤對話框或者是終止程序(工具條按鈕變灰,但不會中轉到SAP Easy Access屏幕)

 

W

Warning

警告

Depending ontheprogram context, an errordialogappearsorthe programterminates.

依賴於程序上下文(可能顯示在對話框中或狀態欄上),顯示錯誤對話框或者是終止程序(工具條按鈕變灰,但不會中轉到SAP Easy Access屏幕)

 

I

Information

消息

Themessageappearsinadialogbox.Oncetheuserhasconfirmedthemessage,theprogramcontinuesimmediatelyaftertheMESSAGE statement.

此種類型的消息只會出現在顯示在對話框。一旦用戶確認了對話框,程序將繼續執行MESSAGE語句后面的語句

 

S

Status

狀態

TheprogramcontinuesnormallyaftertheMESSAGEstatement,andthemessageisdisplayedinthestatusbarof thenextscreen.

程序會繼續執行MESSAGE后面的語句,並且消息將顯示在下一屏幕的狀態欄中(如果沒有下一屏幕,則顯示在本屏幕的狀態欄中)。程序不會被中斷

消息顯示及處理

Messages可以以模式對話框或者在屏幕的狀態欄中顯示,這究竟如何顯示,則依賴限Messages的類型與運行時MESSAGE語句所在上下文環境。

特別是是E  W類型的消息,它們的行為與所在的程序上下文相關。

非屏幕PAI事件塊中

適用所有不屬於任何屏幕處理事件塊。非屏幕處理包括以下事件塊:

n  PBO(PBO of screens):對話屏幕的PBO

n  The selection screen event AT SELECTION-SCREEN OUTPUT(PBO of a selection screen)選擇屏幕的PBO

n  報表程序事件塊:INITIALIZATIONSTART-OF-SELECTIONGETEND-OF-SELECTION

n  列表事件塊TOP-OF-PAGEEND-OF-PAGE

 

另:此節具體的各種情況下的演示,還可以通過 DEMO_MESSAGES程序(SAP自帶的各種情況下的Message測試)此節的程序來演示

類型

Display顯示

(顯示在對話框中還是狀態欄中)

Processing處理(是終止程序還是繼續,以及終止時返回到哪里)(注:顯示及處理是不一樣的

X

None

不顯示信息

image492

Triggers a runtime error with short dump

觸發運行時錯誤並伴隨着dump

A

Dialogbox以對話框形式顯示:

image493

Programterminates,andcontrolreturnstolastarea menu

並且會終止當應用程序,控制權返回到“SAP Easy Access”初始屏幕

E

In PBO context,the same as type A, otherwise statusbar

PBO塊里與A類型相同(指顯示方式相同,即以對話框形式顯示):

image494

否則(指那些上面除PBO以外的事件塊——INITIALIZATIONSTART-OF-SELECTIONGETEND-OF-SELECTIONTOP-OF-PAGEEND-OF-PAGE)顯示在狀態欄中(此種情況貼圖在右邊)。

In PBO context like type A,

otherwise,program terminates and control returns to pointfrom which the program was called

PBO塊里與A類型消息相同(指處理方式相同,即退出應用程序,並跳轉到歡迎屏幕);否則,程序終止,但控制權返回到該程序被調用的地方(指界面停留在運行前的地方):

image495

W

In PBO context,thes a meas type S, otherwise statusbar

PBO里與S類型相同:

image496

否則顯示在狀態欄中(此種情況貼圖在右邊)。

In PBO context like type S,otherwise,program terminates andcontrol returns to point from which the program was called

PBO中與S類型相同

否則,程序終止,並且控制權返回到程序被調用的地方(指界面停留在調用前的地方)

image497

I

In PBO context,thes a meas type S,otherwise dialogbox

PBO里與S類型相同:

image498

否則以對話框的形式顯示(此種情況貼圖在右邊)。

Program continues processing after the MESSAGE

Statement

程序會繼續向下執行

image499

S

Status bar of next screen

消息會顯示在下一屏幕的狀態欄中(前提是有下一屏幕):

image500

如果沒有下一屏幕,則顯示在當前屏幕的狀態欄中(此種情況貼圖在右邊)。

Program continues processing after the MESSAGE Statement

程序會繼續向下執行

image501

 

 

 

 

 

 

 

 

 

 

 

屏幕中(對話屏幕)

會影響用戶的的輸入性為。屏幕處理即所有的PAI modules

另:此節具體的各種情況下的演示,還可以通過 DEMO_MESSAGES程序(SAP自帶的各種情況下的Message測試)此節的程序來演示

類型

Display顯示

(顯示在對話框中還是狀態欄中)

Processing處理

(是終止程序還是繼續,以及終止時返回到哪里)

X

None

不會顯示消息

image502

Triggers a runtime error with short dump

觸發運行時錯誤並伴隨着dump

A

Dialog box以對話框顯示image503

Program terminates, and control returns to last area menu

並且會終止當應用程序,控制權返回到歡迎屏幕

E

Status bar在狀態欄中顯示

image504

PAI processing is terminated, and control returns to the

current screen. All of the screen fields for which there is a

FIELD or CHAIN statement are ready for input. The user

must enter a new value. The system then restarts PAI

processing for the screen using the new values. Error

messages are not possible in POH or POV processing.

Instead, a runtime error occurs.

PAI處理結束,並且控制權返回到當前屏幕MESSAGE所在的Module所屬的FIELDCHAIN所對應的字段全部可以重新輸入(其他不在FIELDCHAIN中的字段會灰掉,以及即使在其他FIELD或其他CHAIN中的字段如果通過驗證了的也會灰掉。變灰就意味着驗證已通過,無需才輸入),且用戶必須重新輸入新的值。然后系統將重新對新輸入的值進行PAI處理。注:Error消息將不能用在POHPOV,否則將會發生運行時錯誤

W

Statusbar

在狀態欄中顯示

image505

Like type E, but the user can confirm the message by

pressing ENTER without having to enter new values. The

system then resumes PAI processing directly after the

MESSAGE statement. Warning messages are not possible

in POH or POV processing. Instead, a runtime error occurs.

像類型E一樣(指出彈出警告消息后,哪些屏幕字段變灰,哪些需要重新輸入,這些處理相同)。但用戶可以在不必輸入新的值情況下按回車鍵繼來忽略警告消息,系統會繼續后面的PAI處理。

注:Warning消息將不能用在POHPOV,否則將會發生運行時錯誤

I

Dialog box對話框中顯示

image506

Program continues processing after the MESSAGEStatement

程序會繼續向下執行

S

Status bar of next screen

消息會顯示在下一屏幕的狀態欄中

image507

Program continues processing after the MESSAGEStatement

程序會繼續向下執行

選擇屏幕中

包括AT SELECTION-SCREEN及所有帶ON選項的AT SELECTION-SCREEN,但不包括AT SELECTION-SCREEN OUTPUT具體有哪些事件請參考這里

另:此節具體的各種情況下的演示,還可以通過 DEMO_MESSAGES程序(SAP自帶的各種情況下的Message測試)此節的程序來演示

類型pe

Display顯示

(顯示在對話框中還是狀態欄中)

Processing處理

(是終止程序還是繼續,以及終止時返回到哪里)

A

Dialogbox以對話框顯示

image508

Program terminates, and control returns to last area menu

並且會終止當應用程序,控制權返回到歡迎屏幕

E

Statusbar

在狀態欄中顯示

image509

Selection screen processing terminates, and the selection

screen is redisplayed. The screen fields specified through

the additions to the AT SELECTION-SCREEN statement

are ready for input. The user mustenter a new value. The

system then restarts the selection screen processing using

the new values. You cannot use error messages with the

ON HELP-REQUEST or ON VALUE-REQUEST additions.

Instead, a runtime error occurs.

選擇屏幕處理結束,並且控制權返回到選擇屏幕重新顯示。

AT SELECTION-SCREEN ON中的字段將可以重新輸出(如果是發生在AT SELECTION-SCREEN里,則所有屏幕字段都是可以重新輸入的),並且用戶必須輸入新的值,系統然后重新對新輸入的值進行處理,如果驗證通過(不再彈出錯誤消息),則是繼續后面的屏幕事件處理。

不能將error消息與ON HELP-REQUEST or ON VALUE-REQUEST選項的AT SELECTION-SCREEN一起使用,否則出現運行時錯誤

W

Statusbar

在狀態欄中顯示
image510

Like type E, but the user can confirm the message by

pressing ENTER without having to enter new values. The

system then resumes selection screen processing directly

after the MESSAGE statement. You cannot use warning

messages with the ON HELP-REQUEST or ON VALUEREQUEST

additions. Instead, a runtime error occurs.

像類型E一樣(指出彈出警告消息后,哪些屏幕字段變灰,哪些需要重新輸入,這些處理相同)。但用戶可以在不必輸入新的值情況下按回車鍵繼來忽略警告消息,系統會繼續后面的PAI處理。

注:不能將warning消息與ON HELP-REQUEST or ON VALUE-REQUEST選項的AT SELECTION-SCREEN一起使用,否則出現運行時錯誤

I

Dialogbox

對話框中顯示

image511

Program continues processing after the MESSAGEStatement

程序會繼續向下執行

S

Statusbarof nextscreen

消息會顯示在下一屏幕的狀態欄中

image512

Program continues processing after the MESSAGEStatement

程序會繼續向下執行

X

None

不會顯示消息

image513

Triggers a runtime error with short dump

觸發運行時錯誤並伴隨着dump

List輸出列表事件中

適用於所有列表處理list is being processed

2  AT LINE-SELECTION

2  AT USER-COMMAND

2  AT PF<nn>

2  TOP-OF-PAGE DURING LINE-SELECTION

另:此節具體的各種情況下的演示,還可以通過 DEMO_MESSAGES程序(SAP自帶的各種情況下的Message測試)此節的程序來演示

類型

Display顯示(顯示在對話框中還是狀態欄中)

Processing處理(是終止程序還是繼續,以及終止時返回到哪里)

A

Dialogbox以對話框顯示

Program terminates, and control returns to last area menu

並且會終止當應用程序,控制權返回到歡迎屏幕

E

Statusbar在狀態欄中顯示

Processing block terminates. Previous list levels remaindisplayed.

事件塊處理終止,繼續保留上一級別的List

I

Dialogbox對話框中顯示

Program continues processing after the MESSAGEStatement

程序會繼續向下執行

S

Status bar of next screen

消息會顯示在下一屏幕的狀態欄中

Program continues processing after the MESSAGEstatement

程序會繼續向下執行

W

Statusbar在狀態欄中顯示

Like type E.

像類型E一樣

X

None

不會顯示消息

Triggers a runtime error with short dump

觸發運行時錯誤並伴隨着dump

Messages in Function Modules and Methods

MessageFuncionMethod中有下面兩種不同的功能:Messsage的普通使用、使用Messsage觸發異常

此節具體的各種情況下的演示,還可以通過 DEMO_MESSAGES程序(SAP自帶的各種情況下的Message測試)此節的程序來演示

Messsage的普通使用

如果你在Message詞句中未使用RAISING選項,則它就是一個普通的Message,是不能被調用者所捕獲的,此時Message將會根據上下文來進行顯示與處理

Messsage轉異常(RAISING選項)

如果加了選項RAISING時:MESSAGE... RAISING <exc>此時的Message 的處理方式與是否顯示,就要依賴於主調者在調用時,是否加上了exception <exc>選項:

1、如果調用時沒有帶exception <exc>選項,此時Message語包中的RAISING <exc>選項拋出的異常將會被忽略,Message語句會當作正常消息來處理

2、如果調用時加上了exception <exc>選項對exc 異常進行了捕獲,則不會再顯示消息(但如果即使加上了exception選項,但沒有捕獲到exc異常,則此時會忽略RAISING選項)。只要異常被捕獲,相關消息內容將會入存入到SY-MSGID,SY-MSGTY, SY-MSGNO, and SY-MSGV1 to SY-MSGV4有關系統變量中。

捕獲Messageerror_message

可以Message語句沒有使用RAISING選項的情況下,在主調程序中的Exception參數列表中使用隱式異常error_message選項來捕獲Message,但error_message是否能捕獲得到Message,與消息類型相關:

1、對於WIS類型的消息,將不顯示消息(本來是要顯示的),也不會去設置 sy-subrc = n_error此時還是會將消息的相關信息存儲到SY-MSGID, SYMSGTY,SY-MSGNO, and SY-MSGV1 to SY-MSGV4這些系統變量中

2、對於AE類型消息,也將不顯示提示消息,但會拋出ERROR_MESSAGE異常,即這兩類型的消息會自動被轉換error_message異常拋出,並終最被CALL FUNCTION Exception異常列表中的error_message異常所捕獲,並設置sy-subrc = n_error。此時與消息相關的信息分別存儲到相應系統字段中:
SY-MSGID 
消息類
SY-MSGNO 
消息號
SY-MSGTY 
消息類型
SY-MSGV1 ... SY-MSGV4 
消息參數

此時,對於A類型消息而言,ROLLBACK WORK語句將會隱式執行

3、對於X類型消息將會拋出runtime error,並且程序會dump

CALL FUNCTION[error_message]

DEMO_MESSAGES程序(SAP自帶的各種情況下的Message測試)

關於Message不同上下文環境的運行情況,請參數SAP自帶的實例程序:DEMO_MESSAGES

下面的程序是從DEMO_MESSAGES拷貝過來,並進行了少量修改,可以對不同情況下,Message的運行情況測試。如果需運行此程序,請先從DEMO_MESSAGES拷貝一份,生成必要的屏幕,再將下面的代碼貼入。

REPORT zjzj_demo_messages.
DATA: ok_code TYPE sy-ucomm,"用來接收對話屏幕傳遞過來的 Function Code
      save_ok
TYPE sy-ucomm,"ok_code的副本,使用副本的原因請參考這里
     
BEGIN OF place,"消息執行所在程序類型復選框
       
report(1) TYPE c,
       
function(1) TYPE c,
        list
(1) TYPE c,
        selscreen
(1) TYPE c,
       
dynpro(1) TYPE c,
     
END OF place,
     
BEGIN OF type,"消息的類型復選框
        a
(1) TYPE c,
        e
(1) TYPE c,
       
i(1) TYPE c,
        s
(1) TYPE c,
        w
(1) TYPE c,
       
x(1) TYPE c,
     
END OF type,
     
BEGIN OF event,"屏幕事件類型復選框
        pai
(1) TYPE c,
        pbo
(1) TYPE c,
     
END OF event,
     
BEGIN OF except,"異常拋出、消息捕獲復選框
       
no(1) TYPE c,
        yes
(1) TYPE c,
       
catch(1) TYPE c,
        nocatch
(1) TYPE c,
     
END OF except,
      message_type
(1) TYPE c,
      message_place
(40) TYPE c,
      message_event
(20) TYPE c.
DATA:msg TYPE string.

"此選擇屏幕供后面對話屏幕的Module來調用
SELECTION-SCREEN BEGIN OF SCREEN 1100.
   PARAMETERS: input1(10) TYPE c,
            input2
(10) TYPE c.
   SELECTION-SCREEN SKIP.
   SELECTION-SCREEN BEGIN OF LINE.
      SELECTION-SCREEN COMMENT 1(33) text-001.
      PARAMETERS  funct AS CHECKBOX.
      SELECTION-SCREEN COMMENT 38(64) text-015.
   SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN END OF SCREEN 1100.

START-OF-SELECTION.
 
"為對話屏幕上相應字段設置默認值
  place
-report = 'X'.
 
type-i = 'X'.
 
"event-pai = 'X'.
  except
-no = 'X'.
 
"CALL SCREEN 100放在死循環里的調用的效果是:由於100是這里的主屏幕(第一個屏幕)
 
"后續其他的屏幕都是由此屏幕來調用(CALL SELECTION-SCREEN 1100CALL SCREEN 300)新
 
"產生的或者是跳轉得到的(LEVE TO 200)。如果在Module user_command_0100中是通過 LEVE TO 200
 
"跳轉到200對話屏幕的,則在200屏幕上的標准工具欄中點擊了 Back 或者 Exit 按鈕后,則
 
"主屏幕(100)所在的屏幕序列會結束(因為LEVE TO 200就是在主屏幕序列中,所以在200
 
"屏幕中的 LEAVE TO SCREEN 0 最終會結束掉主屏幕所在的屏幕序列),當屏幕序列結事時,序列中的
 
"所有屏幕也會隨之關閉,並返回到被關閉序列所產生之外,即CALL SCREEN 100調用處,此時會繼續執行
 
"CALL SCREEN 100的后續語句,如果果此時不再調用其他屏幕,則整個程序會結束(最終的界面會停留在
 
"ABAP編輯器上——在通過ABAP編輯運行此程序的情況下),所以為了后繼其他情況的Message 測試
 
" CALL SCREEN 100語句的調用就放在了循環中;另一種情況是,如果在Module user_command_0100中是通過
 
"CALL SELECTION-SCREEN 1100CALL SCREEN 300調用產生的新序列屏幕,則在選擇屏幕1100或對話
 
"屏幕300所在的屏幕序列結束時(可點擊選擇屏幕1100標准工具欄中的Back按鈕,或在屏幕邏輯流中使用
 
"LEAVE TO SCREEN 0語句時會結束屏幕序列),不會返回到 CALL SCREEN 100 語句后面的后續語句繼續執行,
 
"而是停留在以前已經顯示出來的主調屏幕100(會調用100屏幕的PBO,重新顯示100屏幕),所以此種情況
 
"下可以省略這個Do...While循環
 
DO.
   
CALL SCREEN 100."全屏方式調用對話屏幕100
   
IF place-report = 'X'.
      message_event
= 'START-OF-SELECTION'.
      message_place
= 'in main program'.
     
PERFORM call_message.
   
ELSEIF place-function = 'X'.
      message_event
= 'START-OF-SELECTION'.
      message_place
= 'in function module from main program'.
     
PERFORM call_function.
   
ENDIF.
 
ENDDO.

************************************************************************
* Dialog Modules                                                       *
************************************************************************
MODULE status_0100 OUTPUT.
 
"在這里控制復制框是否可選(禁止輸入)
 
IF place-report = 'X' OR  place-function = 'X' OR  place-list = 'X' .
   
PERFORM modi_screnn USING '' '0' '' '0'.
 
ENDIF.
 
IF  place-dynpro = 'X' OR place-selscreen = 'X'.
   
PERFORM modi_screnn USING 'X' '0' '' '1'.
 
ENDIF.

 
SET PF-STATUS 'SCREEN_100'.
 
SET TITLEBAR 'TITL_100'.
ENDMODULE.                    "status_0100 OUTPUT

MODULE cancel INPUT.
 
LEAVE PROGRAM.
ENDMODULE.                    "cancel INPUT

MODULE user_command_0100 INPUT.
  save_ok
= ok_code.
 
CLEAR ok_code.
 
"100屏幕上用戶選中的消息轉換成真實的消息類型
 
PERFORM convert_user_input.
 
CASE save_ok.
   
WHEN 'TEST'.
     
"如果選擇的是在 主調程序中 或者是在 Function 執行Message
     
IF place-report = 'X' OR place-function = 'X'.
       
LEAVE TO SCREEN 0."結束當前屏幕序列,返回到主調程序的CALL SCREEN后繼續執行
       
"如果選擇是在對話屏幕中執行Message,則結束當前屏幕100,調轉到200屏幕(不會產生
       
"新的屏幕序列)
     
ELSEIF place-dynpro = 'X'.
       
LEAVE TO SCREEN 200.
       
"如果選擇是在選擇屏幕中執行Message,則會產生一個新的屏幕序列,跳轉1100選擇屏幕
     
ELSEIF place-selscreen = 'X'.
       
"下面是原程序采用CALL方式來調用1100選擇屏幕的,但這種方式會產生一個新的屏幕
       
"序列,結束1100選擇屏幕所有的新屏幕序列后,原主調屏幕100所在的屏幕序列不會消失
       
",所以這種方式下,主調程序中的 CALL SCREEN 100 所在的Do...While就沒有意義了
       
"且點擊標准工具欄上的 Back 按鈕時,該選擇屏幕所在的屏幕序列會結束,返回到 100 屏幕
       
CALL SELECTION-SCREEN 1100.
       
"在這里不能使用下面方式代替上面的CALL SELECTION-SCREEN 1100,否則在第二次調用此語句時
       
"會出錯,具體問題不清
       
"LEAVE TO SCREEN 1100.
       
"如果選擇是在輸出列表List中執行Message,則跳轉到 300屏幕,也不會產生新的屏幕序列
     
ELSEIF place-list = 'X'."如果要求Messge在輸出列表List中調用時
       
"會產生新的屏幕序列,如果此地方運行50次,則最后因為屏幕序列大於50而堆棧溢出,
       
"因為每次運行此語句時,都會產生一個新的屏幕序列,且在離開300屏幕所在
       
"的序列時,並未關掉屏幕序列(status_0300 PBO中設置返回到100屏幕)。但上面的
       
"CALL SELECTION-SCREEN 1100 不會有這樣的問題,因為在按1100所在屏幕的標准工具欄上
       
"Back按鈕時,會結束1100所在的屏幕序列。所以這里最好修改成 LEAVE TO SCREEN 300
       
"這樣在多次調用此處后不會因為產生了50個序列而溢出
       
CALL SCREEN 300.
       
"LEAVE TO SCREEN 300.
     
ENDIF.
   
WHEN 'FC_PLC'."FC_PLC為屏幕上的單先按鈕的Function code
     
"不要在這里控制屏幕字段的可輸入性(比如這里點 Main Program單選按鈕后,
     
"要使屏幕上的 PBOPAI兩個復選框變灰),即不要在這里對SCREEN內表進行修改
     
"而是將修改的代碼直接移到PBO事件塊里。因為在這里即使你修改了SCRENN內表的
     
"值,但在該PAI執行完后,去執行PBO時,SCREEN內表的值又會回到屏幕設計時設定的
     
"的初始設置了,所以在這里直接修改SCREEN是無法將屏幕字段置為灰的,除非在這里
     
"將這些修改設置存儲起來,再在PBO根據這些值來修改SCREEN內表,但這樣顯得麻煩,
     
"還不如直接在PBO中對SCREEN進行修改
   
WHEN OTHERS.
     
"如果是其他情況,則結束整個程序
     
LEAVE PROGRAM.
 
ENDCASE.
ENDMODULE.                    "user_command_0100 INPUT

MODULE status_0200 OUTPUT.
 
SET PF-STATUS 'SCREEN_200'.
 
SET TITLEBAR 'TITL_200'.
 
"如果設置的是在對話屏幕的 PBO 事件塊中執行Message
 
IF event-pbo = 'X'.
    message_event
= 'PBO'.
    message_place
= 'on dynpro'.
   
"在對話屏幕的PBO里並沒有通過調用函數方式去執行Message
   
PERFORM call_message.
 
ENDIF.
ENDMODULE.                    "status_0200 OUTPUT

MODULE user_command_0200 INPUT.
  save_ok
= ok_code.
 
CLEAR ok_code.
 
CASE save_ok.
     
"如果用戶點擊的是標准工具欄中的 Back Exit 按鈕時,則立即結束當前屏幕序列
   
WHEN 'BACK_100'.
     
LEAVE TO SCREEN 0.
   
WHEN 'LAUNCH'.
     
"IF event-pai = 'X'.
      message_event
= 'PAI'.
      message_place
= 'on dynpro'.
     
PERFORM call_message.
     
" ENDIF.
   
WHEN 'FUNC'.
      message_event
= 'PAI'.
      message_place
= 'in function module on dynpro'.
     
PERFORM call_function.
   
WHEN 'EXIT'.
     
LEAVE TO SCREEN 100.
 
ENDCASE.
ENDMODULE.                    "user_command_0200 INPUT

MODULE status_0300 OUTPUT.
 
SET PF-STATUS 'LIST'.
 
SET TITLEBAR 'TITL_300'.
 
"LEAVE TO LIST-PROCESSING將控制權從對話屏幕轉向輸出列表處理器LIST PROCESSING,讓當前屏幕的PBO
 
"PAI中的Write輸出語句將結果都輸出到該輸出列表List屏幕之上
 
"離開這里(300屏幕)並到達(TO)列表處理,並且(AND)設置  after exiting the list processor時,會
 
"跳轉到對話屏幕100,如果設置為0,則當前屏幕序列會關閉
 
"該語句不會掛起當前屏幕的PBO處理,執行后會立即繼續執行后續語句,這與LEAVE TO SCREEN XXX是不同的
 
LEAVE TO LIST-PROCESSING AND RETURN TO SCREEN 100.

 
NEW-PAGE NO-TITLE.
 
WRITE 'Basic List'.
 
"讓當前屏幕(300屏幕)不彈出來。該語句作用是:如果該語句用在PBO中,當前屏幕不會顯示,但會繼續后續的PBO
 "處理,且前一屏幕還會繼續保持顯示。

 
"該語句不能使用在PBO之外的塊處理中。該語句的一般是與LEAVE TO LIST-PROCESSING一起使用,當使用
"LEAVE TO LIST-PROCESSING
之后,控制權從屏幕轉向了輸出列表,所有的Write輸出結果都會寫到輸出列表中(否
"
則這些Write語句會輸入到對話屏幕中),如果此時不想顯示屏幕200,則可以使用此語句來過路此屏幕,當然這可
"
以使用LEAVE SCREEN.語句來代替此語句,但LEAVE screen需要放在pbo的最后面(因為leave screen后面的
"
語句是不會再執行的),但suppress dialog可以放在pbo中的任何位置
 
"注:如果在被壓制的屏幕的PAI事件中彈出了任何類型的消息,則被壓制的屏幕還是會顯示出來。
 
SUPPRESS DIALOG.
 
"LEAVE SCREEN.離開當前屏幕跳轉到當前屏幕的下一屏幕,注:如果全要使用此語句代替SUPPRESS DIALOG,則要
"
Module的最后面
ENDMODULE.                    "status_0300 OUTPUT

************************************************************************
* Selection screen events                                              *
************************************************************************
AT SELECTION-SCREEN OUTPUT."1100選擇屏幕的PBO事件
 
IF event-pbo = 'X'.
    message_event
= 'PBO'.
    message_place
= 'on selection screen'.
   
PERFORM call_message.
 
ENDIF.

 
"此為1100選擇屏幕的PAI事件,該事件在點擊選擇屏幕上的 "執行" 按鈕后調用。
AT SELECTION-SCREEN.
 
IF funct = 'X'.
    message_event
= 'PAI'.
    message_place
= 'in funktion module on selection screen'.
   
PERFORM call_function.
 
ELSEIF event-pai = 'X'.
    message_event
= 'PAI'.
    message_place
= 'on selection screen'.
   
PERFORM call_message.
 
ENDIF.

************************************************************************
* List events
************************************************************************
AT USER-COMMAND.
 
CASE sy-ucomm.
   
WHEN 'DETAIL'.
     
WRITE: / 'Detail list, level:', sy-lsind.
   
WHEN 'MESSAGE'.
      message_event
= 'AT USER-COMMAND'.
      message_place
= 'on list'.
     
WRITE: / 'Detail list, level:', sy-lsind.
     
PERFORM call_message.
   
WHEN 'FUNCT'.
      message_event
= 'AT USER-COMMAND'.
      message_place
= 'in funktion module on list'.
     
PERFORM call_function.
     
WRITE: / 'Detail list, level:', sy-lsind.
 
ENDCASE.

************************************************************************
* Subroutines                                                          *
************************************************************************
FORM call_message.
 
CONCATENATE message_type ', ' message_place ',' message_event INTO msg.
 
MESSAGE ID '00' TYPE message_type NUMBER '001' WITH msg .
ENDFORM.                    "call_message

FORM call_function.
 
IF except-no = 'X'."(RAISING)異常,但不處理
   
"由於函數拋出了異常,但未處理,所以會忽略掉 MESSAGE raising 選項,最
   
"message以原本的形式展現,不會轉存到 SY-MSGID SY-MSGNO SY-MSGTY
   
"SY-MSGV1 ... SY-MSGV4 系統變量中去
   
CALL FUNCTION 'ZJZJ_FUNCTION_MESSAGE_RAISING'
     
EXPORTING
        message_type 
= message_type
        message_place
=
message_place
        message_event
= message_event.

 
ELSEIF except-yes = 'X'."(RAISING)異常,且進行處理
   
"由於函數拋出了異常,且在主調程序中進行了處理,所以MESSAGE最終不會以原本形式展現,raising
   
"項拋出的的異常信息會轉存到 SY-MSGID SY-MSGNO SY-MSGTYSY-MSGV1 ... SY-MSGV4 系統變量中去
   
CALL FUNCTION 'ZJZJ_FUNCTION_MESSAGE_RAISING'
     
EXPORTING
        message_type 
= message_type
        message_place
=
message_place
        message_event
=
message_event
     
EXCEPTIONS

        mess         
= 4."捕獲到異常
   
CASE sy-subrc.
     
WHEN 0.
       
CONCATENATE sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO msg.
       
MESSAGE i001(00)
               
WITH 'No exception raised in function module' msg.
     
WHEN 4."如果捕獲到了mess異常
       
CONCATENATE sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO msg.
       
MESSAGE i001(00)
               
WITH 'Handling exception from function module.' msg .
   
ENDCASE.
 
ELSEIF except-catch = 'X'."捕獲消息
   
CALL FUNCTION 'ZJZJ_FUNCTION_MESSAGE'
     
EXPORTING
        message_type 
= message_type
        message_place
=
message_place
        message_event
=
message_event
     
EXCEPTIONS

        error_message
= 4.
   
CASE sy-subrc.
     
WHEN 0.
       
CONCATENATE sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO msg.
       
MESSAGE i001(00)
               
WITH 'No exceptiontype E A raised in function module.' msg.
     
WHEN 4.
       
CONCATENATE sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO msg.
       
MESSAGE i001(00)
               
WITH 'Handling exception from function module.' msg.
   
ENDCASE.
 
ELSEIF except-nocatch = 'X'."未捕獲消息
   
CALL FUNCTION 'ZJZJ_FUNCTION_MESSAGE'
     
EXPORTING
        message_type 
= message_type
        message_place
=
message_place
        message_event
= message_event.

 
ENDIF.
ENDFORM.                    "call_function

FORM convert_user_input.
 
IF type-a = 'X'.
    message_type
= 'A'.
 
ELSEIF type-e = 'X'.
    message_type
= 'E'.
 
ELSEIF type-i = 'X'.
    message_type
= 'I'.
 
ELSEIF type-s = 'X'.
    message_type
= 'S'.
 
ELSEIF type-w = 'X'.
    message_type
= 'W'.
 
ELSEIF type-x = 'X'.
    message_type
= 'X'.
 
ENDIF.
ENDFORM.                    "convert_user_input

FORM modi_screnn USING pai pai_input pbo pbo_input.
 
LOOP AT SCREEN.
   
IF screen-name = 'EVENT-PAI'.
     
"復選框 EVENT-PAI 是否鈎選上
     
event-pai = pai.
     
"設置 EVENT-PAI 是否可選(禁止輸入)
     
screen-input = pai_input.
     
MODIFY SCREEN.
   
ENDIF.
   
IF screen-name = 'EVENT-PBO'.
     
"復選框 EVENT-PBO 是否鈎選上
     
event-pbo = pbo.
     
"設置 EVENT-PBO 是否可選(禁止輸入)
     
screen-input = pbo_input.
     
MODIFY SCREEN.
   
ENDIF.

   
IF place-report = 'X'
     
and ( screen-name = 'EXCEPT-NO'
     
or screen-name = 'EXCEPT-YES'
     
or screen-name = 'EXCEPT-CATCH'
     
or screen-name = 'EXCEPT-NOCATCH' ).
      except
-no = ''.
 
     screen-input = '0'.
     
MODIFY SCREEN.
   
ENDIF.
 
ENDLOOP.
ENDFORM.                    " MODI_SCRENN

FUNCTION ZJZJ_FUNCTION_MESSAGE_RAISING.
 
DATA: msg TYPE string.
 
CONCATENATE MESSAGE_TYPE ',' MESSAGE_PLACE ',' MESSAGE_EVENT INTO msg.
 
MESSAGE ID '00' TYPE MESSAGE_TYPE NUMBER '001' WITH msg RAISING MESS.
ENDFUNCTION.

FUNCTION ZJZJ_FUNCTION_MESSAGE.
  DATA: msg TYPE string.

 
CONCATENATE message_type ','  message_place ',' message_event INTO msg.
 
MESSAGE ID '00' TYPE message_type NUMBER '001' WITH msg.
ENDFUNCTION.

在狀態欄中顯示信息

一般用於多步操作的進度指示,顯示當前正在處理的任務信息

CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'"
EXPORTING
TEXT = text-022.

E”消息與回退按扭

START-OF-SELECTION.

 
DATA: l_vkorg TYPE likp-vkorg .

 
SELECT SINGLE vkorg FROM likp  INTO l_vkorg WHERE vbeln = p_vbeln .

   
CALL FUNCTION 'ZMM_ILG_LOCK_DN'
     
EXPORTING
        i_vbeln 
= p_vbeln
        i_loctyp
=
p_loctyp
     
IMPORTING

        e_zflag 
= flg
        e_errmg 
= msg.


   
IF p_loctyp = '0' AND flg = 'S'.
     
MESSAGE 'DN block successful.' TYPE 'S'.
   
ELSEIF p_loctyp = '1' AND flg = 'S'.
     
MESSAGE 'DN unblock successful.' TYPE 'S'.
   
ELSE.
     
CONCATENATE 'Update failed: '  msg  INTO msg.
     
* MESSAGE  msg  TYPE 'E'."如果使用此種方式打印消息,則程序會顯示成下面截圖樣子,此時界面沒有了,回退按鈕也不能使用,所以修改成如下形式即可
     
MESSAGE  msg  TYPE 'S' DISPLAY LIKE 'E'.
     
STOP.”使用程序停止下來,不然的話會執行START-OF-SELECTION事件塊后面剩余的程序
    ENDIF.

 

 

 MESSAGE s001(00) DISPLAY LIKE 'E' WITH text-001 l_vkorg.
     
STOP.

 

在函數中,不直接彈出消息,而是向上再次拋出:

MESSAGE E201 WITH HOST RAISING NOT_CONNECTED.

在上層可以這樣捕獲:

CALL FUNCTION 'ZMM_DATA_TO_FTP'
     
EXPORTING
        im_funid      
= l_funid
        im_filename   
=
l_filename
        im_rfcdest    
= 'SAPFTPA'

     
TABLES
       
text           = t_div
     
EXCEPTIONS

        not_connected 
= 2
       
OTHERS         = 5.
   
IF sy-subrc <> 0.
     
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
             
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.

   
ENDIF.

確認框函數POPUP_TO_CONFIRM


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM