14.         Messages

14.1.     00消息ID中的通用消息

00消息ID中的001消息本身未设置任何消息串,这条消息可以传递8个参数,在用于拼接消息时很有用

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

14.2.     消息常量

直接显示消息常量,不引用消息ID与消息号

MESSAGE 'aaaa' TYPE 'S'.

14.3.     静态指定

MESSAGE <t><nnn>(<id>) [with<f1>... <f4>][raising <exc>].

MESSAGE s002(00).

14.4.     动态指定

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.

14.5.     消息拼接MESSAGE …INTO

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.

14.6.     修改消息显示性为…DISPLAY LIKE…

此种方式不会影响到消息本身的处理性为,只是改变了消息的显示图标类型,如下面只是改变了S类型消息在状态栏中以错误图标来显示(本来是绿色状态图标):

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

:消息以异常形式抛出">14.7.     RAISING <exc>:消息以异常形式抛出

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

当使用该选项后,并且如果在调用的地方(CALL FUNCTION或者是 CALL METHOD的地方)使用了EXCEPTION选项来捕获RAISING抛出的异常,则不再以MESSAGE的原有形式来显示消息,而是被主调捕获后进一步处理或者是程序Dump(A、E、W、I、S类型都能被捕获到,但X类型的Message不会走到被主调者捕获这一步,因为在被调程序中就宕掉了);反过来,当主调者未使用EXCEPTION选项(或者使用了但未捕获到所抛出的异常),则RAISING选项会被忽略,MESSAGE语句会按照无RAISING选项时那样运行(弹框还是在状态栏中显示、以及程序是否终止等性为、还是转换为error_message抛出)

如果加了选项RAISING时:MESSAGE... RAISING <exc>,此时的Message 的处理方式与是否显示,就要依赖于主调者在调用时,是否加上了exception <exc>选项:

1、如果调用时没有带exception <exc>选项,此时Message语包中的RAISING <exc>选项抛出的异常将会被忽略,Message语句会当作正常消息来处理

2、  如果调用时加上了exception <exc>选项对exc 异常进行了捕获,则不会再显示消息(但如果即使加上了exception选项,但没有捕获到exc异常,则此时会忽略RAISING选项),并设置sy-subrc。只要异常被捕获,相关消息内容将会入存入到SY-MSGID,SY-MSGTY, SY-MSGNO, and SY-MSGV1 to SY-MSGV4有关系统变量中。

下面程序中,第一次调用时中会弹出消息框(因为没有使用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.

14.8.     CALL FUNCTION…EXCEPTIONS

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

exc1,exc2...与OTHERS异常只能捕获到MESSAGE...RAISING选项或RAISE语句抛出的异常,而error_message是无法捕获MESSAGE...RAISING与RAISE抛出的异常的

MESSAGE中的RAISING <exc1...exci>抛出异常时,如果在Call Function的Exception列表中有exc1...exci或others异常,则异常会优先被exc1...exci或others捕获到;否则RAISING选项将直接被忽略掉,MESSAGE会被error_message所捕获(在使用error_message捕获的前提下)

CALL FUNCTION 'ZJZJ_FUNC1'
  EXCEPTIONS
    error_message = 5
    "被e捕获,如果注释掉下面E类型异常捕获列表,则会被error_message捕获
    e             = 4
    d             = 6.

14.8.1.           error_message = n_error捕获消息

可以在Message语句没有使用RAISING选项的情况下(使用exc1...exci或others但未捕获到),在主调程序中的CALL FUNCTION ...Exception参数列表中使用隐式异常error_message选项来捕获Message,但error_message是否能捕获到Message(实为是否设置sy-subrc = n_error),与消息类型有关:

1、对于W、I、S类型的消息,将不显示消息(本来是要显示的),也不会去设置 sy-subrc = n_error此时还是会将消息的相关信息存储到SY-MSGID, SYMSGTY,SY-MSGNO, and SY-MSGV1 to SY-MSGV4这些系统变量中

2、对于A、E类型消息,也将不显示提示消息,但会抛出ERROR_MESSAGE异常,即这两类型的消息会自动被转换为error_message异常抛出,并终最被CALL FUNCTION 中Exception异常列表中的error_message异常所捕获,并设置sy-subrc = n_error。此时还会将消息的相关信息存储到SY-MSGID, SYMSGTY,SY-MSGNO, and SY-MSGV1 to SY-MSGV4这些系统变量中

此时,对于A类型消息而言,ROLLBACK WORK语句将会隐式执行

3、对于X类型消息将会抛出runtime error,并且程序会dump

14.9.     各种消息的显示及处理

消息类型

非屏幕PAI事件

PBO、

AT SELECTION-SCREEN OUTPUT、INITIALIZATION、START-OF-SELECTION

GET、

END-OF-SELECTION

TOP-OF-PAGE、

END-OF-PAGE

对话/选择屏幕

PAI、

AT SELECTION-SCREEN [ON]

List列表事件

AT LINE-SELECTION、

AT USER-COMMAND、

AT PF<nn>、

TOP-OF-PAGE DURING LINE-SELECTION

显示

显示在对话框中还是状态栏中

处理

是终止程序还是继续

显示

处理

显示

处理

X

不显示信息

触发运行时错误并伴随着dump

不显示信息

触发运行时错误并伴随着dump

不显示信息

触发运行时错误并伴随着dump

A

Dialogbox以对话框形式显示

程序终止

Dialogbox以对话框形式显示

程序终止

Dialogbox以对话框形式显示

程序终止

E

PBO:与A相同,否则显示在状态栏

程序终止

状态栏中显示

PAI处理结束,并且控制权返回到当前对话/选择屏幕继续输入

状态栏中显示

事件块处理终止,返回上一级别的List

W

PBO:与S相同,否则显示在状态栏

程序终止

状态栏中显示

PAI处理结束,并且控制权返回到当前对话/选择屏幕可继续输入可按回车键继来忽略警告继续运行后面程序而不必输入

状态栏中显示

事件块处理终止,返回上一级别的List

I

PBO:与S相同,否则对话框的形式显示

程序会继续向下执行

Dialog box对话框中显示

程序会继续向下执行

Dialog box对话框中显示

程序会继续向下执行

S

消息会显示在下一屏幕的状态栏中,如果没有下一屏幕,则显示在当前屏幕的状态栏中

程序会继续向下执行

消息会显示在下一屏幕的状态栏中,如果没有下一屏幕,则显示在当前屏幕的状态栏中

程序会继续向下执行

消息会显示在下一屏幕的状态栏中,如果没有下一屏幕,则显示在当前屏幕的状态栏中

程序会继续向下执行

14.10.             异常处理

14.10.1.      RAISE [EXCEPTION]…触发异常

两种方式触发异常:

RAISE <except>.  只在函数中使用

MESSAGE...RAISING <except>.

一旦主调程序捕获了异常,以上两种触发异常的方式都会返回到主调程序,并且不会返回值(Function Module参数输出)。MESSAGE ..... RAISING语句也不会再显示消息,而是将相关的信息填充到SY-MSGID, SY-MSGTY,SY-MSGNO, and SY-MSGV1 to SY-MSGV4这些系统变量中(即使是I,S,W三种消息类型也会设置这些系统变量

14.10.1.1.触发类异常

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

cx_class为异常Class,EXPORTING为构造此异常类的构造参数,oref可以是已存在的异常Class引用。

RAISE EXCEPTION语句一般用来抛出基于Class的异常类class-based exceptions,而RAISE一般是直接用来抛出 non-class-based exceptions(在函数中使用)

DATA result TYPE p DECIMALS 2.
  DATA oref TYPE REF TO cx_root.
  DATA text TYPE string.
  DATA i TYPE i.
  TRY .
      i = 1 / 0.
  CATCH cx_root INTO oref.
      text = oref->get_text( ).
      WRITE: '---' , text.
      RAISE EXCEPTION oref.
  ENDTRY.

DATA: exc  TYPE REF TO cx_sy_dynamic_osql_semantics,
      text TYPE string.
TRY.
  RAISE EXCEPTION TYPE cx_sy_dynamic_osql_semantics
        EXPORTING textid = cx_sy_dynamic_osql_semantics=>unknown_table_name token  = 'Test'.
  CATCH cx_sy_dynamic_osql_semantics INTO exc.
    text = exc->get_text( ).
    MESSAGE text TYPE 'I'.
ENDTRY.

14.10.1.2.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

14.10.2.      捕获异常

14.10.2.1.类异常捕获TRY…CATCH

DATA myref TYPE REF TO cx_sy_arithmetic_error.
DATA err_text TYPE string.
DATA result TYPE i.
TRY.
    result = 1 / 0.
CATCH cx_sy_arithmetic_error INTO myref.
    err_text = myref->get_text( ).
ENDTRY.

14.10.2.2.老式方式捕获runtime errors(运行时异常)

CATCH SYSTEM-EXCEPTIONS [exc1 = n1 exc2 = n2 ...][OTHERS = n_others].
  …
ENDCATCH.

 

DATA: result TYPE i.
CATCH SYSTEM-EXCEPTIONS arithmetic_errors = 5.
    result = 1 / 0.  
ENDCATCH.
IF sy-subrc = 5.
  WRITE / 'Division by zero!'.
ENDIF.

14.10.3.      向上抛出异常

如果Form中出现了运行时错误,但Form签名又没有使用RAISING向上抛,则程序会直接挂掉,所以最好是向上抛

FORM subform RAISING cx_static_check cx_dynamic_check.
...

ENDFORM.

Funcion函数不会主动向外抛出运行时错误,所以要先在Function手动CATCH,再手动向外抛如果出现运行时错误不抛出,则Function与会直接宕掉

14.10.4.      类异常

l   CX_STATIC_CHECK

l   CX_DYNAMIC_CHECK

l   CX_NO_CHECK

CX_NO_CHECK类似于Java中的Error,CX_DYNAMIC_CHECK类似于Java中的RuntimeException,CX_STATIC_CHECK类似于Java检测性异常Exception     [dai?n?mik]

自己定义的异常一般继承CX_STATIC_CHECK、CX_DYNAMIC_CHECK,但CX_NO_CHECK也可以创建,不像Java

CX_STATIC_CHECK是一个抽象类。在程序中使用RAISE EXCEPTION 手动抛出这类异常时,方法或过程接口上一定要显示的通过RAISING 来向上层抛出异常、或者直接在方法或过程中进行处理也可以,否则静态编译时就会出现警告

CX_NO_CHECK类型的异常一般表示系统资源不足引起的,不能在方法或过程接口后面抛出CX_NO_CHECK类型的异常,它会被隐含的抛出与传递。系统中已有预定义这类异常。

如果程序逻辑能够排除可能性的潜在性错,相应的异常就可能不用处理或继续抛出,此类情况下可以使用CX_DYNAMIC_CHECK类型的异常,这与Java中的运行时异常相似,一旦发生也该类异常,表示问题出现在程序的本身设计上,程序设计不严谨(如没有判断空指针问题)。ABAP大多数的系统预定义的异类都是属于该类型异常,这就意味着不需要处理或抛出ABAP语句可能出现的每一种异常,但一旦发生了该类异常,则表示程序的出现了问题,程序执行的结果将不会在正确。

自定义的全局异常类名以ZCX_  作为前缀

如果是通过Class Builder创建的全局异常类时,由于构造器是默认创建好的(异常相关参数已经固定下来了),不能传递自定义参数,所以异常文本ID只能通过TEXTID传递(参考触发类异常),但局部异常类没有这个限制。

原文出自 江正军 技术博客,博客链接:www.cnblogs.com/jiangzhengjun

ABAP开发 ~消息处理 (Messages)相关推荐

  1. 也谈SAP业务顾问如何避免被ABAP开发顾问怒打

    也谈SAP业务顾问如何避免被ABAP开发顾问怒打 近期一个视频火了,说是中国平安一个产品经理和APP开发人员在办公室直接扭打起来.据说是因为该产品经理向程序员提出了一个需求,要求用户APP的主题颜色能 ...

  2. 不喜欢SAP GUI?那试试用Eclipse进行ABAP开发吧

    Jerry和SAP成都研究院一些新同事聊天时,谈到ABAP和SAP GUI这个话题.很多新同事在加入SAP成都之前,是做Java和C++开发的,习惯了Eclipse/IntelliJ IDEA/Vis ...

  3. 《SAP ABAP 开发入门》课程正式发布

    首先,课程还没有全部做完,这次课程采用的是连载的方式,目前已经完成第二章共计8个课时.以后打算每周至少更新2个课时,在每周三和周六必定更新.当然如果时间允许的话,我会加快课程的制作. 课程购买地址 & ...

  4. 【整理】ABAP开发中的屏幕跳转

    ABAP开发中的屏幕跳转 这里介绍常见的几种在开发中常用到的事务代码跳转功能. 1.最常用到的是"SET PARAMETER"语句赋值,然后再使用"CALL TRANSA ...

  5. ABAP开发环境安装

    想玩ABAP开发,苦于SAP费用高,没关系,教你怎样实现自己的开发环境. 1.下载 官方地址:  ftp://ftp.sap.com/pub/sdn/devkits/netweaver/ 我选择的是A ...

  6. ABAP开发如何动态的实现任意表的ALV显示

    在ABAP开发中如何动态的实现任意表的ALV的显示,以下是具体操作步骤: 第一部分:程序框架 REPORT  ZALV_20090304_EVENT. INCLUDE ZALV_DATA_INTI. ...

  7. ABAP开发环境语法高亮的那些事儿

    关于SAP ABAP开发环境,Jerry之前写过几篇公众号文章: 那些年我用过的SAP IDE 不喜欢SAP GUI?那试试用Eclipse进行ABAP开发吧 使用Visual Studio Code ...

  8. ABAP开发环境终于支持以驼峰命名法自动格式化ABAP变量名了

    Jerry进入SAP成都研究院前,一直是用C/C++开发,所以刚接触ABAP,对于她在某些语法环境下大小写敏感,某些环境下不敏感的特性很不适应.那时候Jerry深深地怀念之前在C/C++编程时遵循的驼 ...

  9. abap 帮助文档 中文_一个13年ABAP老兵的建议:了解这些知识对ABAP开发有百利而无一害...

    在Jerry之前的图片推送中,我提到了SAP社区上这样一篇博客: Proof of Concept: Deploying ABAP in Kubernetes https://blogs.sap.co ...

最新文章

  1. 分布式主键解决方案----Twitter 雪花算法的原理(Java 版)
  2. mysql流行的四种高可用架构之:Keepalived+Mysql Replication
  3. 使用%的符号问题(只与被除数有关)
  4. oracle数据库impdp导入dmp文件功能演示,imp导入IMP-00038: Could not convert to environment character sets handle问题解决
  5. 分享一个Vant Weapp小程序UI组件库
  6. 静态方法-应用场景和定义方式
  7. 深入理解DOM节点类型第六篇——特性节点Attribute
  8. JavaFx导出文件
  9. s5pv210——中断实战
  10. 转载 从算法上解读自动驾驶是如何实现的?
  11. 福师《计算机应用基础》期末考试a卷数据是,2020年春福师《计算机应用基础》期末考试A卷附答案...
  12. java 源码学习,Java源码剖析34讲学习笔记~4
  13. HDU1370 Biorhythms【中国剩余定理】
  14. 容大热敏打印机打印纸张出半截,测试页不出嗡嗡响
  15. 【数字图像处理】基于SeetaFace2的人脸检测
  16. (原)使用ass字幕文件通过ffmpeg给视频添加字幕的一些研究
  17. 微型计算机噪声要求国标,中国噪声标准(GB noise standards)
  18. Springboot定时任务配置及遇到的问题
  19. 文科妹学 GitHub 简易教程(转)
  20. 群晖aria2 bt没速度_群晖终于开窍了!联手迅雷推出下载套件 NAS功能再上一层楼...

热门文章

  1. JMeter 系列 —— BeanShell 取样器
  2. MySQL 数据库--存储引擎
  3. Python——打开文件
  4. java map date_时间转换与map集合
  5. 谷歌开源的跨平台UI开发框架Flutter
  6. 审计溯源 | IP-guard终端操作审计,助力高效防控泄密风险
  7. USB HOST与 USB OTG的区别及工作原理
  8. 二叉树的建立(已知前序序列和中序序列)
  9. 【每日一练】day(7)
  10. mysql设置远程访问。