Меню

Abap сообщение об ошибке

Оператор MESSAGE служит для диалогового взаимодействия с пользователем. Существует шесть типов сообщения.

Тип Описание
S Status (Success). Сообщение отображается в статусной строке и не влияет на работу программы. Данный вид сообщения применяется для информирования об успешной выполнении операции.
status-message
W Warning. Предупредительные сообщения отображаются в статусной строке. При возникновении сообщения работа программы прерывается, а пользователю предоставляется возможность вносить исправления в полях для ввода. При нажатии на Enter в диалоговом режиме, работа программы будет восстановлена.
warning-message
E Error. Сообщение отображается в статусной строке. При возникновении данного вида сообщения обработка программы останавливается.
error-message
I Information. Информационное сообщение отображается в отдельном модальном окне. При возникновении сообщения работа программы прерывается. После закрытия диалога работа программы восстанавливается.
imformation-message
A Abend (Abort). Сообщение отображается в модальном окне. При возникновении сообщения программа завершается, а система возвращается в меню более высокого уровня. Сообщения стоит применять только в крайних ситуациях.
abend-message
X Exception. Сообщение инициирует дамп MESSAGE_TYPE_X. Данный вид сообщения стоит применять в ситуациях, когда нужно проанализировать что именно привело к ошибке во время выполнения.
x-message

Синтаксис

MESSAGE { msg | text | exception }
{ { [DISPLAY LIKE dtype] [WITH dobj1 … dobj4] }
| { [DISPLAY LIKE dtype] [WITH dobj1 … dobj4] RAISING exception }
| { [WITH dobj1 … dobj4] INTO text } }.

После вызова оператора MESSAGE заполняются системные поля

Поле Значение
sy-msgid Содержит класс сообщения
sy-msgno Содержит номер сообщения
sy-msgty Содержит тип сообщения (S,I,W,E,A,X)
sy-msgv1 .. sy-msgv4 Содержит данные сообщения, указанные после добавления WITH

Для вывода сообщений используются классы сообщений, которые создаются в тр. SE91
se91

MESSAGE — msg

При выводе сообщений нужно указать: класс, номер и тип сообщения

MESSAGE tn(id)
MESSAGE tn
MESSAGE ID mid TYPE mtype NUMBER num.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

*&———————————————————————*

*& Report  Z_MESSAGE

*& Возможности оператора MESSAGE

*&———————————————————————*

*& Примеры использования оператора MESSAGE

*& http://abap4.ru/?p=360

*&———————————————————————*

REPORT z_message MESSAGE-ID 00.

START-OF-SELECTION.

  PERFORM main.

FORM main.

  » Краткая запись

  MESSAGE s002(00).

  » Краткая запись. Класс сообщения указывается в MESSAGE-ID программы

  MESSAGE s002.

  » Полная запись с указанием класса, типа и номера в отдельных полях

  MESSAGE ID ’00’ TYPE ‘S’ NUMBER ‘002’.

ENDFORM.

Результат работы программы
Класс сообщения 00, номер сообщения 002

MESSAGE — text

MESSAGE text TYPE mtype.

В также MESSAGE можно передать свободный текст. В этом случае класс сообщения будет 00, номер сообщения 001. Данный вариант обычно используют когда нет возможности определить сообщения в SAP, например когда текст сообщения формируется во внешних системах.

*&———————————————————————*

*& Пример вывода текста

*& http://abap4.ru/?p=360

*&———————————————————————*

REPORT z_message.

START-OF-SELECTION.

  PERFORM main.

FORM main.

  MESSAGE ‘Текст сообщения’ TYPE ‘I’.

ENDFORM.

Результат работы программы
free-text
В системных полях будет сообщение базисного класса 001(00)
free-text-sy

MESSAGE — exception

MESSAGE oref TYPE mtype.

В также MESSAGE можно передать исключение. Результат будет аналогичен выводу исключения.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

*&———————————————————————*

*& Пример вывода исключения

*& http://abap4.ru/?p=360

*&———————————————————————*

REPORT z_message.

START-OF-SELECTION.

  PERFORM main.

FORM main.

  DATA lr_root TYPE REF TO cx_root.

  DATA lv_value TYPE i.

  TRY .

    lv_value = 1 / 0.

  CATCH cx_root INTO lr_root.

    MESSAGE lr_root TYPE ‘I’.

  ENDTRY.

ENDFORM.

Результат работы программы
devide-by-zero
Значения системных полей
devide-by-zero-sy

MESSAGE — WITH

MESSAGEWITH dobj1 … dobj4.

Сообщения могут содержать параметры, которые передаются через дополнение WITH. Пример вывода сообщения 076(va) с двумя параметрами.
076(va)

*&———————————————————————*

*& Вывод сообщения с параметрами

*& http://abap4.ru/?p=360

*&———————————————————————*

REPORT z_message.

START-OF-SELECTION.

  PERFORM main.

FORM main.

  MESSAGE i076(va) WITH ‘TESTVAR’ syrepid.

ENDFORM.

Результат работы программы
message-with

MESSAGE — DISPLAY LIKE

MESSAGEDISPLAY LIKE dtype.

При использовании дополнения DISPLAY LIKE, происходит замена иконки на специфичную для типа, указанного в dtype. В dtype можно передать одно из следующих значений: A, E, I, S или W. Данное дополнение нельзя использовать для сообщения типа X, оно всегда вызывает дамп. DISPLAY LIKE обычно используется в ситуациях, когда нужно отобразить ошибку, но не прерывать выполнение программы.

*&———————————————————————*

*& Пример использования DISPLAY LIKE

*& http://abap4.ru/?p=360

*&———————————————————————*

REPORT z_message.

START-OF-SELECTION.

  PERFORM main.

FORM main.

  MESSAGE ‘Ошибка в модальном окне’ TYPE ‘I’ DISPLAY LIKE ‘E’.

ENDFORM.

Результат работы программы
i-as-e

MESSAGE — INTO

MESSAGEINTO text.

При использовании дополнения INTO, в переменную text записывается короткий текст сообщения. Само сообщение при этом, не отображается. Данное дополнение обычно применяют в двух случаях: когда нужно получить текст сообщения; когда нужно заполнить системные переменные для дальнейшего использования, например, для журнала приложений.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

*&———————————————————————*

*& Пример использования MESSAGE INTO

*& http://abap4.ru/?p=360

*&———————————————————————*

REPORT z_message.

START-OF-SELECTION.

  PERFORM main.

FORM main.

  DATA lv_text TYPE text120.

  MESSAGE e036(60) WITH ‘2100’ INTO lv_text. » Балансовая единица «&» неизвестна (ввести существующую БЕ).

  WRITE: / ‘TEXT: ‘, lv_text.

  WRITE: / ‘SY-MSGID: ‘, symsgid.

  WRITE: / ‘SY-MSGTY: ‘, symsgty.

  WRITE: / ‘SY-MSGNO: ‘, symsgno.

  WRITE: / ‘SY-MSGV1: ‘, symsgv1.

  WRITE: / ‘SY-MSGV2: ‘, symsgv2.

  WRITE: / ‘SY-MSGV3: ‘, symsgv3.

  WRITE: / ‘SY-MSGV4: ‘, symsgv4.

ENDFORM.

message-into

MESSAGE — RAISING

MESSAGERAISING exception.

Оператор MESSAGE вместе с дополнением RAISING представляет собой комбинацию операторов MESSAGE и RAISE. Данное дополнение имеет смысл только во время обработки методов и функциональных модулей, в которых определено исключение старого типа (основанного не на классах). Если вызывающий метод или функциональный модуль обрабатывает данное исключение в EXCEPTIONS, то MESSAGE .. RAISING работает аналогично оператору RAISE. Если же вызывающей стороне исключение не обрабатывается, то RAISING игнорируется.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

*&———————————————————————*

*& Пример использования MESSAGE RAISING

*& http://abap4.ru/?p=360

*&———————————————————————*

REPORT z_message.

CLASS c1 DEFINITION.

  PUBLIC SECTION.

    CLASS-METHODS m1 EXCEPTIONS exc1.

ENDCLASS.

CLASS c1 IMPLEMENTATION.

  METHOD m1.

    MESSAGE ‘Сообщение с RAISING’ TYPE ‘I’ RAISING exc1.

  ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.

  PERFORM main.

FORM main.

  c1=>m1( ).                      » Отработает MESSAGE

  c1=>m1( EXCEPTIONS exc1 = 4 ).  » Отработает RAISING

  IF sysubrc = 4.

  ENDIF.

ENDFORM.

Предисловие — Этот пост является частью ABAP-новичок серии.

Введение

Программист всегда старается кодировать таким образом, чтобы в его коде не было ошибок и чтобы он был полностью проверен. Но есть определенные сценарии, когда его коды могут дать сбой. В таком случае, если кодер уже знает сценарии, он обрабатывает их в форме обработки ошибок. Но в случае ситуаций, когда ошибка может быть сгенерирована из-за неизвестных ситуаций и не обработана, это может привести к серьезным дампам. Для этих сценариев у нас есть обработка исключений в SAP. В этой статье мы рассмотрим все сценарии обработки исключений и ошибок в отчетах ABAP.

Обработка исключений и ошибок в отчетах SAP ABAP

Как обсуждалось выше, кодировщик должен обрабатывать известные проблемы, а также предполагаемые сообщения об ошибках. Эти сообщения отображаются пользователю в выводе с помощью оператора MESSAGE.

Различные способы обнаружения ошибок/исключений

ABAP предоставляет различные способы обнаружения ошибок в программе ABAP.

  1. Использование системной переменной

Самый простой способ — использовать их системные переменные.

 SY-SUBRC EQ 0. «Этот оператор указывает, что операция завершена успешно. SY-SUBRC NE 0. «Этот оператор указывает, что операция не удалась.

Этот способ работает напрямую, если весь код отчета обрабатывался в рамках одной программы. Это означает, что он не может напрямую поймать ошибку, если вы обработали операторы функционального модуля или класса ABAP. Для этих объектов нам нужно вызвать исключение с их конца, а затем исключение можно обработать в отчете и соответствующим образом обработать.

  1. Отлов ошибок на основе исключения

В случае, если мы реализуем функциональный модуль или метод класса, важно вызвать исключение из этих классов, а затем мы можем поймать эти исключения в отчете и показать соответствующую ошибку.

Например:

CALL FUNCTION 'Test_Function' EXPORTING DELIMITER = ':' STRING = lv_string IMPORTING HEAD = lv_head TAIL = lv_tail EXCEPTIONS NOT_FOUND = 1 OTHERS = 2. CASE SY-SUBRC. КОГДА 1. ... // Показать сообщение об ошибке КОГДА 2. ... // Показать сообщение об ошибке КОГДА ДРУГОЕ. // Показать сообщение об ошибке ENDCASE.
  1. Использование TRY CATCH ENDTRY

Если исключение возникает с помощью метода класса или возникает неожиданное исключение, в этих случаях мы используем функцию TRY CATCH SAP ABAP. Это один из лучших способов полного доказательства для обработки всех типов исключений.

Пример:

ПЫТАТЬСЯ. //Здесь вызовите свой класс или функциональный модуль CATCH CX_SY_ZERODIVIDE INTO O_REF. // Исключение, которое вы там вызвали СООБЩЕНИЕ «Ваше сообщение об ошибке». КОНЕЦ.

Различные способы отображения сообщений

  1. Использование оператора ABAP

Синтаксис:

СООБЩЕНИЕ ' ' TYPE 'Введите тип сообщения здесь'.

Типы сообщений

ABAP предоставляет следующие 6 типов сообщений:

Тип сообщения Смысл объяснение
A прекращение Это сообщение отображается при завершении программы.
E Ошибка Это сообщение отображается во время Ошибка.
I Информация Это сообщение используется для отображения любой информации.
S Успех Это отображается в состоянии экрана вывода.
W Предупреждение Он ведет себя как сообщение об ошибке.
X Выход Это вызывает короткий дамп с сообщением об ошибке.
  1. Использование предопределенных функциональных модулей

ABAP предоставляет следующие функциональные модули, которые можно использовать для хранения, форматирования и отображения сообщений:

Функциональный модуль Применение
MESSAGES_INITIALIZE Для инициализации сообщений.
MESSAGE_STORE Чтобы сохранить сообщения для отображения.
MESSAGES_SHOW Отображать все сообщения вместе во всплывающем окне
FORMAT_MESSAGE Форматировать сообщения
HR_DISPLAY_ERROR_LIST Для отображения всех сообщений об ошибках

Пример:

  1. Использование оператора сообщения
СООБЩЕНИЕ 'Это сообщение об ошибке' ТИП 'E'.
  1. Использование нескольких функций для хранения и отображения сообщений:
" Инициализируется только изначально... * Инициализируйте свои сообщения CALL FUNCTION 'MESSAGES_INITIALIZE' EXCEPTIONS log_not_active = 1 неправильно_идентификация = 2 OTHERS = 3. "Одно за другим добавьте сюда все ваши сообщения PERFORM store_messages USING 'E' w_pn w_batch2 w_werks ' ' w_msgno . FORM store_messages ИСПОЛЬЗОВАНИЕ p_msgty p_msgv1 p_msgv2 p_msgv3 p_msgv4 p_txtnr. IF p_msgty EQ 'E'. w_err_fg = 'Х'. КОНЕЦ. * Храните все ваши сообщения, предназначенные для отображения. CALL FUNCTION 'MESSAGE_STORE' EXPORTING arbgb = 'ZCCH001' msgty = p_msgty msgv1 = p_msgv1 msgv2 = p_msgv2 msgv3 = p_msgv3 msgv4 = p_msgv4 txtnr = p_txtnr EXCEPTIONS = 1 not_valid = RM.2 not_valid message_type_not_valid = OTH. . " STORE_MESSAGES "В конце получить все ваши сообщения и показать их целиком * Это отображает все сообщения во всплывающем окне ФУНКЦИЯ ВЫЗОВА 'MESSAGES_SHOW' ЭКСПОРТ show_linno = ' ' ИМПОРТ e_exit_command = wa_exit_command ИСКЛЮЧЕНИЯ inconsistent_range = 3 no_messages = 1 OTHERS = 2.
  1. Использование HR_DISPLAY_ERROR_LIST
ДАННЫЕ: it_error TYPE СТАНДАРТНАЯ ТАБЛИЦА HRERROR,"TABLES PARAM wa_error LIKE LINE OF it_error . DATA(ld_no_popup) = 'здесь какой-то текст'. DATA(ld_no_print) = 'здесь какой-то текст'. DATA(ld_no_img) = 'здесь какой-то текст' .DATA(ld_no_msgno) = 'здесь какой-то текст'. DATA(ld_linesize) = '123'. DATA(ld_listheader) = 'Проверка типа требуемых данных'. DATA(ld_colheader) = 'Проверка типа требуемых данных'. DATA(ld_hidemsg ) = 'некоторый текст здесь'. "заполнить поля структуры и добавить к itab добавить wa_error к it_error. . CALL FUNCTION 'HR_DISPLAY_ERROR_LIST' * EXPORTING * no_popup = ld_no_popup * no_print = ld_no_print * no_img = ld_no_img * no_msgno = ld_no_msgno * linesize = ld_linesize * listheader = ld_listheader * colheader = ld_colheader * hidemsg = ld_hidemsg * TABLES * error = it " HR_DISPLAY_ERROR_LIST IF SY-SUBRC EQ 1. "Все в порядке ELSEIF SY-SUBRC EQ 0. "Exception" "Добавьте сюда код исключения ENDIF.

imagesКогда мы создаем какой-либо многократно используемый компонент, например функциональный модуль или метод в классе, мы сталкиваемся с необходимостью обработки непредвиденных ситуаций (какой-либо входной параметр, оказался не заполненным или доступ к файлу не был получен и т.п.), т.е. тех ситуаций, после которых программа не может выполняться далее стандартным образом, либо требуется дополнительная обработка.

В приведенной статье рассматриваются способы вызова и обработки данных ситуаций, называемых исключениями.

В ABAP есть два основных способа работы с исключениями, классический способ заключается в вызове особых ситуаций описанных в ФМ или методе на отдельной закладке:

1

Классический способ может использоваться и в классах:

2

Новый способ основывается на ООП, где в качестве исключений используются классы (обратите внимание, что установлена галочка – классы исключений):

3

Хочется отметить, что новый способ был введен с версии SAP Web AS 6.10 и при создании новых функциональных модулей или методов рекомендуется использовать именно его. В данной статье не рассматриваются системные исключения и их обработка до введения классов исключений.

В RFC модулях в настоящее время используется классический способ обработки исключений. Не допускается одновременно использовать классический и основанный на классах, способы обработки исключений (в интерфейсе методов, процедур, функций).

Классический способ обработки исключений

При вызове исключения, системное поле sy-subrc будет заполнено номером, под которым исключение было обозначено при вызове ФМ, метода или процедуры:

CALL FUNCTION ...

...

EXCEPTIONS

  Ошибка1 = 1

  Ошибка2 = 2.

Как правило, исключения вызываются с текстом сообщения, данный текст может быть описан статически – при вызове исключения оператором MESSAGE, либо динамически – путём получения текста из описания ФМ.

Так же исключение может быть вызвано без какого-либо текста (оператором RAISE ИмяИсключения), но данный способ лучше не использовать, т.к. вызов исключения должен как-то себя расшифровывать и говорить о том, что собственно произошло.

Напишем небольшой ФМ, рассчитывающий сумму двух чисел, оба параметра помечены как необязательные, если первый параметр не будет задан при вызове ФМ, система выдаст исключение – no_num_1.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

FUNCTION ZTEST_EXC.

*»———————————————————————-

*»*»Локальный интерфейс:

*»  IMPORTING

*»     REFERENCE(I_NUM_1) TYPE  I OPTIONAL

*»     REFERENCE(I_NUM_2) TYPE  I OPTIONAL

*»  EXPORTING

*»     REFERENCE(E_SUMM) TYPE  I

*»  EXCEPTIONS

*»      NO_NUM_1

*»———————————————————————-

  IF i_num_1 IS NOT SUPPLIED.

    MESSAGE e398(00) WITH ‘Число 1 не указано, расчёт невозможен’ RAISING no_num_1.

  ENDIF.

  E_SUMM = i_num_1 + i_num_2.

ENDFUNCTION.

И программа для его вызова:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

DATA:

  gv_num_2 TYPE i VALUE 10,

  gv_summ  TYPE i.

CALL FUNCTION ‘ZTEST_EXC’

  EXPORTING

    i_num_2  = gv_num_2    » Число 2

  IMPORTING

    e_summ   = gv_summ     » Сумма

  EXCEPTIONS

    no_num_1 = 1

    others   = 2.

IF sysubrc <> 0.

MESSAGE ID symsgid TYPE symsgty NUMBER symsgno

            WITH symsgv1 symsgv2 symsgv3 symsgv4.

ENDIF.

WRITE gv_summ.

При запуске программы произойдет вызов исключения, т.к. был использован тип сообщения «Е», программа завершит свое выполнение после показа сообщения:

4

Замечу, что это вовсе не означает, что при вызове ФМ или метода и обработке исключения необходимо завершать работу программы, вы можете свободно продолжить её выполнение и далее, добавив например, сообщение об ошибке в лог программы, а не на вывод как в примере.

Ключевое слово OTHERS используется для того чтобы поймать исключения не описанные в ФМ или явно неуказанные, при вызове ФМ.

Пример вызова неописанного исключения:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

FUNCTION ztest_exc.

*»———————————————————————-

*»*»Локальный интерфейс:

*»  IMPORTING

*»     REFERENCE(I_NUM_1) TYPE  I OPTIONAL

*»     REFERENCE(I_NUM_2) TYPE  I OPTIONAL

*»  EXPORTING

*»     REFERENCE(E_SUMM) TYPE  I

*»  EXCEPTIONS

*»      NO_NUM_1

*»———————————————————————-

  IF i_num_1 IS NOT SUPPLIED.

    MESSAGE e398(00) WITH ‘Число 1 не указано, расчёт невозможен’ RAISING no_num_2.

  ENDIF.

  E_SUMM = i_num_1 + i_num_2.

ENDFUNCTION.

В данном примере вызывается неописанное в интерфейсе ФМ исключение – no_num_2, которое будет благополучно поймано с помощью ключевого слова OTHERS (системное поле sy-subrc примет значение равное 2).

Кроме того, можно не обрабатывать большой список всех возможных исключений описанных в ФМ, тогда в случае если такое исключение будет вызвано поле sy-subrc примет значение, указанное в OTHERS.

В ФМ, могут быть добавлены новые исключения и в случае, когда при вызове ФМ они не обработаны и не указано слово OTHERS программа упадет в дамп с ошибкой времени выполнения — RAISE_EXCEPTION. Отсюда вывод, ключевое слово OTHERS подставляем всегда, при вызове ФМ (метода или процедуры), когда мы точно не уверены в неизменности компонента.

5

При вызове исключения в процедурах (perform…) из ФМ, система пытается найти и вызвать исключение в первом ФМ из стека вызовов, если исключение не найдено, вызывается так же, как и неопределенное исключение в ФМ.

Как уже было упомянуто выше, есть возможность получать текст непосредственно из описания особой ситуации:

6

ФМ будет выглядеть следующим образом:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

FUNCTION ztest_exc.

*»———————————————————————-

*»*»Локальный интерфейс:

*»  IMPORTING

*»     REFERENCE(I_NUM_1) TYPE  I OPTIONAL

*»     REFERENCE(I_NUM_2) TYPE  I OPTIONAL

*»  EXPORTING

*»     REFERENCE(E_SUMM) TYPE  I

*»  EXCEPTIONS

*»      NO_NUM_1

*»———————————————————————-

  DATA:

    lv_fun TYPE functfuncname,

    lv_exc TYPE functparameter,

    lv_txt TYPE swotlqshorttext.

  lv_fun = ‘ZTEST_EXC’.

  lv_exc = ‘NO_NUM_1’.

  CALL FUNCTION ‘SWO_TEXT_FUNCTION_EXCEPTION’

    EXPORTING

      language  = sylangu

      function  = lv_fun

      exception = lv_exc

    IMPORTING

      shorttext = lv_txt.

  IF i_num_1 IS NOT SUPPLIED.

    MESSAGE e398(00) WITH lv_txt RAISING no_num_1.

  ENDIF.

  e_summ = i_num_1 + i_num_2.

ENDFUNCTION.

Результат: 7

Иногда особые ситуации используются не как исключения, а как параметры показывающие обработку ФМ и его результат, возвращаемый в поле sy-subrc, хотя лучше бы пренебречь подобным стилем:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

FUNCTION ZMORE_THEN_10.

*»———————————————————————-

*»*»Локальный интерфейс:

*»  IMPORTING

*»     REFERENCE(I_VAL) TYPE  I

*»  EXCEPTIONS

*»      MORE_10

*»      LESS_10

*»      EQUAL_10

*»———————————————————————-

  IF i_val = 10.

    RAISE equal_10.

  ELSEIF i_val > 10.

    RAISE more_10.

  ELSE.

    RAISE less_10.

  ENDIF.

ENDFUNCTION.

Программа:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

DATA:

  gv_val TYPE i VALUE 10.

CALL FUNCTION ‘ZMORE_THEN_10’

  EXPORTING

    i_val    = gv_val

  EXCEPTIONS

    more_10  = 1

    less_10  = 2

    equal_10 = 3.

CASE sysubrc.

  WHEN 1.

    WRITE ‘More 10’.

  WHEN 2.

    WRITE ‘Less 10’.

  WHEN 3.

    WRITE ‘Equal

Результат:

8

Сообщения, вызываемые в ФМ или методах, оператором MESSAGE, без дополнения RAISING, либо сообщения вызываемые системой (например, при обработке экранов), могут быть обработаны программой с использованием дополнения: error_message = n_error, указываемого так же после ключевого слова EXCEPTIONS.

При обработке сообщений:

  • Сообщения с типом I, W, S не обрабатываются, но записываются в журнал обработки фонового выполнения, если происходит обработка в фоне.
  • Сообщения с типом E или A могут быть обработаны, при этом в поле sy-subrc будет записано значение n_error. При вызове сообщения с типом А, происходит вызов ROLLBACK WORK (см. описание оператора MESSAGE).
  • Сообщение с типом X не обрабатывается, программа завершается с дампом.

Пример ФМ:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

FUNCTION ztest_exc.

*»———————————————————————-

*»*»Локальный интерфейс:

*»  IMPORTING

*»     REFERENCE(I_NUM_1) TYPE  I OPTIONAL

*»     REFERENCE(I_NUM_2) TYPE  I OPTIONAL

*»  EXPORTING

*»     REFERENCE(E_SUMM) TYPE  I

*»  EXCEPTIONS

*»      NO_NUM_1

*»———————————————————————-

  IF i_num_1 IS NOT SUPPLIED.

    MESSAGE e398(00) WITH ‘Число 1 не указано, расчёт невозможен’.

  ENDIF.

  E_SUMM = i_num_1 + i_num_2.

ENDFUNCTION.

Программа:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

PROGRAM test_exceptions.

DATA:

  gv_val TYPE i VALUE 10,

  gv_summ TYPE i.

CALL FUNCTION ‘ZTEST_EXC’

  EXPORTING

    i_num_2  = gv_val    » Число 2

  IMPORTING

    e_summ   = gv_summ    » Сумма

  EXCEPTIONS

    error_message = 1

    others   = 2.

IF sysubrc = 1.

  WRITE ‘ФМ вызвал MESSAGE с типом E,A’.

ENDIF.

Результат:

9

Обработка исключения классическим способом может быть выполнена динамически, с помощью ключевого слова EXCEPTION-TABLE. Пример:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

DATA: line     TYPE c LENGTH 80,

      text_tab LIKE STANDARD TABLE OF line,

      filename TYPE string,

       filetype TYPE c LENGTH 10,

      fleng    TYPE i.

DATA: func TYPE string,

      ptab TYPE abap_func_parmbind_tab,

      ptab_line TYPE abap_func_parmbind,

      etab TYPE abap_func_excpbind_tab,

      etab_line TYPE abap_func_excpbind.

func = ‘GUI_DOWNLOAD’.

filename = ‘c:temptext.txt’.

filetype = ‘ASC’.

ptab_linename = ‘FILENAME’.

ptab_linekind = abap_func_exporting.

GET REFERENCE OF filename INTO ptab_linevalue.

INSERT ptab_line INTO TABLE ptab.

ptab_linename = ‘FILETYPE’.

ptab_linekind = abap_func_exporting.

GET REFERENCE OF filetype INTO ptab_linevalue.

INSERT ptab_line INTO TABLE ptab.

ptab_linename = ‘DATA_TAB’.

ptab_linekind = abap_func_tables.

GET REFERENCE OF text_tab INTO ptab_linevalue.

INSERT ptab_line INTO TABLE ptab.

ptab_linename = ‘FILELENGTH’.

ptab_linekind = abap_func_importing.

GET REFERENCE OF fleng INTO ptab_linevalue.

INSERT ptab_line INTO TABLE ptab.

...

etab_linename = ‘OTHERS’.

etab_linevalue = 10.

INSERT etab_line INTO TABLE etab.

CALL FUNCTION func

  PARAMETERTABLE

  ptab

  EXCEPTIONTABLE

  etab.

CASE sysubrc.

  WHEN 1.

    ...

    ...

ENDCASE.

Обработка исключений, основанная на классах

Как понятно из названия, под исключениями в данном случае понимаются объекты специальных классов исключений. Вызов такого исключения может быть выполнен либо в программе с помощью оператора RAISE EXCEPTION, либо системой (например, при делении на ноль будет вызвано предопределённое исключение CX_SY_ZERODIVIDE, список таких исключений), либо через дополнение THROW в условных выражениях (с версии ABAP 7.4).

Во всех случаях инициируется создание объекта указанного класса (если указано дополнение INTO в CATCH), в атрибутах которого содержится информация о возникшей исключительной ситуации, доступ к ним, как правило, осуществляется через методы этого класса.

Классы особых ситуаций могут быть определены как локально, так и глобально через построитель классов – транзакция SE24, диалог создания:

10

В данном случае галочка «с классом сообщений» означает использование в качестве текста сообщения из класса сообщений транзакция SE91 (будет рассмотрено ниже). По умолчанию текст сообщения создается в текстах класса:

11

Категории исключений

Все классы особых ситуаций являются производными одного из классов: CX_NO_CHECK, CX_DYNAMIC_CHECK или CX_STATIC_CHECK, которые сами являются производными общего суперкласса CX_ROOT.

  • CX_STATIC_CHECK – как правило, исключения которые вызываются в процедуре (ФМ или методе), должны быть либо обработаны в ней, либо процедура должна иметь соответствующий интерфейс, чтобы вызывающий её код мог обработать эту ситуацию. Если исключение определено как потомок этого класса, оно должно быть явно указано в интерфейсе метода (ФМ или формы) в котором происходит его вызов. Данная категория используется тогда, когда в коде явно ожидается передача обработки особой ситуации на уровень выше того места где оно было вызвано. Если при статической проверке, система не увидит обработки в блоке TRY..CATCH..ENDTRY подобного исключения система выдаст предупреждение: 12
  • CX_DYNAMIC_CHECK – при проверке кода, компилятор не будет делать предупреждений об отсутствии обработки исключений их этой категории, в случае вызова исключения его обработка будет проверена динамически и если обработчик не будет найден программа упадет в дамп. Обычно данная категория используется тогда, когда исключение может быть обработано внутри самого метода, без передачи обработки выше по стеку. Примером такой категории может являться исключение вызываемое при делении на ноль, передавать его выше по стеку и указывать в интерфейсе метода вовсе не обязательно, т.к. мы можем его обработать внутри самого метода. Однако, если мы хотим передать обработку данного исключения, необходимо указать его в интерфейсе метода.
  • CX_NO_CHECK – аналогичны предыдущему типу, но данную категорию нельзя объявлять в интерфейсах, при этом классы исключений наследуемые от этого класса, неявно все же передаются в интерфейс и выше по стеку вызовов. Данную категорию следует использовать для исключительных ситуаций, которые могут произойти в любое время и не могут быть обработаны непосредственно в коде метода. Кроме того, можно использовать в случаях когда одна и та же исключительная ситуация может возникнуть во множествах методов, а объявлять её в интерфейсах каждого из методов не имеет смысла, т.к. это усложнит код. В итоге подобные исключения могут пройти всю цепочку вызовов методов (т.к. неявно передаются в интерфейс) и быть обработаны на уровне программы.

На исключения накладываются следующие ограничения:

  • Исключение не может быть объявлено в интерфейсе статического конструктора:

13

  • Исключение не может быть объявлено в интерфейсе обработчика событий. При этом если в коде обработчика произошел вызов исключения, и он не был обработан, система вызовет исключение — CX_SY_NO_HANDLER, которое может быть обработано в вызывающем его коде.
  • При вызове программ через SUMBIT или CALL TRANSACTION, исключение, возникающее в вызываемой программе, не может быть передано в вызывающую программу.

Небольшой пример с локальным классом исключения:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

PROGRAM test_exceptions.

CLASS lcx_no_num DEFINITION INHERITING FROM cx_static_check.

ENDCLASS.

CLASS lcl_test_exceptions DEFINITION.

  PUBLIC SECTION.

    METHODS:

      do_summ IMPORTING

                i_num_1 TYPE i OPTIONAL

                i_num_2 TYPE i OPTIONAL

              RETURNING value(re_summ) TYPE int1

              RAISING lcx_no_num.

ENDCLASS.

CLASS lcl_test_exceptions IMPLEMENTATION.

  METHOD do_summ.

    IF i_num_1 IS NOT SUPPLIED OR i_num_2 IS NOT SUPPLIED.

      » Данное исключение присутствует в интерфейсе, может быть обработано вне метода

      RAISE EXCEPTION TYPE lcx_no_num.

    ENDIF.

    TRY.

      re_summ = i_num_1 + i_num_2.

      » Ошибка с дин. проверкой, при её обработке обнулим результат

    CATCH CX_SY_CONVERSION_OVERFLOW.

      re_summ = 0.

    ENDTRY.

  ENDMETHOD.

ENDCLASS.

DATA:

  go_test_exceptions TYPE REF TO lcl_test_exceptions,

  gv_summ TYPE int1.

START-OF-SELECTION.

  CREATE OBJECT go_test_exceptions.

  TRY.

    go_test_exceptions>do_summ(

      EXPORTING

        i_num_2 = 1

      RECEIVING

        re_summ = gv_summ

    ).

  CATCH lcx_no_num.

    WRITE ‘Не заполнены все параметры’.

  ENDTRY.

  go_test_exceptions>do_summ(

    EXPORTING

      i_num_1 = 999

      i_num_2 = 1

    RECEIVING

      re_summ = gv_summ

  ).

  WRITE: / ‘Результат cуммы 999 и 1:’, gv_summ.

В стандартной системе SAP имена всех классов особых ситуаций начинаются с CX_ , пользовательские исключения рекомендуется называть, начиная с ZCX или lcx для локальных классов исключений.

Класс CX_ROOT предоставляет некоторые предопределенные методы, которые наследуются всеми классами особых ситуаций:

  • Метод GET_SOURCE_POSITION возвращает имя главной программы и (если связаны) имена включенных программ (инклудов) и номер строки исходного кода, в которой возникла особая ситуация.
  • Метод GET_TEXT возвращает текст особой ситуации в форме строки.
  • Метод GET_LONGTEXT возвращает подробный текст текста особой ситуации в форме строки.

Тексты исключений

Каждому классу можно присвоить несколько текстов. Присвоенные им идентификаторы создаются построителем классов как константы в атрибутах класса. Тексты сохраняются в репозитарии текстов (OTR). Константы идентификаторы, представленные в шестнадцатеричном формате, уникальны на уровне системы:

14

Доступ к хранилищу текстов можно получить через транзакцию SOTR_EDIT.

В текстах можно определить параметры, их необходимо обозначить в амперсандах. В качестве примера, можно рассмотреть текст из класса исключения — CX_SY_FILE_IO:

15

В параметры будут переданы (при вызове метода GET_TEXT) соответствующие им атрибуты класса:

16

Заполняются эти атрибуты в конструкторе при вызове исключения:

DATA: lr_ex  TYPE REF TO cx_sy_file_io,

      lv_msg TYPE string.

TRY.

   ...

   RAISE EXCPETION TYPE cx_sy_file_io

      EXPORTING

         textid = cx_sy_file_io=>read_error

         filename = ‘somefile.txt’.

CATCH cx_sy_file_io INTO lr_ex.

   lv_msg = lr_ex>get_text( ).

   MESSAGE lv_msg TYPE ‘I’.

ENDTRY.

Так же в конструкторе можно указать, какой текст должен использоваться при инициировании особой ситуации, передав одну из определенных констант в параметр импорта TEXTID. Не рекомендуется использовать подобную методику, т.к. это может запутать код, однако как было уже показано выше SAP сам это использует (read_error, write_error в CX_SY_FILE_IO). Инкапсуляция текстов в классах сообщений и их саморасшифровываемость является одним из преимуществ над классическими исключениями.

Конструктор, который генерируется автоматически в SE24, для нового созданного исключения (ZCX_NO_NUM1), выглядит так:

CALL METHOD SUPER>CONSTRUCTOR

EXPORTING

TEXTID = TEXTID

PREVIOUS = PREVIOUS

.

IF textid IS INITIAL.

   me>textid = ZCX_NO_NUM1 .

ENDIF.

Блок обработки исключений

Особая ситуация может быть обработана, только если оператор, который может инициировать ее, заключен в блок TRY-ENDTRY. Затем особая ситуация обрабатывается с помощью оператора CATCH в блоке TRY-ENDTRY.

17

Блок TRY содержит набор операторов, обрабатывающих особые ситуации. Если в блоке TRY появляется особая ситуация, система осуществляет поиск первого оператора CATCH в том же блоке TRY-ENDTRY, а затем последовательно снаружи во всех заключающих блоках TRY-ENDTRY, обрабатывающих особую ситуацию. Если оператор находится, система осуществляет переход к его обработчику. Если обработчик найти не удается, но блок TRY-ENDTRY находится в процедуре, система осуществляет попытку передачи особой ситуации вызывающей программе.

Блок CATCH содержит обработчик особых ситуаций, исполняемый при возникновении указанной особой ситуации в связанном блоке TRY. Для оператора CATCH можно указать любое количество классов особых ситуаций. Таким образом, определяется обработчик особых ситуаций для всех этих классов особых ситуаций и их подклассов.

Блоки TRY-ENDTRY могут иметь вложенность любой глубины. Поэтому блок TRY, блоки CATCH и блок CLEANUP в целом сами могут содержать полные блоки TRY-ENDTRY.

При возникновении особой ситуации система осуществляет поиск по перечисленным обработчикам особых ситуаций в указанном порядке. Затем она исполняет первый обработчик особых ситуаций, оператор CATCH которого содержит подходящий класс особой ситуации или один из ее суперклассов.

Если ошибка не будет обработана и не будет передана вызывающей программе, система выдаст дамп с ошибкой времени выполнения — UNCAUGHT_EXCEPTION, в том случае когда не обрабатывается исключительная ситуация, связанная с ошибкой времени выполнения, система выдает дамп с ошибкой времени выполнения (например, CX_SY_CONVERSION_CODEPAGE — CONVT_CODEPAGE):

18

Просмотр ошибки в транзакции ST22:Безымянный

Распространение особых ситуаций

Если возникает особая ситуация (наследуемая от CX_DYNAMIC_CHECK, CX_STATIC_CHECK), она автоматически распространяется на все уровни стека вызовов, до тех пор, пока она не будет обработана или пока не встретится такой интерфейс, в котором она (либо её предки) будет отсутствовать.

Следующий пример демонстрирует распространение особой ситуации на несколько методов:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

CLASS lcx_calc_error DEFINITION INHERITING FROM cx_static_check.

ENDCLASS.

CLASS lcx_summ_error DEFINITION INHERITING FROM lcx_calc_error.

ENDCLASS.

CLASS lcl_test_exc DEFINITION.

  PUBLIC SECTION.

  METHODS:

    do_calc

      RAISING

        lcx_calc_error,

    do_summ

      RAISING

        lcx_summ_error.

ENDCLASS.

CLASS lcl_test_exc IMPLEMENTATION.

  METHOD do_calc.

    do_summ( ).

  ENDMETHOD.

  METHOD do_summ.

    RAISE EXCEPTION TYPE lcx_summ_error.

  ENDMETHOD.

ENDCLASS.

DATA:

  go_test TYPE REF TO lcl_test_exc.

START-OF-SELECTION.

  CREATE OBJECT go_test.

  TRY.

    go_test>do_calc( ).

  CATCH lcx_calc_error.

    WRITE ‘Catched’.

  ENDTRY.

Обратите внимание на метод do_calc, в нем описана особая ситуация от которой наследуется lcx_summ_error, соответственно прерывание продолжится на следующий уровень и будет обработано в блоке TRY..CATCH..ENDTRY. При правильно выстроенной архитектуре наследования исключительных ситуаций, прозрачность кода заметно повышается.

В случае, когда используется исключение, наследуемое от CX_NO_CHECK, описание его в интерфейсе метода может быть опущено, т.к. оно инициируется неявным способом системой:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

CLASS lcx_calc_error DEFINITION INHERITING FROM cx_no_check.

ENDCLASS.

CLASS lcx_summ_error DEFINITION INHERITING FROM lcx_calc_error.

ENDCLASS.

CLASS lcl_test_exc DEFINITION.

  PUBLIC SECTION.

  METHODS:

    do_calc,

    do_summ.

ENDCLASS.

CLASS lcl_test_exc IMPLEMENTATION.

  METHOD do_calc.

    do_summ( ).

  ENDMETHOD.

  METHOD do_summ.

    RAISE EXCEPTION TYPE lcx_summ_error.

  ENDMETHOD.

ENDCLASS.

DATA:

  go_test TYPE REF TO lcl_test_exc.

START-OF-SELECTION.

  CREATE OBJECT go_test.

  TRY.

    go_test>do_calc( ).

  CATCH lcx_calc_error.

    WRITE ‘Catched’.

  ENDTRY.

Очистка после вызовов исключений

Блок CLEANUP исполняется, когда выполнен выход из блока TRY-ENDTRY, так как система не смогла найти обработчик для исключения в определенном блоке TRY-ENDTRY, но особая ситуация обрабатывается в окружающем блоке TRY-ENDTRY или передается вызывающей программе.

Данный блок обычно применяется для освобождения занятых ресурсов: очистке ссылочных переменных, закрытие локаторов или наборов данных (datasets) и т.п. Допустим, Вы записываете некоторые данные в файл на сервере приложений. Внутри блока TRY Вы открываете набор данных (dataset) и начинаете запись в него. Однако в некоторый момент, случается особая ситуация, которую вы не обработали и блок TRY прерывает свою работу, при этом, не выполнив закрытие набора данных. Для того чтобы избежать подобной ситуации воспользуемся ключевым словом CLEANUP:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

TRY.

*  Открываем файл на запись:

   OPEN DATASET lv_file FOR OUTPUT IN TEXT MODE

                        ENCODING DEFAULT.

*  Переносим данные в файл:

   LOOP AT lt_extract INTO ls_record.

      PERFORM sub_format_record CHANGING ls_record.

      TRANSFER ls_record TO lv_file.

   ENDLOOP.

*  Закрываем файл:

   CLOSE DATASET lv_file.

CATCH cx_sy_file_access_error INTO lr_file_ex.

*  Ошибки ввода, вывода (датасет в таком случае не открыт)…

CATCH lcx_format_error INTO lr_format_ex.

*  Обрабатываем свою внутренюю ошибку при форматировании…

*  при этом необходимо закрыть набор данных

   CLOSE DATASET lv_file.

CLEANUP.

*  В случае если возникнет не обработанное исключение закроем набор данных:

   CLOSE DATASET lv_file.

ENDTRY.

В случае возобновляемых оператором RESUME исключений, блок CLEANUP не выполняется. Блок CLEANUP, как и блок CATCH позволяет получить ссылочную переменную на вызванное исключение, с помощью дополнения [INTO oref].

Передача исключений по цепочке

Необходимо понимать, что особая ситуация может передаваться через любое количество иерархий вызова перед финальной обработкой. Одна особая ситуация может инициировать вторую и т. д. Каждая инстанция должна оставаться действительной, независимо то того, был ли связанный блок CATCH уже обработан или нет. Поэтому необходимо убедиться, что предыдущая инстанция особой ситуации доступна с помощью, по крайней мере, одной ссылки. Атрибут общей инстанции PREVIOUS, наследуемый всеми классами особых состояний из CX_ROOT, обеспечивает удобный для этого способ.

Пример:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

CLASS lcx_very_big DEFINITION INHERITING FROM cx_static_check.

ENDCLASS.

CLASS lcx_calc_error DEFINITION INHERITING FROM cx_static_check.

ENDCLASS.

CLASS lcl_test_exceptions DEFINITION.

  PUBLIC SECTION.

    METHODS:

      do_calc IMPORTING

                i_num_1 TYPE i OPTIONAL

                i_num_2 TYPE i OPTIONAL

              RETURNING VALUE(re_result) TYPE i

              RAISING lcx_calc_error.

  PRIVATE SECTION.

    METHODS:

      do_summ IMPORTING

                i_num_1 TYPE i OPTIONAL

                i_num_2 TYPE i OPTIONAL

              RETURNING value(re_summ) TYPE i

              RAISING lcx_very_big.

ENDCLASS.

CLASS lcl_test_exceptions IMPLEMENTATION.

  METHOD do_summ.

    re_summ = i_num_1 + i_num_2.

    IF re_summ > 100.

      RAISE EXCEPTION TYPE lcx_very_big.

    ENDIF.

  ENDMETHOD.

  METHOD do_calc.

    DATA:

      lo_very_big TYPE REF TO lcx_very_big.

    TRY.

      me>do_summ(

        EXPORTING

          i_num_1 = i_num_1

          i_num_2 = i_num_2

        RECEIVING

          re_summ = re_result

      ).

    CATCH lcx_very_big INTO lo_very_big.

      RAISE EXCEPTION TYPE lcx_calc_error EXPORTING previous = lo_very_big.

    ENDTRY.

  ENDMETHOD.

ENDCLASS.

DATA:

  go_test_exceptions TYPE REF TO lcl_test_exceptions,

  gv_result TYPE i,

  go_calc_error TYPE REF TO lcx_calc_error,

  go_big_error  TYPE REF TO lcx_very_big.

START-OF-SELECTION.

  CREATE OBJECT go_test_exceptions.

  TRY.

    go_test_exceptions>do_calc(

      EXPORTING

        i_num_1   = 1000

        i_num_2   = 500

      RECEIVING

        re_result = gv_result

    ).

  CATCH lcx_calc_error INTO go_calc_error.

    go_big_error ?= go_calc_error>previous.

  ENDTRY.

Таким образом, пройдя по цепочке, мы всегда можем определить, в каком конкретном месте было инициировано исключение и что из-за этого произошло. Иногда при построении какой-либо ООП модели, удобно собрать всю цепочку из ошибок в каком-нибудь одном виде и выдать в качестве универсального исключения, в качестве примера рекомендую посмотреть этот пример.

Возобновляемые исключения и повтор блока TRY

При срабатывании исключения, выполнение программы в текущем контексте завершается. Иногда необходимо не завершать выполнение текущего контекста, для этого были созданы так называемые возобновляемые исключения. Для того чтобы вызвать такое исключение, необходимо в операторе RAISE (или в THROW) указать что вызывается именно возобновляемое исключение, при этом для того чтобы воспользоваться оператором RESUME (который возвращает код обратно в то место где было вызвано исключение), необходимо у оператора CATCH указать дополнение BEFORE UNWIND (обозначает обработку возобновляемого исключения), иначе система вызовет исключение CX_SY_ILLEGAL_HANDLER. При возврате в контекст, из которого было вызвано исключение блок CLEANUP не вызывается. Если в указанном в CATCH блоке не будет вызван оператор RESUME, контекст будет удален при выходе из блока CATCH.

Пример обработки возобновляемого исключения:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

CLASS lcx_no_num DEFINITION INHERITING FROM cx_static_check.

ENDCLASS.

CLASS lcx_less_zero DEFINITION INHERITING FROM cx_no_check.

ENDCLASS.

CLASS lcl_test_exceptions DEFINITION.

  PUBLIC SECTION.

    METHODS:

      do_summ IMPORTING

                i_num_1 TYPE i OPTIONAL

                i_num_2 TYPE i OPTIONAL

              RETURNING value(re_summ) TYPE int1

              RAISING RESUMABLE(lcx_no_num).

ENDCLASS.

CLASS lcl_test_exceptions IMPLEMENTATION.

  METHOD do_summ.

    IF i_num_1 IS NOT SUPPLIED OR i_num_2 IS NOT SUPPLIED.

      » Данное исключение присутствует в интерфейсе, может быть обработано вне метода

      RAISE RESUMABLE EXCEPTION TYPE lcx_no_num.

    ENDIF.

    TRY.

      re_summ = i_num_1 + i_num_2.

      » Динамическая ошибка, при её обработке обнулим результат

    CATCH CX_SY_CONVERSION_OVERFLOW.

      re_summ = 0.

    ENDTRY.

  ENDMETHOD.

ENDCLASS.

DATA:

  go_test_exceptions TYPE REF TO lcl_test_exceptions,

  gv_summ TYPE int1.

START-OF-SELECTION.

  CREATE OBJECT go_test_exceptions.

  TRY.

    go_test_exceptions>do_summ(

      EXPORTING

        i_num_2 = 1

      RECEIVING

        re_summ = gv_summ

    ).

  CATCH BEFORE UNWIND lcx_no_num.

    RESUME.

  ENDTRY.

  WRITE: / ‘Cумма без указания 1-го числа’, gv_summ.

  go_test_exceptions>do_summ(

    EXPORTING

      i_num_1 = 999

      i_num_2 = 1

    RECEIVING

      re_summ = gv_summ

  ).

  WRITE: / ‘Результат cуммы 999 и 1:’, gv_summ.

При обработке исключений так же есть возможность повтора блока TRY..CATCH, делается это с использованием оператора RETRY. Пример:

PARAMETERS: number1 TYPE i,

            number2 TYPE i.

DATA result  TYPE p DECIMALS 2.

TRY.

    result = number1 / number2.

  CATCH cx_sy_zerodivide.

    number1 = 0.

    RETRY.

ENDTRY.

В данном случае если номер 2 будет равен нулю, система вызовет исключение, с помощью RETRY мы заново запустим блок TRY..CACTH, при этом уже исключение не возникнет, т.к. при делении нуля на ноль результатом будет ноль.

Отображение сообщений из классов сообщений в тексты исключений

Начиная с версии 6.40, появилась возможность связывать тексты исключительных сообщений с классами сообщений (транзакция SE91). Как уже упоминалось выше для этого необходимо в конструкторе класса, указать галочку класс сообщений. При этом вместо интерфейса IF_MESSAGE будет внедрен интерфейс IF_T100_MESSAGE (таблица T100 хранит в себе эти сообщения):

19

При редактировании текста, необходимо будет привязать его к классу и номеру сообщения, при этом заполнить параметры, если это необходимо:

20

Начиная с NW 2004, оператор MESSAGE позволяет напрямую обработку исключений, внедряющих интерфейс IF_T100_MESSAGE:

TRY.

   ...

CATCH cx_some_exception INTO lr_ex.

   MESSAGE lr_ex TYPE ‘E’.

ENDTRY.

Локальный класс исключения в приватном методе глобального класса

Бывают ситуации, когда для какого-либо приватного метода необходимо реализовать исключение, которое может быть вызвано исключительно данным методом (классом).  Реализовать подобное можно, если создать локальный класс исключений:

  • Перейти в локальные определения/внедрения:

21

  • Создать класс исключения:

22

  •  Указать в методе имя локального класса исключения (обязательно в режиме редактирования исходного кода):

23

Результат:

24

Если попробовать сделать тоже самое в режиме редактирования на основе формуляров, выскочит предупреждение о том, что такого класса не существует:

25

Более подробно об исключениях можно почитать в официальной документации:

http://help.sap.com/abapdocu_740/en/abenabap_exceptions.htm

abap

Message types in ABAP as in every programming language are used to give information to the user or programmer about the status of the programming code execution. In ABAP there are 6 types of messages, which are available:

Type A (abend – abnormal end of task)

Type A (abend – abnormal end of task) means termination of the program. The message appears in a dialog box and the program terminates. The user is not able to make any further entries. The task is terminated and the system returns to a high-level menu. Messages of type A should be issued only in extraordinary circumstances, such as serious system errors. A-messages should be avoided, if possible.

Type E (error)

Type E is for error messages. An error message appears and the program stops. These messages are wide used. They can prevent the user from creating inconsistent records. They can point to a prerequisite to be fulfilled.

Type I (information)

Messages from type I are information only. The program is executed and information is displayed. After the user confirms the message, the program continues.

Type S (success, status)

Type S (success, status) messages only give information about the execution of the program. The only display the status of the program.

Type W (warning)

Waring messages are with type W. They are used to display information for the user, which warns the user for possible problems, but they don’t stop the program. The user can than perform corrections.

Type X (exit)

Messages from type X (exit) are the popular ABAP short dumps. The program terminates and the detailed information can be found in transaction ST22, searching by the user and the time of the error.

Syntax

The syntax for message is MESSAGE <message> TYPE <message type>.

For example if we want to display a warning message:

MESSAGE ‘This is a warning message.’ TYPE ‘W’.

The usage of messages can vary in the different programs and functional requirements. The programmer should carry for the proper and good professional usage of messaging.

Check also the meaning of SY-SUBRC here.

Messages in ABAP

Home

Messages

Сообщения хранятся в massages class, создать который можно в SE91.

Обычно на каждый ABAP проект используется один massages class.

SE91

Создание massages class для использования в ABAP программе или проекте. На вкладке Сообщения нужно задать текст для сообщений.

qownnotes-media-AkGDdH

MASSAGE-ID

Это ключ-слово (имя massages class в se91) по которому можно massages class присвоить программе (report) и тогда все сообщения из massages class станут доступными для вызова из программы.

*Link massages class to report program
REPORT ZTEST_MASSAGES MESSAGE-ID ZCUST_TEST_MASSAGES.

Syntax

Без предварительного создания massages class

*задание напрямую в коде, без предварительного создания massages class
MASSAGE <massage> TYPE '<message type>'.

С предварительным созданием massages class

REPORT ZTEST_MASSAGES MESSAGE-ID <massages_class>.

*задание через предварительное создание <massages_class>.
MASSAGE <message_type><massageclass_text_id>.

MASSAGES TYPES

A — Termination

Прекращение работы программы, появляется как dialog box, после подтверждения пользователем возвращает область вышестоящего меню.

qownnotes-media-tIktYr

I — Information

Показывается как dialog box, после подтверждения пользователем выполнение программы продолжается со строки кода идущей сразу после блока кода вызова сообщения.

qownnotes-media-pgylih

E — Error

Сообщении об ошибке будет показано в строке состояния и после нажатия enter программа завершиться.

qownnotes-media-AKpJKf

W — Warning

Будет показано в строке состояния.

qownnotes-media-jWfKhh

S — Status

Программа продолжает выполнение не останавливаясь на блоке кода сообщения, а само сообщение появляется в строке состояния на следующем экране.

qownnotes-media-hMWtuI

X — Exit

Сообщений не выводится, а программа завершается с кратким дампом.

ST22

Краткий дам можно посмотреть в ST22, где будет указана причина runtime errors.

Example

Сначала нужно создать massages class ZCUST_TEST_MASSAGES как в пункте SE91,затем его можно использовать в программе. Код примера программы ниже:

*Link massages class to report program
REPORT ZTEST_MASSAGES MESSAGE-ID ZCUST_TEST_MASSAGES.

TABLES SSCRFIELDS.
PARAMETERS P_X TYPE I.

SELECTION-SCREEN FUNCTION KEY 1.
SELECTION-SCREEN FUNCTION KEY 2.
SELECTION-SCREEN FUNCTION KEY 3.
SELECTION-SCREEN FUNCTION KEY 4.
SELECTION-SCREEN FUNCTION KEY 5.

INITIALIZATION.

SSCRFIELDS-FUNCTXT_01 = 'ABAP EDITOR'.
SSCRFIELDS-FUNCTXT_02 = 'FUNCTION BUILDER'.
SSCRFIELDS-FUNCTXT_03 = 'CLASS BUILDER'.
SSCRFIELDS-FUNCTXT_04 = 'FORM PAINTER'.
SSCRFIELDS-FUNCTXT_05 = 'SMARTFORMS'.

AT SELECTION-SCREEN.
CASE SY-UCOMM.
  WHEN 'K1'.
    LEAVE PROGRAM.

*X - Exit  
*  WHEN 'FC01'.
*    MESSAGE X005.
*    CALL TRANSACTION 'SE38'.

*A - Termination
  WHEN 'FC01'.
    MESSAGE A000.
    CALL TRANSACTION 'SE38'.

*E - Error
  WHEN 'FC02'.
    MESSAGE E001.
    CALL TRANSACTION 'SE37'.

*I - Information
  WHEN 'FC03'.
    MESSAGE I002.
    CALL TRANSACTION 'SE24'.

*S - Status
  WHEN 'FC04'.
    MESSAGE S003.
    CALL TRANSACTION 'SE71'.

*W - Warning
  WHEN 'FC05'.
    MESSAGE W004.
    CALL TRANSACTION 'SMARTFORMS'.

ENDCASE.

qownnotes-media-VdCuqd

Cкрины самих сообщений см в пункте messages types.

REPORT zdemomessages.

*&———————————————————————&*

*& Program Description:                                               &*

*& ————————                                            &*

*& This demo program will demonstrate the different types of SAP ABAP &*

*& messages.                                                          &*

*&                                                                    &*

*& Author:  ABAPCOOKBOOK                                              &*

*& Website: www.abapcookbook.com                                      &*

************************************************************************

************************************************************************

* SELECTION SCREEN                                                     *

************************************************************************

PARAMETERS:

  rb_msg01 RADIOBUTTON GROUP msg DEFAULT ‘X’,   » Success Message

  rb_msg02 RADIOBUTTON GROUP msg,               » Error Message

  rb_msg03 RADIOBUTTON GROUP msg,               » Warning Message

  rb_msg04 RADIOBUTTON GROUP msg,               » Information Message

  rb_msg05 RADIOBUTTON GROUP msg,               » Abend/Termination Message

  rb_msg06 RADIOBUTTON GROUP msg.               » Exit Message

************************************************************************

* SAMPLE CODE LOGIC FOR DEMONSTRACTION PURPOSES                        *

************************************************************************

START-OF-SELECTION.

  CASE ‘X’.

*   Success Message.

*   A success message appears along the SAP Logon footer (in green)

*   and processing is not stop.

    WHEN rb_msg01.

        MESSAGE ‘This is an example of a SUCCESS message.’ TYPE ‘S’.

*   Error Message.

*   Error message appears along the SAP Logon footer (in red) and

*   processing is stopped.

    WHEN rb_msg02.

      MESSAGE ‘This is an example of an ERROR message.’ TYPE ‘E’.

*   Warning Message.

*   Warning message is similar to error message, however depending

*   on the context, error message may appear or program terminated.

    WHEN rb_msg03.

      MESSAGE ‘This is an example of a WARNING message.’ TYPE ‘W’.

*   Information Message.

*   An information message appears in a popup window, processing halt.

*   When the user close the information message, processing resume.

    WHEN rb_msg04.

      MESSAGE ‘This is an example of an INFORMATION message.’ TYPE ‘I’.

*   Abend/Termination Message.

*   A termination message will stop processing and an exit button will

*   appears which will exit the session.

    WHEN rb_msg05.

      MESSAGE ‘This is an example of a TERMINATION message.’ TYPE ‘A’.

*   Exit Message.

*   An exit message will normally terminated the program. Usually, a

*   stack dump for the state of the system is raised (can be viewed in ST22).

    WHEN rb_msg06.

      MESSAGE ‘This is an example of an EXIT message.’ TYPE ‘X’.

  ENDCASE.

MESSAGE Class (SE91)

Сообщения бывают следующих типов:

I – Information messages

Информационное сообщение, появляющееся в виде выскакивающего окна.

E – Error message
Сообщение об ошибке, отображается с строке статуса.

W – Warning message
Предупреждающее сообщение, отображается также в строке статуса.

S – Success/Status message
Успешное завершение

A – Termination/Abend
Ненормальное завершение

После создания класса сообщения его можно вызвать программно

Пример вызова

REPORT zkre_hw5 MESSAGE-ID ZMSGNIK.
START-OF-SELECTION.
MESSAGE e001.

Пример 2

 MESSAGE |Result{ result ALIGN LEFT }| TYPE ‘I’

ООП

Локальные классы

Локальные классы состоят из ABAP кода, заключенного между операторами CLASS … ENDCLASS. Полное описание класса состоит из секции объявлений и, если необходимо, из секции реализации.

Пример:

CLASS <class> DEFINITION.

ENDCLASS.

1.5.4Области видимости

Секция объявлений может включать от одной до трех областей видимости.

CLASS <class> DEFINITION.
PUBLIC SECTION.

PROTECTED SECTION.

PRIVATE SECTION.

ENDCLASS.

ПРИМЕРЫ КЛАССОВ С ОБЛАСТЬЮ ВИДИМОСТЕЙ МЕТОДОВ И ИХ РЕАЛИЗАЦИЕЙ

CLASS c_counter DEFINITION.

PUBLIC SECTION.

METHODS: set IMPORTING value(set_value) TYPE i,

increment,

get EXPORTING value(get_value) TYPE i.

PROTECTED SECTION.

DATA count TYPE i.

ENDCLASS.

CLASS c_counter IMPLEMENTATION.

METHOD set.

count = set_value.

ENDMETHOD.

METHOD increment.

ADD 1 TO count.

ENDMETHOD.

METHOD get.

get_value = count.

ENDMETHOD.

ENDCLASS.

ВЫЗОВ МЕТОДОВ

DATA: h1 TYPE REF TO c_counter.

START-OF-SELECTION.

CREATE OBJECTh1.
CALL METHOD h1->increment.

С ОПЕРАТОРОМ RETURN

REPORT zprogram1denisov.
CLASS sqr DEFINITION.
PUBLIC SECTION.
CLASS-METHODSsqr IMPORTING VALUE(numTYPE f
RETURNING VALUE(resTYPE f.
PROTECTED SECTION.
CLASS-DATA NUM TYPE f.
CLASS-DATA RES TYPE f.
ENDCLASS.

CLASS sqr IMPLEMENTATION.
METHOD sqr.
RES NUM * NUM.
WRITE / res.
ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

sqr=>sqr).

Наследование 

Наследование реализуется с помощью дополнения INHERITING FROM в операторе описания класса:

CLASS <subclass> DEFINITION
INHERITING FROM <superclass>.

ПРИМЕР:

CLASS lcl_base DEFINITION.

PUBLIC SECTION.

METHODS:

method1,

method2.

ENDCLASS.

CLASS lcl_sub_class DEFINITION INHERITING FROM lcl_base.

PUBLIC SECTION.

НАСЛЕДОВАНИЕ С ВЫЗОВОМ МЕТОДА СУПЕРКЛАССА В НАСЛЕДНИКЕ

CLASS counter DEFINITION.
PUBLIC SECTION.
METHODS: set IMPORTING value(set_value) TYPE i,
increment,
get EXPORTING value(get_value) TYPE i.
PROTECTED SECTION .
DATA count TYPE i.
ENDCLASS.

CLASS counter IMPLEMENTATION.
METHOD set.
count = set_value.
ENDMETHOD.
METHOD increment.
ADD 1 TO count.
ENDMETHOD.
METHOD get.
get_value = count.
ENDMETHOD.
ENDCLASS.

CLASS counter_ten DEFINITION INHERITING FROM counter.
PUBLIC SECTION.
METHODS increment REDEFINITION .
DATA count_ten.
ENDCLASS.

CLASS counter_ten IMPLEMENTATION.
METHOD increment.
DATA modulo TYPE I.
CALL METHOD super->increment .
write / count.
modulo = count mod 10.
IF modulo = 0.
count_ten = count_ten + 1.
write count_ten.
ENDIF.
ENDMETHOD.
ENDCLASS.

DATA: count TYPE REF TO counter,
number TYPE i VALUE 5.

START-OF-SELECTION.

   CREATE OBJECT count TYPE counter_ten .

  CALL METHOD count->set EXPORTING set_value = number.

  DO 20 TIMES.
CALL METHOD count->increment.
ENDDO.

ИНТЕРФЕЙСЫ

Так же как и классы, интерфейсы могут определяться либо глобально, либо локально в ABAP программе.

Пример:

INTERFACE <intf>.

ENDINTERFACE.

Генерация событий

Событие инстанции в классе может быть сгенерировано любым методом класса. Статические события могут быть сгенерированы только любым статическим методом. Для генерации события в методе используется следующий оператор

RAISE EVENT <evt> EXPORTING… <ei> = <fi>…

Определение методов – обработчиков событий

Любой класс может иметь методы, являющиеся обработчиками событий для событий из других классов. Существует также возможность определить методы -обработчики событий в том же классе, где определено событие. Для определения метода-обработчика события используется следующий оператор для метода инстанции.

METHODS <meth> FOR EVENT <evt> OF <cif>
IMPORTING..
<ei>..

ПРИМЕР РЕАЛИЗАЦИИ МЕТОДА И СОБЫТИЯ ( ПЕРЕДАЧА ПАРАМЕТРА В СОБЫТИЕ)

REPORT demo_class_counter_event.

CLASS counter DEFINITION.
PUBLIC SECTION.
METHODS increment_counter.
EVENTS  critical_value
EXPORTING value(excess) TYPE i.
PRIVATE SECTION.
DATA: count     TYPE i,
threshold TYPE i VALUE 10.
ENDCLASS.

CLASS counter IMPLEMENTATION.
METHOD increment_counter.
DATA diff TYPE i.
ADD 1 TO count.
IF count > threshold.
diff = count – threshold.
RAISE EVENT critical_value
EXPORTING excess = diff.
ENDIF.
ENDMETHOD.
ENDCLASS.

CLASS handler DEFINITION.
PUBLIC SECTION.
METHODS handle_excess
FOR EVENT critical_value OF counter
IMPORTING excess.
ENDCLASS.

CLASS handler IMPLEMENTATION.
METHOD handle_excess.
WRITE: / ‘Excess is’, excess.
ENDMETHOD.
ENDCLASS.

DATA: r1 TYPE REF TO counter,
h1 TYPE REF TO handler.

START-OF-SELECTION.

  CREATE OBJECT: r1, h1.

  SET HANDLER h1->handle_excess FOR ALL INSTANCES. ” для реализации метода для события

  DO 20 TIMES.
CALL METHOD r1->increment_counter.
ENDDO.

ТОЖЕ САМОЕ СО СТАТИЧЕСКИМИ ПОЛЯМИ, МЕТОДАМИ И СОБЫТИЯМИ

CLASS counter DEFINITION.
PUBLIC SECTION.
CLASS-METHODSincrement_counter.
CLASS-EVENTS critical_value
EXPORTING VALUE(excessTYPE i.
PRIVATE SECTION.
CLASS-DATAcount     TYPE i,
threshold TYPE VALUE 10.
ENDCLASS.

CLASS counter IMPLEMENTATION.
METHOD increment_counter.
DATA diff TYPE i.
ADD TO count.
IF count > threshold.
diff count – threshold.
RAISE EVENT critical_value
EXPORTING excess diff.
ENDIF.
ENDMETHOD.
ENDCLASS.

CLASS handler DEFINITION.
PUBLIC SECTION.
CLASS-METHODS handle_excess
FOR EVENT critical_value OF counter
IMPORTING excess.
ENDCLASS.

CLASS handler IMPLEMENTATION.
METHOD handle_excess.
WRITE‘Excess is’excess.
ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

SET HANDLER handler=>handle_excess.

DO 20 TIMES.
CALL METHOD counter=>increment_counter.
ENDDO.

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • 2a53 ошибка bmw e90
  • Android adb interface произошла ошибка