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

posted @ 2015-02-15 00:48  江正军  阅读(15468)  评论(0编辑  收藏  举报