Оператор MESSAGE служит для диалогового взаимодействия с пользователем. Существует шесть типов сообщения.
Тип | Описание |
---|---|
S | Status (Success). Сообщение отображается в статусной строке и не влияет на работу программы. Данный вид сообщения применяется для информирования об успешной выполнении операции.![]() |
W | Warning. Предупредительные сообщения отображаются в статусной строке. При возникновении сообщения работа программы прерывается, а пользователю предоставляется возможность вносить исправления в полях для ввода. При нажатии на Enter в диалоговом режиме, работа программы будет восстановлена.![]() |
E | Error. Сообщение отображается в статусной строке. При возникновении данного вида сообщения обработка программы останавливается.![]() |
I | Information. Информационное сообщение отображается в отдельном модальном окне. При возникновении сообщения работа программы прерывается. После закрытия диалога работа программы восстанавливается.![]() |
A | Abend (Abort). Сообщение отображается в модальном окне. При возникновении сообщения программа завершается, а система возвращается в меню более высокого уровня. Сообщения стоит применять только в крайних ситуациях.![]() |
X | Exception. Сообщение инициирует дамп MESSAGE_TYPE_X. Данный вид сообщения стоит применять в ситуациях, когда нужно проанализировать что именно привело к ошибке во время выполнения.![]() |
Синтаксис
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
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. |
Результат работы программы
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. |
Результат работы программы
В системных полях будет сообщение базисного класса 001(00)
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. |
Результат работы программы
Значения системных полей
MESSAGE — WITH
MESSAGE … WITH dobj1 … dobj4.
Сообщения могут содержать параметры, которые передаются через дополнение WITH. Пример вывода сообщения 076(va) с двумя параметрами.
*&———————————————————————* *& Вывод сообщения с параметрами *& http://abap4.ru/?p=360 *&———————————————————————* REPORT z_message. START-OF-SELECTION. PERFORM main. FORM main. MESSAGE i076(va) WITH ‘TESTVAR’ sy—repid. ENDFORM. |
Результат работы программы
MESSAGE — DISPLAY LIKE
MESSAGE … DISPLAY 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. |
Результат работы программы
MESSAGE — INTO
MESSAGE … INTO 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: ‘, sy—msgid. WRITE: / ‘SY-MSGTY: ‘, sy—msgty. WRITE: / ‘SY-MSGNO: ‘, sy—msgno. WRITE: / ‘SY-MSGV1: ‘, sy—msgv1. WRITE: / ‘SY-MSGV2: ‘, sy—msgv2. WRITE: / ‘SY-MSGV3: ‘, sy—msgv3. WRITE: / ‘SY-MSGV4: ‘, sy—msgv4. ENDFORM. |
MESSAGE — RAISING
MESSAGE … RAISING 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 sy—subrc = 4. ENDIF. ENDFORM. |
В статье вы найдете актуальные рекомендации по решению различных ошибок в рамках поддержки системы SAP CRM. Эти рекомендации – сумма личного опыта автора, опыта его коллег и выводов из анализа многих книг/статей по релевантным темам в системе SAP CRM.
Оглавление
Введение
Список основных SAP веб-ресурсов
Общие рекомендации по решению ошибок в системе SAP
Роли полномочий (PFCG-роли)
Полезные документы
Как выполнить транзакцию в SAP GUI при отсутствии полномочий
Как узнать какой авторизационный объект проверяется системой
Бизнес-роли (интерфейс WebUI)
Полезные документы
Алгоритм определения бизнес-роли
Как определяется язык входа по умолчанию при запуске WebUI интерфейса
Как сделать Т-образную конфигурацию ракурса
Ракурс поиска – как добавить новый оператор для критерия поиска
Интерфейс SAP GUI
Как определяется язык входа по умолчанию при запуске SAP GUI интерфейса
SAP Basis
Как открыть/закрыть продуктивную систему для изменений
Как задать правила для введения паролей в SAP системе
Как выгрузить файл с сервера (транзакция AL11)
Пользовательские параметры – транзакция SU3 вкладка «Параметры»
АВАР
Полезные документы
Бесконечный цикл
Как дебажить POP-UP окно в SAP GUI интерфейсе
Как программировать без ключа разработчика
Основные и транзакционные данные
Удаление основных и транзакционных данных
Middleware – механизм обмена данных
Сроки на операции. XML правила
Введение
В статье Вы найдете актуальные рекомендации по решению различных ошибок в рамках поддержки системы SAP CRM. Эти рекомендации – сумма личного опыта автора, опыта его коллег и выводов из анализа многих книг/статей по релевантным темам в системе SAP CRM.
Дополнительно в статье рассказывается о некоторых полезных инструментах «фишках», которые часто помогают в продуктивной системе воспроизвести ошибку и найти пути её решения при наличии очень малого количества прав.
Ниже приведены ссылки на основные веб-ресурсы, где можно найти информацию по SAP CRM.
Общие ресурсы.
- https://help.sap.com – «справка» достаточно подробная, часто гораздо лучше курсов, если требуется разобраться в конкретном вопросе.
- https://blogs.sap.com – здесь можно найти множество статей по самым различным темам.
- https://wiki.scn.sap.com/wiki/display/CRM/Customer+Relationship+Management – это своего рода Wikipedia для SAP CRM.
- https://influence.sap.com/sap/ino/#/campaign – ресурс, на котором можно отслеживать новые доработки в области SAP CRM. Идея в том, что SAP запустил программу, где пользователи публикуют пожелания к функциональности системы SAP CRM. Затем идут голосование и реализация тех доработок, которые набрали максимальное число голосов в данном календарном году.
- http://blog.acorel.nl – блог голландской компании со множеством коротких и полезных статей по SAP CRM.
- http://www.sapfans.com – довольно популярный форум на английском языке.
- http://sapuniversity.eu
Ресурсы на русском языке.
- http://sapboard.ru
- https://sapland.ru
Специализированные ресурсы – SAP Security.
- http://www.mariewagener.de/Notes.PDF.Download
- http://www.sapsecurityexpert.com
- http://www.sapsecuritypages.com
Общие рекомендации по решению ошибок в системе SAP
ВАЖНО – в первую очередь надо обязательно убедиться, что имеет место именно «ошибка». Тяжелей всего чинить то, что не сломалось. Часто обращения пользователей по поводу «ошибки системы» лечатся чтением инструкции.
Алгоритм работы при обнаружении ошибки в системе SAP:
- Читаем внимательно сообщение об ошибке – проверяем настройки в системе.
- Ищем, не обсуждалась ли подобная ошибка на форумах.
- Ищем ноту по коду ошибки и ключевым словам, описывающим проблему.
- Если нота не найдена, то заводим сообщение в поддержку SAP, детально описываем ошибку и ждем ответа.
- Если ждать нет возможности, то можно обратиться в чате к эксперту SAP.
- Если нет результата или хочется самостоятельно разобраться в причине – запускаем транзакцию под отладчиком и «дебажим», то есть проверяем логику работы программы до наступления ошибки.
Несколько лирических отступлений.
Поиск подобной ошибки на форумах:
- Прежде чем задать вопрос, обязательно пользуйтесь «поиском», так как в большинстве случаев вы самостоятельно найдете ответ.
- Если задаете вопрос, то старайтесь узко и точно его сформулировать. На такого рода вопросы практически всегда дают ответы. А вот на общие вопросы шанс получить ответ минимальный.
Нота – SAP Note:
- Нота – это «заметка», выпускаемая SAP, описывающая проблему и способы ее решения.
- Помимо текстовой части нота может содержать исправления (корректуры) для программ.
- Ноты следует искать на веб-ресурсе https://launchpad.support.sap.com
- Установка ноты осуществляется через транзакцию SNOTE.
Сообщение – SAP Message:
- Это сообщение в команду поддержки SAP об ошибке в вашей системе.
- Сообщение следует заводить на том же веб-ресурсе https://launchpad.support.sap.com через пункт меню «Report an Incident» (рис. 1).
Чат – SAP Chat:
- Это чат с экспертом SAP (плановая сессия или режим реального времени).
- Важно помнить, что чат в реальном времени может состоятся только, если доступен эксперт SAP по теме вашего обращения на текущий момент.
- Чат следует инициировать на том же веб-ресурсе https://launchpad.support.sap.com через пункт меню «Expert Chat» (рис. 1).
Рис. 1 – Пункты меню для инициации SAP Message и SAP Chat.
Это было описание общих правил и рекомендаций, которые сокращают время решения типичных ошибок в системе SAP CRM. Теперь давайте перейдём непосредственно к рассмотрению самих ошибок и полезных инструментов.
Роли полномочий (PFCG-роли)
Полезные документы
Роль полномочий – сущность в системе SAP CRM, которая описывает, какие именно действия может осуществлять пользователь в системе.
Книга «SAP CRM AUTHORIZATIONS. Concepts and examples».
- Автор: Davy Pelssers
- Год публикации: 2007
- Источник: http://sapuniversity.eu/wp-content/uploads/2012/11/SAP-AUTHORIZATIONS-V3.pdf
Данная книга доступна по ссылке выше и по личному запросу на электронный адрес автора – davy.pelssers@contactoffice.net. Книга представляет собой полное и детальное описание механизма работы полномочий именно в системе SAP CRM.
Статья «PFCG Roles and Authorization Concept. SAP CRM 7.0».
- Автор: SAP AG
- Год публикации: 2009
- Источник: http://www.sdn.sap.com/irj/scn/index?rid=/library/uuid/00515e75-f1d0-2c10-bebb-e5675f470ee6
В данной статье описывается алгоритм определения бизнес-роли, в частности значение настройки привязки роли-полномочий к бизнес-роли (рис. 2). Идея в том, что данная связь участвует в системе SAP CRM для определения Бизнес-Роли, а не наоборот (см. ниже раздел – Алгоритм определения Бизнес-роли).
Рис. 2 – Настройка привязки роли-полномочий к бизнес-роли.
Далее давайте рассмотрим несколько полезных инструментов «фишек» при работе с полномочиями в системе SAP CRM.
Как выполнить транзакцию в SAP GUI при отсутствии полномочий
Пример сообщения о нехватке полномочий выглядит следующим образом (рис. 3).
Рис. 3 – сообщение о нехватке полномочий.
Метод обхода проверки полномочий.
- Ставим точку прерываний в функциональном модуле SMTR_KERNEL_CHECK_AUTHORITY – строка 35 (рис. 4).
Рис. 4 – Проверка полномочий на выполнение транзакции.
- В новом окне включаем системную отладку – транзакция /HS.
- Затем запускаем нашу транзакцию и проваливаемся в отладчик.
- Доходим до нашей точки прерывания и перепрыгиваем проверку полномочий.
- Как результат нужная транзакция будет выполнена.
ВАЖНО – для данного способа необходимо иметь полномочия на отладку с подменой значения.
Альтернативный способ.
В транзакции ST01 включить трассировку – возобновить ошибку – узнать недостающий объект полномочий – запросить себе недостающие полномочия (рис. 5).
Рис. 5 – Меню управления в транзакции ST01.
Как узнать какой авторизационный объект проверяется системой
Эту задачу можно решить с помощью отладчика. При выполнении нашего действия вызываем отладчик и ставим точку прерывания на команде AUTHORITY-CHECK (рис. 6). Затем анализируем все срабатывания точки прерывания пока не будет найдено место, где выполняется проверка нашего объекта авторизации.
Рис. 6 – Установка точки прерывания.
Детально данный метод описан в статье по ссылке https://blogs.sap.com/2014/03/19/how-to-analyze-authorization-issues-in-debug.
Пример использования данного метода.
Пункты навигационного меню не видны в интерфейсе WebUI после их добавления в настройках бизнес-роли (рис. 7). Хорошо бы знать какой объект полномочий отвечает за навигационное меню в интерфейсе WebUI, чтобы проверить присвоены ли требуемые полномочия к нашему пользователю.
Рис. 7 – Объект полномочий для меню в интерфейсе WebUI.
С помощью вышеописанного метода в момент загрузки бизнес-роли можно определить какой объект полномочий система проверяет для каждого пункта меню в интерфейсе WebUI:
- Класс – CL_CRM_UI_NAVBAR_SRV
- Метод – COMP_AUTHORITY_CHECK
- Объект полномочий – UIU_COMP.
Более детальную информацию можно найти в SAP Note – 2550558 «Work center not visible in Web UI Navigation menu».
На этом мы завершаем рассмотрение раздела «Роли полномочий (PFCG-роли)» и переходим к следующему разделу «Бизнес-роли (интерфейс WebUI)».
Бизнес-роли (интерфейс WebUI)
Полезные документы
Бизнес-роль – сущность, которая определяет веб-интерфейс пользователя, то есть то, что он видит в браузере, когда открывает систему SAP CRM.
Web-интерфейс – это интерфейс системы SAP CRM в браузере.
Обязательные PFCG-роли для запуска WebUI:
- SAP_CRM_UIU_FRAMEWORK
- SAP_CRM_UIU_SLS_PROFESSIONAL
Статьи – более детальную информацию по данной теме можно найти по ссылкам ниже:
- http://sapuniversity.eu/logon-is-not-possible-because-you-have-not-been-assigned-to-a-business-role-please-contact-your-system-administrator/
- http://sapuniversity.eu/necessary-authorization-in-order-to-use-the-sap-crm-user-parameter-crm_ui_profile/
Далее давайте рассмотрим несколько полезных инструментов «фишек» при работе и настройке бизнес-ролей и интерфейса WebUI.
Алгоритм определения бизнес-роли
Алгоритм состоит из 3-х последовательных шагов:
- Система проверяет параметр CRM_UI_PROFILE в настройках пользователя (рис. 8).
Рис. 8 – Параметры пользователя.
- Если ничего не найдено на шаге выше, то система проверяет присвоение бизнес-роли в орг. структуре (рис. 9).
Рис. 9 – Присвоение бизнес-роли на орг. структуре.
- Если ничего не найдено на шаге выше, то система получает все PFCG-роли, присвоенные пользователю, и определяет присвоены ли они к бизнес-ролям. Найденная бизнес-роль присваивается пользователю (рис. 10).
Рис. 10 – Присвоение роли полномочий на бизнес-роль.
Более детальную информацию о работе данного алгоритма, можно получить в статье ниже http://www.sdn.sap.com/irj/scn/index?rid=/library/uuid/00515e75-f1d0-2c10-bebb-e5675f470ee6
Как определяется язык входа по умолчанию при запуске WebUI интерфейса.
При запуске WebUI интерфейса в диалоговом окне регистрации входа в систему заполнено поле «Язык». Хочется узнать, как система определяет язык входа по умолчанию, и можно ли его изменить (рис. 11).
Рис. 11 – Диалоговое окно регистрации входа в систему.
Алгоритм определения языка состоит из 5-ти последовательных шагов:
- SICF Service – система проверяет значение в поле «Язык» для вашего сервиса «Запуск интерфейса WebUI» в транзакции SICF (рис. 12).
Рис. 12 – сервис для запуска интерфейса WebUI.
-
WebUI link – если ничего не найдено на шаге выше, то система проверяет содержит ли HTTP запрос параметр SAP-LANGUAGE.
- http://…/sap/bc/bsp/sap/crm_ui_frame/default.htm?s&sap-language=EN
-
Browser language settings – если ничего не найдено на шаге выше, то система проверяет настройки языка в браузере.
- Система берет язык, который установлен как основной в настройках браузера.
- ВАЖНО – язык браузера должен быть установлен/инсталлирован в системе SAP CRM.
- Для IE браузера путь настройки языка: Tools – Internet Options – Languages.
- User Settings – если ничего не найдено на шаге выше, то система проверяет настройки пользователя (транзакция SU01 – поле «Язык входа» на карточке пользователя).
- SAP system default language – если ничего не найдено на шаге выше, то система использует язык, который установлен как язык по умолчанию для системы SAP CRM.
Соответственно, чтобы изменить значение по умолчанию в поле «Язык», достаточно выполнить настройку в одном из пяти пунктов, описанных выше.
Более детальную информацию по данной теме можно найти по ссылкам ниже:
- http://sapuniversity.eu/how-to-set-a-default-logon-language-in-my-sap-crm-web-ui/
- https://help.sap.com/viewer/f7dd32926c1c4fcf889a4303d833a22b/7.5.7/en-US/48cae5c9356c3254e10000000a42189b.html
Как сделать Т-образную конфигурацию ракурса
Рассмотрим интересную задачу, где требуется изменить макет (формат) расположения ракурсов в интерфейсе WebUI (рис. 13).
Рис. 13 – Макет (формат) расположения ракурсов.
Для решения данной задачи необходимо выполнить следующие настройки в системе SAP CRM:
- Настройка в SPRO для ракурса, где регистрируется возможность изменения формата расположения ракурсов.
- Путь меню настройки: SPRO — CRM — Фреймворк UI — Определение архитектуры пользовательского интерфейса — Регистрация обзорных страниц для формата подэкрана.
- Настройка в SPRO для ракурса, где создается новый формат расположения ракурсов.
- Путь меню настройки: SPRO — CRM — Фреймворк UI — Определение архитектуры пользовательского интерфейса — Информационный бюллетень — Обработать информационный бюллетень.
- Настройка конфигурации ракурса, где происходит выбор нового формата (рис. 14).
Рис. 14 – Настройка конфигурации ракурса.
Более детально с данной темой можно ознакомиться в статьях ниже:
- https://www.acorel.nl/2013/08/overview-pages-in-tile-layout/
- https://help.sap.com/doc/saphelp_crm70/7.0.0.18/en-US/12/31441d9a204c29baa10ffe8ff4c3c1/content.htm?no_cache=true
Ракурс поиска – как добавить новый оператор для критерия поиска
Другая интересная задача, где показано как без АВАР-разработки можно добавить новый оператор для критерия поиска в интерфейсе WebUI (рис. 15).
Рис. 15 – Доступные операторы в критериях поиска.
Для решения данной задачи необходимо выполнить следующие настройки в системе SAP CRM:
- В браузере определяем техническое имя для ракурса и атрибута поиска (рис. 16).
Рис. 16 – Техническое имя для ракурса и атрибута поиска.
- Затем определяем имя объекта динамического запроса (рис. 17).
- Путь определения: Транзакция BSP_WD_CMPWB – компонент – ракурс – контекст – узел контекста – напр. BuilHeaderAdvancedSearch.
Рис. 17 – Имя объекта динамического запроса.
- Затем выполняем настройку в SPRO, где задаём доступные операторы для критерия поиска (рис. 18).
- Путь меню настройки: SPRO — CRM — CRM: компоненты, общие для всех приложений — Родовой уровень взаимодействия / уровень объекта — Настройки для компонентов — Определить операторов для динамических запросов.
Рис. 18 – Настройка операторов для критерия поиска.
На этом мы завершаем рассмотрение раздела «Бизнес-роли (интерфейс WebUI)» и переходим к разделу «Интерфейс SAP GUI», где мы рассмотрим одну небольшую задачу.
Интерфейс SAP GUI
Как определяется язык входа по умолчанию при запуске SAP GUI интерфейса
При запуске диалогового окна регистрации входа в SAP GUI (рис. 19) мы хотим, чтобы язык входа уже был заполнен значением, которое нам необходимо, чтобы избегать ручного
Если хотите прочитать статью полностью и оставить свои комментарии присоединяйтесь к sapland
Зарегистрироваться
У вас уже есть учетная запись?
Войти
Предисловие — Этот пост является частью ABAP-новичок серии.
При использовании мобильного телефона и веб-сайтов вы могли видеть несколько всплывающих сообщений, таких как сообщение безопасности на мобильных телефонах о доступе к фотографиям или антивирусное сообщение на ПК об обнаружении вирусов. Все эти сообщения могут быть сообщением об успехе, информацией или сообщением об ошибке. Аналогичным образом мы можем продемонстрировать сообщение SAP и в программах ABAP.
Определение
Сообщение в ABAP используется для отображения текстового сообщения, хранящегося в таблице T100, или любого текста [может быть в классе сообщений], где тип сообщения может быть состоянием, предупреждением, ошибкой и т. д. Сообщение в ABAP также может использоваться для создания исключения.
Класс сообщений SAP
Класс сообщений — это класс, который содержит список сообщений с идентификатором сообщения. Он создается с использованием кода транзакции SE91. Это помогает хранить все сообщения, связанные с проектом/программой, вместе.
Синтаксис
СООБЩЕНИЕ { сообщение | текст
| тн
| тн (идентификатор)
| {ID mid TYPE mtype NUMBER num}
| {oref TYPE mtype}
| {ТИП текста mtype} }
{ { [DISPLAY LIKE dtype] [ПОВЫШЕНИЕ исключения] }
| [В тексте] }
[С добж1…добж4].
Объяснение синтаксиса
Приведенный выше синтаксис объясняется ниже:
Синтаксис | объяснение | Пример |
сообщение | текст или {text TYPE mtype} |
Здесь msg берется из класса T100, а текст — это строка. | СООБЩЕНИЕ ‘Сообщение об успехе’ ТИП ‘I’. |
tn | Ему нужен класс сообщений. Здесь t — один символ, а n — трехзначное число; оба написаны вместе. Эти конкретные tn будут представлять текст, который хранится в классе сообщений. Здесь имя класса сообщения записывается в начале отчета. | ОТЧЕТ ztest ИДЕНТИФИКАТОР СООБЩЕНИЯ zmessageclass.
… СООБЩЕНИЕ s001. -> Здесь s001 — это сообщение, текст которого хранится в zmessageclass. |
тн (идентификатор) | Как и выше, t и n означают одно и то же. Здесь id — это имя класса сообщения, и оно пишется сразу после сообщения. | ОТЧЕТ
… СООБЩЕНИЕ s001 (zmessageclass). |
{ID mid TYPE mtype NUMBER num} | Здесь mid означает класс сообщения, mtype означает тип сообщения (поясняется позже), а num — номер сообщения (число длины три). | ДАННЫЕ: m_id TYPE sy-msgid VALUE ‘zmessageclass’,
m_type TYPE sy-msgty ЗНАЧЕНИЕ ‘I’, m_num TYPE sy-msgno ЗНАЧЕНИЕ ‘001’. ИДЕНТИФИКАТОР СООБЩЕНИЯ m_id ТИП m_type НОМЕР m_num. |
{oref TYPE mtype} | Здесь oref — переменная ссылки на объект, которая указывает на объект, класс которого реализует системный интерфейс IF_T100_MESSAGE. Они в основном используются, когда мы имеем дело с локальными классами внутри отчета. | Проверьте пример на данном ссылке. |
[ОТОБРАЖАТЬ КАК dtype] | Когда используется Display Like, то вместо типа сообщения значок будет соответствовать Display Like | СООБЩЕНИЕ ‘Сообщение об успешном завершении’ ТИП ‘I’ ОТОБРАЖАЕТСЯ КАК ‘E’.
*** Примечание. Приведенное выше сообщение является информативным, но будет отображаться как сообщение об ошибке. |
[ПОВЫШАЕТСЯ исключение] | Он вызывает исключение, не основанное на классе, и отправляет сообщение, только если исключение не было обработано. Это можно сделать через sy-subrc. | МЕТОДЫ КЛАССА msg1 ИСКЛЮЧЕНИЯ excp1.
МЕТОД msg1. СООБЩЕНИЕ ‘Exception msg in a Method’ TYPE ‘I’ RAISING exp1. КОНЕЦ МЕТОД. |
[В тексте] | Этот тип сообщения не влияет на ход программы, и не имеет значения, какой это тип сообщения. Он просто присваивает значение Message пользовательскому полю [здесь текст]. | СООБЩЕНИЕ i001 В ДАННЫЕ (новый текст).
***Примечание. Здесь newText создается динамически и содержит в себе значение i001. Это значение можно использовать позже в той же программе. |
[С добж1… добж4] | Это используется для добавления статического текста вместо ‘&’.
Предположим, мы выводим текст из таблицы T100, и это текст «Я &&». Затем мы можем поставить наши значения вместо & & в зависимости от ситуации. |
СООБЩЕНИЕ i001 С ‘Хорошим’ ‘Игроком’.
-> Вышеприведенное вернет «Я хороший игрок». ***Примечание: мы можем даже указать индекс для «&» в таблице. Предположим, текст был «Я 2&1&». Затем приведенное выше сообщение выдаст вывод: «Я хороший игрок». |
Типы сообщений SAP
Значение | Тип | объяснение |
A | прекращение | Оно отображается в диалоговом окне, и программа закрывается. |
E | Ошибка | Он отображает сообщение об ошибке в строке состояния, и все поля ввода очищаются. |
I | Информация | Он отображается в диалоговом окне. |
S | Статус | Он отображается в строке состояния следующего экрана. |
W | Предупреждение | Он отображает предупреждающее сообщение в строке состояния, и все поля ввода очищаются. |
X | Выход | Сообщения о выходе отменяют запущенную программу и возвращают дамп. |
Информационное сообщение в SAP — иллюстрация изображения
Сообщение об ошибке в SAP — иллюстрация изображения
Сообщение о состоянии в SAP — иллюстрация изображения
Предисловие — Этот пост является частью ABAP-новичок серии.
Введение
Программист всегда старается кодировать таким образом, чтобы в его коде не было ошибок и чтобы он был полностью проверен. Но есть определенные сценарии, когда его коды могут дать сбой. В таком случае, если кодер уже знает сценарии, он обрабатывает их в форме обработки ошибок. Но в случае ситуаций, когда ошибка может быть сгенерирована из-за неизвестных ситуаций и не обработана, это может привести к серьезным дампам. Для этих сценариев у нас есть обработка исключений в SAP. В этой статье мы рассмотрим все сценарии обработки исключений и ошибок в отчетах ABAP.
Обработка исключений и ошибок в отчетах SAP ABAP
Как обсуждалось выше, кодировщик должен обрабатывать известные проблемы, а также предполагаемые сообщения об ошибках. Эти сообщения отображаются пользователю в выводе с помощью оператора MESSAGE.
Различные способы обнаружения ошибок/исключений
ABAP предоставляет различные способы обнаружения ошибок в программе ABAP.
-
Использование системной переменной
Самый простой способ — использовать их системные переменные.
SY-SUBRC EQ 0. «Этот оператор указывает, что операция завершена успешно. SY-SUBRC NE 0. «Этот оператор указывает, что операция не удалась.
Этот способ работает напрямую, если весь код отчета обрабатывался в рамках одной программы. Это означает, что он не может напрямую поймать ошибку, если вы обработали операторы функционального модуля или класса ABAP. Для этих объектов нам нужно вызвать исключение с их конца, а затем исключение можно обработать в отчете и соответствующим образом обработать.
-
Отлов ошибок на основе исключения
В случае, если мы реализуем функциональный модуль или метод класса, важно вызвать исключение из этих классов, а затем мы можем поймать эти исключения в отчете и показать соответствующую ошибку.
Например:
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.
-
Использование TRY CATCH ENDTRY
Если исключение возникает с помощью метода класса или возникает неожиданное исключение, в этих случаях мы используем функцию TRY CATCH SAP ABAP. Это один из лучших способов полного доказательства для обработки всех типов исключений.
Пример:
ПЫТАТЬСЯ. //Здесь вызовите свой класс или функциональный модуль CATCH CX_SY_ZERODIVIDE INTO O_REF. // Исключение, которое вы там вызвали СООБЩЕНИЕ «Ваше сообщение об ошибке». КОНЕЦ.
Различные способы отображения сообщений
-
Использование оператора ABAP
Синтаксис:
СООБЩЕНИЕ ' ' TYPE 'Введите тип сообщения здесь'.
Типы сообщений
ABAP предоставляет следующие 6 типов сообщений:
Тип сообщения | Смысл | объяснение |
A | прекращение | Это сообщение отображается при завершении программы. |
E | Ошибка | Это сообщение отображается во время Ошибка. |
I | Информация | Это сообщение используется для отображения любой информации. |
S | Успех | Это отображается в состоянии экрана вывода. |
W | Предупреждение | Он ведет себя как сообщение об ошибке. |
X | Выход | Это вызывает короткий дамп с сообщением об ошибке. |
-
Использование предопределенных функциональных модулей
ABAP предоставляет следующие функциональные модули, которые можно использовать для хранения, форматирования и отображения сообщений:
Функциональный модуль | Применение |
MESSAGES_INITIALIZE | Для инициализации сообщений. |
MESSAGE_STORE | Чтобы сохранить сообщения для отображения. |
MESSAGES_SHOW | Отображать все сообщения вместе во всплывающем окне |
FORMAT_MESSAGE | Форматировать сообщения |
HR_DISPLAY_ERROR_LIST | Для отображения всех сообщений об ошибках |
Пример:
- Использование оператора сообщения
СООБЩЕНИЕ 'Это сообщение об ошибке' ТИП 'E'.
- Использование нескольких функций для хранения и отображения сообщений:
" Инициализируется только изначально... * Инициализируйте свои сообщения 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.
- Использование 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.
Когда мы создаем какой-либо многократно используемый компонент, например функциональный модуль или метод в классе, мы сталкиваемся с необходимостью обработки непредвиденных ситуаций (какой-либо входной параметр, оказался не заполненным или доступ к файлу не был получен и т.п.), т.е. тех ситуаций, после которых программа не может выполняться далее стандартным образом, либо требуется дополнительная обработка.
В приведенной статье рассматриваются способы вызова и обработки данных ситуаций, называемых исключениями.
В ABAP есть два основных способа работы с исключениями, классический способ заключается в вызове особых ситуаций описанных в ФМ или методе на отдельной закладке:
Классический способ может использоваться и в классах:
Новый способ основывается на ООП, где в качестве исключений используются классы (обратите внимание, что установлена галочка – классы исключений):
Хочется отметить, что новый способ был введен с версии 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 sy—subrc <> 0. MESSAGE ID sy—msgid TYPE sy—msgty NUMBER sy—msgno WITH sy—msgv1 sy—msgv2 sy—msgv3 sy—msgv4. ENDIF. WRITE gv_summ. |
При запуске программы произойдет вызов исключения, т.к. был использован тип сообщения «Е», программа завершит свое выполнение после показа сообщения:
Замечу, что это вовсе не означает, что при вызове ФМ или метода и обработке исключения необходимо завершать работу программы, вы можете свободно продолжить её выполнение и далее, добавив например, сообщение об ошибке в лог программы, а не на вывод как в примере.
Ключевое слово 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 подставляем всегда, при вызове ФМ (метода или процедуры), когда мы точно не уверены в неизменности компонента.
При вызове исключения в процедурах (perform…) из ФМ, система пытается найти и вызвать исключение в первом ФМ из стека вызовов, если исключение не найдено, вызывается так же, как и неопределенное исключение в ФМ.
Как уже было упомянуто выше, есть возможность получать текст непосредственно из описания особой ситуации:
ФМ будет выглядеть следующим образом:
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 funct—funcname, lv_exc TYPE funct—parameter, lv_txt TYPE swotlq—shorttext. lv_fun = ‘ZTEST_EXC’. lv_exc = ‘NO_NUM_1’. CALL FUNCTION ‘SWO_TEXT_FUNCTION_EXCEPTION’ EXPORTING language = sy—langu 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. |
Результат:
Иногда особые ситуации используются не как исключения, а как параметры показывающие обработку ФМ и его результат, возвращаемый в поле 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 sy—subrc. WHEN 1. WRITE ‘More 10’. WHEN 2. WRITE ‘Less 10’. WHEN 3. WRITE ‘Equal |
Результат:
Сообщения, вызываемые в ФМ или методах, оператором 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 sy—subrc = 1. WRITE ‘ФМ вызвал MESSAGE с типом E,A’. ENDIF. |
Результат:
Обработка исключения классическим способом может быть выполнена динамически, с помощью ключевого слова 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_line—name = ‘FILENAME’. ptab_line—kind = abap_func_exporting. GET REFERENCE OF filename INTO ptab_line—value. INSERT ptab_line INTO TABLE ptab. ptab_line—name = ‘FILETYPE’. ptab_line—kind = abap_func_exporting. GET REFERENCE OF filetype INTO ptab_line—value. INSERT ptab_line INTO TABLE ptab. ptab_line—name = ‘DATA_TAB’. ptab_line—kind = abap_func_tables. GET REFERENCE OF text_tab INTO ptab_line—value. INSERT ptab_line INTO TABLE ptab. ptab_line—name = ‘FILELENGTH’. ptab_line—kind = abap_func_importing. GET REFERENCE OF fleng INTO ptab_line—value. INSERT ptab_line INTO TABLE ptab. ... etab_line—name = ‘OTHERS’. etab_line—value = 10. INSERT etab_line INTO TABLE etab. CALL FUNCTION func PARAMETER—TABLE ptab EXCEPTION—TABLE etab. CASE sy—subrc. WHEN 1. ... ... ENDCASE. |
Обработка исключений, основанная на классах
Как понятно из названия, под исключениями в данном случае понимаются объекты специальных классов исключений. Вызов такого исключения может быть выполнен либо в программе с помощью оператора RAISE EXCEPTION, либо системой (например, при делении на ноль будет вызвано предопределённое исключение CX_SY_ZERODIVIDE, список таких исключений), либо через дополнение THROW в условных выражениях (с версии ABAP 7.4).
Во всех случаях инициируется создание объекта указанного класса (если указано дополнение INTO в CATCH), в атрибутах которого содержится информация о возникшей исключительной ситуации, доступ к ним, как правило, осуществляется через методы этого класса.
Классы особых ситуаций могут быть определены как локально, так и глобально через построитель классов – транзакция SE24, диалог создания:
В данном случае галочка «с классом сообщений» означает использование в качестве текста сообщения из класса сообщений транзакция SE91 (будет рассмотрено ниже). По умолчанию текст сообщения создается в текстах класса:
Категории исключений
Все классы особых ситуаций являются производными одного из классов: CX_NO_CHECK, CX_DYNAMIC_CHECK или CX_STATIC_CHECK, которые сами являются производными общего суперкласса CX_ROOT.
- CX_STATIC_CHECK – как правило, исключения которые вызываются в процедуре (ФМ или методе), должны быть либо обработаны в ней, либо процедура должна иметь соответствующий интерфейс, чтобы вызывающий её код мог обработать эту ситуацию. Если исключение определено как потомок этого класса, оно должно быть явно указано в интерфейсе метода (ФМ или формы) в котором происходит его вызов. Данная категория используется тогда, когда в коде явно ожидается передача обработки особой ситуации на уровень выше того места где оно было вызвано. Если при статической проверке, система не увидит обработки в блоке TRY..CATCH..ENDTRY подобного исключения система выдаст предупреждение:
- CX_DYNAMIC_CHECK – при проверке кода, компилятор не будет делать предупреждений об отсутствии обработки исключений их этой категории, в случае вызова исключения его обработка будет проверена динамически и если обработчик не будет найден программа упадет в дамп. Обычно данная категория используется тогда, когда исключение может быть обработано внутри самого метода, без передачи обработки выше по стеку. Примером такой категории может являться исключение вызываемое при делении на ноль, передавать его выше по стеку и указывать в интерфейсе метода вовсе не обязательно, т.к. мы можем его обработать внутри самого метода. Однако, если мы хотим передать обработку данного исключения, необходимо указать его в интерфейсе метода.
- CX_NO_CHECK – аналогичны предыдущему типу, но данную категорию нельзя объявлять в интерфейсах, при этом классы исключений наследуемые от этого класса, неявно все же передаются в интерфейс и выше по стеку вызовов. Данную категорию следует использовать для исключительных ситуаций, которые могут произойти в любое время и не могут быть обработаны непосредственно в коде метода. Кроме того, можно использовать в случаях когда одна и та же исключительная ситуация может возникнуть во множествах методов, а объявлять её в интерфейсах каждого из методов не имеет смысла, т.к. это усложнит код. В итоге подобные исключения могут пройти всю цепочку вызовов методов (т.к. неявно передаются в интерфейс) и быть обработаны на уровне программы.
На исключения накладываются следующие ограничения:
- Исключение не может быть объявлено в интерфейсе статического конструктора:
- Исключение не может быть объявлено в интерфейсе обработчика событий. При этом если в коде обработчика произошел вызов исключения, и он не был обработан, система вызовет исключение — 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). Константы идентификаторы, представленные в шестнадцатеричном формате, уникальны на уровне системы:
Доступ к хранилищу текстов можно получить через транзакцию SOTR_EDIT.
В текстах можно определить параметры, их необходимо обозначить в амперсандах. В качестве примера, можно рассмотреть текст из класса исключения — CX_SY_FILE_IO:
В параметры будут переданы (при вызове метода GET_TEXT) соответствующие им атрибуты класса:
Заполняются эти атрибуты в конструкторе при вызове исключения:
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.
Блок 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):
Просмотр ошибки в транзакции 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 хранит в себе эти сообщения):
При редактировании текста, необходимо будет привязать его к классу и номеру сообщения, при этом заполнить параметры, если это необходимо:
Начиная с NW 2004, оператор MESSAGE позволяет напрямую обработку исключений, внедряющих интерфейс IF_T100_MESSAGE:
TRY. ... CATCH cx_some_exception INTO lr_ex. MESSAGE lr_ex TYPE ‘E’. ENDTRY. |
Локальный класс исключения в приватном методе глобального класса
Бывают ситуации, когда для какого-либо приватного метода необходимо реализовать исключение, которое может быть вызвано исключительно данным методом (классом). Реализовать подобное можно, если создать локальный класс исключений:
- Перейти в локальные определения/внедрения:
- Создать класс исключения:
- Указать в методе имя локального класса исключения (обязательно в режиме редактирования исходного кода):
Результат:
Если попробовать сделать тоже самое в режиме редактирования на основе формуляров, выскочит предупреждение о том, что такого класса не существует:
Более подробно об исключениях можно почитать в официальной документации:
http://help.sap.com/abapdocu_740/en/abenabap_exceptions.htm
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 OBJECT: h1.
CALL METHOD h1->increment.
С ОПЕРАТОРОМ RETURN
REPORT zprogram1denisov.
CLASS sqr DEFINITION.
PUBLIC SECTION.
CLASS-METHODS: sqr IMPORTING VALUE(num) TYPE f
RETURNING VALUE(res) TYPE 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( 2 ).
Наследование
Наследование реализуется с помощью дополнения 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-METHODS: increment_counter.
CLASS-EVENTS critical_value
EXPORTING VALUE(excess) TYPE i.
PRIVATE SECTION.
CLASS-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.
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.
An overview of error message types, error and pop-up messages, and how to show messages to the end user.
Published Jun 16, 2021
Message Types In ABAP
In total, ABAP has 6 types of messages.
Type | Description | |
---|---|---|
A | Abend (abnormal end of task) | Displays a message in a dialog pop-up window. The entire transaction is canceled after confirming the message. |
E | Error | Displays an error message in the status line. After confirming the message, the current event block is aborted. |
I | Information | Displays a message in a dialog pop-up window. After confirming the message, the report processing is resumed. |
S | Success / Status | Displays a success message in the status line of the current report. |
W | Warning | Displays a warning message in the status line. After confirming the message, the report processing is resumed. |
X | Exit | Triggers a runtime error and creates a short dump. |
DISPLAY LIKE Addition
As you can see from the previous table the message type can also influence the report execution after the message was confirmed.
In case you want to take care of the error handling yourself or simply change the appearance of a message you can use the addition DISPLAY LIKE
:
MESSAGE 'Message text to display' TYPE 'S' DISPLAY LIKE 'E'.
This example prints the message Message text to display
in the status line with the red error icon. Since the type itself is S
report execution continues normally.
Remember: The addition DISPLAY LIKE
only changes the appearance, not the behavior of the message type.
Displaying Messages
Following some examples of how to output a message in ABAP.
MESSAGE 'Message text to display' TYPE 'I' DISPLAY LIKE 'E'.
MESSAGE 'Text.' TYPE 'I'.
MESSAGE 'Message text to display' TYPE 'S' DISPLAY LIKE 'E'.
MESSAGE 'Message text to display' TYPE 'S' DISPLAY LIKE 'W'.
MESSAGE 'Message text to display' TYPE 'S'.
MESSAGE i004(zmessageclass) TYPE 'I' WITH v1.
MESSAGE ID 'zmessageclass' TYPE 'I' NUMBER '004'.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 DISPLAY LIKE 'E'.
Saving Messages In A Variable
The below examples show how to create and store a message in a variable. This can be useful when working with system variables or a message class.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO DATA(message_str).
DATA(msg) = |{ sy-msgv1 } { sy-msgv2 } { sy-msgv3 } { sy-msgv4 }|.
WRITE: / msg.
DATA(msg) = ``.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO msg.
WRITE: / msg.
Просмотр нерешенных тем
Сообщения без ответов | Активные темы
Правила форума
ВНИМАНИЕ! Прежде чем задавать вопрос, ознакомьтесь со ссылками ниже:
Вопросы по отличиям версий SAP, Add-On, EHP — сюда
Вопросы по SAP Front End (SAPlogon, SAPgui, guiXT и т.д.) — сюда
Вопросы по LSMW — сюда
Вопросы по архивации в SAP — сюда
Вопросы по SAP GRC — сюда
Вопросы по SAP Business Workplace (почте SAP) и SAP Office — сюда
Вопросы по miniSAP (SAP mini basis) — сюда
Вопросы по SAP HANA — сюда
Вопросы по лицензированию продуктов SAP — сюда
Автор | Сообщение | ||
---|---|---|---|
levbel |
Заголовок сообщения: Системные сообщения об ошибках
|
||
|
Всем привет, скорее всего дурной вопрос , но всё же. где спрятаны все системные сообщения, например, Meldungsnr. F5223 Bitte Belegnummer aus Nummernkreis 18 zum Jahr 2004 eingeben.
Просто приходит пользователь, и очень невтятно объясняет и показывает только системное сообщение.
|
||
Вернуться к началу |
|
||
![]() |
№1 |
Заголовок сообщения:
|
||
|
SE91
|
||
Вернуться к началу |
|
||
![]() |
Кто сейчас на конференции |
Сейчас этот форум просматривают: нет зарегистрированных пользователей |
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения |
Обработка исключений
Обработка исключений — это то, что происходит, когда система выдает ошибку.
Во время выполнения программы программа может столкнуться с ошибками. Иногда ошибки вносятся программистами случайно, но большинство ошибок связано с неправильным обращением с приложением. Ошибочные ситуации можно предвидеть во время разработки приложения, но просто невозможно избежать всех типов ошибок.
Обзор исключений
Отображение сообщения в процедуре на самом деле не имеет смысла, поскольку сообщения предназначены для отображения пользователю. В случае с процедурами рекомендуемым способом обработки ситуации с ошибкой является возбуждение исключения и предоставление вызывающей программе возможности решить, что делать с исключением.
Например, предположим, что мы разработали функциональный модуль, который принимает номер материала в качестве параметра импорта и экспортирует различные сведения о материале. Если номер материала, импортированный в функциональный модуль, недействителен, то вместо отображения сообщения о том, что номер материала недействителен, мы можем вызвать исключение в функциональном модуле, которое вызывающая программа может обработать в соответствии со своими функциональными требованиями. То есть вызывающая программа может либо показать сообщение об ошибке, либо выполнить другие действия. Кроме того, поскольку процедуры предназначены для повторного использования, вызывая исключения в процедуре, разные программы могут обрабатывать их по-разному в соответствии со своими конкретными требованиями.
Процедурная обработка исключений
До появления исключений на основе классов только функциональные модули и методы могли вызывать самоопределяемые обрабатываемые исключения, а логика обработки исключений смешивалась с реальной логикой программы.
Поддержка исключений с помощью функциональных модулей
Исключения статически поддерживаются в функциональном модуле с пояснительным текстом, объясняющим ситуацию исключения. Когда возникает это исключение, системное поле SY-SUBRC устанавливается с номером исключения, который вызывающая программа может проверить, чтобы реализовать пользовательскую логику обработки ошибок.
Функциональный модуль Z_TEST_EXCEPTION_EXAMPLE поддерживает два исключения: NOT_FOUND и NO_AIRLINE_DATA. При вызове этого функционального модуля в функциональном модуле возникает соответствующее исключение, если возникает ситуация ошибки. Вызывающая программа проверяет значение SY-SUBRC, чтобы идентифицировать исключение и поддерживать соответствующую логику обработки ошибок в программе.
DATA lt_spfli TYPE spfli_tab. CALL FUNCTION 'Z_TEST_EXCEPTION_EXAMPLE' EXPORTING iv_id = 'LH' IMPORTING et_itab = lt_spfli EXCEPTIONS NOT_FOUND = 1 NO_AIRLINE_DATA = 2 OTHERS = 3. CASE sy-subrc. WHEN 1. * Обработка исключения * NOT_FOUND WHEN 2. * Обработка исключения * NO_AIRLINE_DATA WHEN OTHERS. * Обработка других исключений ENDCASE.
Эти самоопределяемые исключения поддерживаются вручную в функциональных модулях и методах и вызываются с помощью оператора RAISE внутри функционального модуля или метода.
Когда возникает первое исключение, функциональный модуль закрывается, и управление передается обратно вызывающей программе без выполнения дополнительного кода в функциональном модуле. Если вызывающая программа не перехватывает исключение, генерируется ошибка времени выполнения (короткий дамп). По этой причине всегда рекомендуется использовать ключевое слово EXCEPTIONS в вызове функционального модуля (CALL FUNCTION) для перехвата исключений, даже если вы не планируете реализовывать какую-либо пользовательскую логику для исключения.
Поддержка исключений с помощью методов
Подобно функциональным модулям, исключения можно поддерживать в методах с помощью Class Builder, удерживая курсор на методе и выбирая кнопку «Исключение», как показано ниже.
В столбце «Исключение» на вкладке «Метод» дайте имя исключению и сохраните описание, объясняющее исключение, чтобы разработчики, вызывающие метод, могли понять, почему возникает это исключение.
Как показано, в методе можно вызвать исключение с помощью оператора RAISE
.
Обратите внимание, что исключения специфичны для процедуры в том смысле, что если исключение поддерживается для функционального модуля, оно может быть вызвано только внутри этого функционального модуля и не может быть вызвано другими функциональными модулями функциональной группы. Точно так же исключение, поддерживаемое для метода, может быть вызвано только внутри этого метода и не может быть вызвано другими методами класса.
Исключений для локальных классов
Для локальных классов исключения можно определить с помощью оператора EXCEPTIONS в части определения класса, как показано ниже. Исключения, определенные в части определения класса, могут быть вызваны методами, реализованными в части реализации того же класса.
CLASS lcl_test_class DEFINITION PUBLIC. PUBLIC SECTION. CLASS-METHODS read_spfli_into_table IMPORTING VALUE(iv_id) TYPE spfli-carrid DEFAULT 'LH ' EXPORTING VALUE(et_itab) TYPE spfli_tab EXCEPTIONS not_found "Запись не найдена no_airline_data . "Нет данных авиакомпании ENDCLASS.
Мы определили исключение NOT_FOUND в части определения класса LCL_TEST_CLASS. Исключения определяются с помощью ключевого слова EXCEPTIONS. Рекомендуется поддерживать комментарий с кратким описанием исключения.
Обработка исключений на основе классов
Исключения на основе классов (объектно-ориентированные) помогают отделить логику обработки исключений от основной логики программирования, обрабатывая исключения в отдельном блоке. В предыдущем разделе, посвященном процедурным методам обработки исключений, вы видели, что помимо проверки системного поля SY-SUBRC для идентификации исключения, информации об исключении не так много.
Кроме того, поскольку самоопределяемые исключения поддерживаются только в функциональных модулях и методах, в обычных программах нет правильного способа обработки ошибок. Например, если в подпрограмме возникает ситуация ошибки, в которой самоопределяемые исключения не поддерживаются, как мы можем с этим справиться?
Один из способов — передать структуру ошибки или какую-либо переменную в интерфейс параметров и проверить ее после выполнения подпрограммы, как показано ниже.
DATA: lv_carrid TYPE scarr-carrid, lt_spfli TYPE spfli_tab, lv_retcode. PERFORM read_spfli_into_table USING lv_carrid CHANGING lt_spfli lv_retcode. IF lv_retcode IS INITIAL. *Логика программы ELSE. *Логика обработки ошибок ENDIF. FORM read_spfli_into_table USING iv_id CHANGING ct_itab TYPE spfli_tab cv_retcode. SELECT SINGLE carrid INTO @DATA(lv_carrid) FROM scarr WHERE carrid = @iv_id. IF sy-subrc NE 0. cv_retcode = 1. ENDIF. SELECT * FROM spfli WHERE carrid = @iv_id INTO TABLE @ct_itab. IF sy-subrc NE 0. cv_retcode = 2. ENDIF. ENDFORM.
Как вы можете видеть, код использует параметр LV_RETCODE, чтобы зафиксировать ситуацию с ошибкой и соответствующим образом построить логику программы для обработки исключения. Однако это не самый элегантный способ обработки исключений, и интерфейс может вскоре стать загроможденным, если необходимо обработать множество исключительных ситуаций. Это также создает проблемы при пересылке исключения, если исключение необходимо обработать в другом блоке обработки. Например, большинство BAPI реализуют структуру ошибок в интерфейсе для захвата ошибки. В этой структуре ошибки фиксируется большая часть информации об ошибке, например тип ошибки, идентификатор ошибки, сообщение и т. д.
Теперь мы хотим передать эти сведения об ошибке другому функциональному модулю, вызываемому в BAPI, в котором может быть обработано исключение. Для этого нам нужно убедиться, что BAPI и функциональный модуль, вызываемый в BAPI, имеют схожие структуры ошибок; в противном случае нам нужно вручную преобразовать данные и присвоить их новой структуре ошибок функционального модуля.
Вопреки тому, что предполагают многие разработчики, исключения на основе классов не ограничиваются объектами ABAP. Их можно использовать в любом блоке обработки. Исключения на основе классов обрабатываются с помощью специального блока, называемого блоком TRY. Используя операторы CATCH и CLEANUP, мы можем обрабатывать исключения в блоке TRY. Оператор CATCH может перехватывать несколько исключений внутри блока, а оператор CLEANUP позволяет выполнять задачи очистки при выходе из исключения. Например, если вы открываете файл для вывода и сталкиваетесь с исключением при передаче одной из записей, то блок очистки позволяет закрыть файл.
Raising Exceptions
Исключения возникают в нескольких ситуациях — либо программно с помощью оператора RAISE EXCEPTION, либо автоматически средой выполнения ABAP. Например, если мы выполним код ниже, это приведет к ошибке времени выполнения.
DATA : lv_unit_value TYPE i, lv_total_value TYPE i VALUE 20, lv_quantity TYPE i. lv_unit_value = lv_total_value / lv_quantity.
Показан класс исключений, который выдается системой при делении операнда на ноль. Мы можем избежать короткого дампа, перехватив исключение в нашей программе и выйдя из ситуации исключения.
Ниже показан синтаксис реализации блока TRY для обработки исключений.
DATA lx_ex TYPE REF TO cx_sy_zerodivide.
DATA : lv_unit_value TYPE i,
lv_total_value TYPE i VALUE 20,
lv_quantity TYPE i.
TRY. "Начало блока TRY
lv_unit_value = lv_total_value / lv_quantity.
*Другая логика программирования
CATCH cx_sy_zerodivide INTO lx_ex.
WRITE :/'Короткий текст ошибки:' , lx_ex->get_text( ).
WRITE :/'Длинный текст ошибки:' , lx_ex->get_longtext( ).
CLEANUP.
* Любая логика очистки
ENDTRY. "Конец TRY блока
Код приводит к выводу, показанному ниже. Здесь система не генерировала короткий дамп, потому что мы поймали исключение в программе и обработали исключительную ситуацию программно. Хорошая практика программирования состоит в том, чтобы избегать таких исключительных ситуаций, проверяя знаменатель перед его использованием при делении (например, IF lv_quantity IS NOT INITIAL ).
Перехватываемые и неперехватываемые исключения
Существует два типа исключений, генерируемых системой: перехватываемые и неперехватываемые. Для перехватываемых исключений мы можем использовать структуру управления TRY для перехвата исключения в программе, неперехватываемые исключения приводят к ошибке времени выполнения.
Мы можем найти информацию о различных возможных исключениях, вызванных системой, проверив документацию по любому конкретному ключевому слову, и реализовать подходящую обработку исключений в нашей программе. Все классы системных исключений начинаются с CX_SY_.
Возвращаясь к коду, мы определили перехватываемое исключение CX_SY_ZERODIVIDE, которое вызывается системой, когда она сталкивается со значением, делящимся на ноль. Единственная ситуация, в которой системное исключение не возникает при таких обстоятельствах, — это когда числитель также равен нулю. Здесь CX_SY_ZERODIVIDE — это глобальный класс с определенными компонентами.
Как видно, класс CX_SY_ZERODIVIDE реализует интерфейс IF_MESSAGE с двумя методами: GET_TEXT и GET_LONGTEXT. Псевдонимы для этих методов сохраняются на вкладке Псевдонимы.
Мы определили ссылочный объект LX_ER, ссылающийся на статический тип CX_SY_ZERODIVIDE. В управляющей структуре TRY оператор CATCH cx_sy_zerodivide INTO lx_ex создает экземпляр объекта LX_EX. Мы получили доступ к короткому и полному тексту ошибки, вызвав методы GET_TEXT и GET_LONGTEXT соответственно.
При желании мы также сохранили блок CLEANUP, в котором может храниться подходящий код выхода для корректного выхода из процедуры. Например, блок CLEANUP можно использовать для закрытия любых открытых файлов или отката любых обновлений базы данных.
Если вы внимательно посмотрите на класс CX_SY_ZERODIVIDE, то увидите, что он наследуется от суперкласса CX_SY_ARITHMETIC_ERROR. Класс CX_SY_ARITHMETIC_ERROR, в свою очередь, наследуется от суперкласса CX_DYNAMIC_CHECK, который наследуется от CX_ROOT
Базовым классом для всех классов исключений является CX_ROOT, который реализует интерфейсы IF_MESSAGE и IF_SERIALIZABLE_OBJECT. Интерфейс IF_MESSAGE содержит методы GET_TEXT и GET_LONGTEXT, позволяющие извлечь сообщение об ошибке. Интерфейс IF_SERIALIZABLE_OBJECT используется для сериализации объектов — процесса, в котором объект преобразуется в формат сериализации (например, XML, CSV), который может быть передан для создания клона объекта в той же или другой системе. Интерфейс IF_SERIALIZABLE_OBJECT должен быть реализован, если объект исключения необходимо сериализовать. Класс CX_ROOT также реализует другой метод, GET_SOURCE_position, который возвращает позицию в исходном коде, вызвавшую ошибку.
При перехвате исключений на основе классов информация об исключении захватывается объектом, который является экземпляром класса, наследуемого от одного из трех глобальных абстрактных классов: CX_STATIC_CHECK, CX_DYNAMIC_CHECK или CX_NO_CHECK. Эти три глобальных абстрактных класса, в свою очередь, являются подклассами CX_ROOT. Например, мы можем определить ссылочный объект LX_ER как экземпляр класса CX_ROOT вместо класса CX_SY_ZERODIVIDE и по-прежнему иметь возможность перехватывать исключение, как показано в листинге 9.6. Однако это сделает логику ошибки общей и упустит какие-либо конкретные детали обработки исключений, поддерживаемые в конкретном классе исключений.
Как уже отмечалось, при определении пользовательского класса исключений он должен наследоваться от одного из трех классов:
CX_STATIC_CHECK
Если класс исключения, являющийся подклассом CX_STATIC_CHECK, вызывается в функциональном модуле или методе, он должен быть либо определен в сигнатуре (интерфейс параметра), либо перехвачен в процедуре внутри блока TRY. В противном случае средство проверки синтаксиса выводит предупреждающее сообщение.
CX_DYNAMIC_CHECK
Подобно CX_STATIC_CHECK, если класс исключения, который является подклассом CX_DYNAMIC_CHECK, возникает в функциональном модуле или методе, он должен быть либо определен в сигнатуре (интерфейс параметра), либо перехвачен в процедуре внутри блока TRY. В противном случае компилятор не выдаст статическое предупреждающее сообщение, а выдаст ошибку времени выполнения.
CX_NO_CHECK
Класс исключения, который является подклассом CX_NO_CHECK, не может быть определен в сигнатуре функционального модуля или метода. Он неявно объявлен по умолчанию и всегда передается вызывающей стороне.
Поскольку CX_STATIC_CHECK проверяется компилятором во время разработки, рекомендуется использовать этот класс для определения классов исключений. Большинство системных исключений являются производными от CX_DYNAMIC_CHECK.
Глобальное определение классов исключений
Чаще всего мы определяем классы исключений глобально, чтобы их можно было использовать в нескольких программах. Действия по созданию класса исключения в Class Builder аналогичны действиям по созданию любого обычного класса, за исключением того, что класс исключения должен наследовать CX_STATIC_CHECK, CX_DYNAMIC_CHECK или CX_NO_CHECK или любой класс, наследующий эти классы.
Кроме того, классы исключений должны следовать соглашению об именах CX_ для пространства имен SAP и ZCX_ для пространства имен клиента. Флажок «Класс исключения» также установлен для класса исключения.
Флажок «С классом сообщений» позволит вам использовать класс сообщений для хранения сообщений.
Вы заметите, что Class Builder создаст класс исключений, которая похожа на обычный класса, за исключением незначительных дополнительных опций. Например, вы увидите вкладку «Тексты», которая недоступна при создании обычных классов.
SAP рекомендует не определять новые методы и не переопределять унаследованные методы.
Исключение можно вызвать внутри функционального модуля, используя синтаксис RAISE EXCEPTION TYPE класс_исключений.
Локальное определение классов исключений
Локальные классы исключений могут быть определены для локальной работы с исключениями внутри программы. Синтаксис определения локального класса исключений подобен обычному классу, за исключением того, что он должен наследовать CX_STATIC_CHECK, CX_DYNAMIC_CHECK или CX_NO_CHECK. Соглашение об именах LCX_ используется для локальных классов исключений.
Помимо их видимости, работа с локальными классами исключений аналогична работе с глобальными классами исключений.
Сообщения в классах исключений
Классы исключений позволяют нам изящно выйти из ситуации исключения. Однако иногда исключение вызвано ошибкой, для исправления которой может потребоваться вмешательство человека. В таких ситуациях мы можем перехватить сообщение, когда возникнет исключение, чтобы можно было идентифицировать ошибку. Для этого мы можем передать текстовое сообщение с исключением. Тексты также могут иметь значения динамических полей для дополнения сообщения.
Тексты могут храниться непосредственно в классе исключений, который использует онлайн-репозиторий текстов (OTR), или мы также можем использовать сообщения из класса сообщений (транзакция SE91).
Использование онлайн-репозитория текстов
Следующие шаги помогут вам поддерживать сообщения в классах исключений:
1. На вкладке Атрибуты класса исключений определите атрибут со значением, которое вы хотите передать в сообщении. В этом примере мы поддерживаем MV_CARRID в качестве имени атрибута типа S_CARR_ID, поскольку мы планируем передать краткое название авиакомпании в сообщении об исключении. После определения атрибута нажмите «Активировать».
2. На вкладке «Тексты» сохраните идентификатор исключения и текст. Вы можете передать значение атрибута в сообщении, сохранив имя атрибута между амперсандами (&). Здесь мы сохранили идентификатор исключения как INVALID_CARRID, а текст как Нет данных авиакомпании &MV_CARRID&, заключив атрибут в амперсанды. Вы также можете сохранить длинный текст сообщения, нажав кнопку «Длинный текст». Когда закончите, нажмите Активировать.
3. В этот момент на вкладке «Атрибуты» вы увидите, что определенный идентификатор исключения добавляется как константа типа SOTR_CONC. Поддерживаемый текст сохраняется в OTR и поддерживает интернационализацию (переводы).
4. Конструктор класса автоматически добавляет атрибуты, которые вы добавили в качестве параметров импорта, в свою сигнатуру, которую можно передать при возникновении исключения с помощью ключевого слова EXPORTING. Конструктор гарантирует, что все атрибуты инициализированы правильно. Атрибут textid хранит идентификатор исключения для доступа к соответствующему тексту. Предыдущий атрибут хранит предыдущие исключения в контексте. Ниже показаны сигнатура и код инициализации метода конструктора после добавления атрибута MV_CARRID.
5. Чтобы сгенерировать исключение и передать сообщение с названием авиакомпании, вы можете написать оператор RAISE EXCEPTION, как показано на ниже. Здесь вы вызываете конструктор и передаете TEXTID, обращаясь к константе INVALID_CARRID, определенной в атрибутах класса. Эта константа относится к соответствующему идентификатору исключения. Вы также передаете номер материала атрибуту MV_CARRID, чтобы поле &MV_CARRID& в тексте было заменено значением.
Перехват исключения в программе.
DATA lt_spfli TYPE spfli_tab. TRY. CALL FUNCTION 'Z_TEST_EXCEPTION_EXAMPLE' EXPORTING iv_id = 'LR' IMPORTING et_itab = lt_spfli. CATCH zcx_test_exception INTO DATA(lx_msg). WRITE / lx_msg->get_text( ). ENDTRY.
Использование сообщений из класса сообщений
Чтобы использовать сообщения из класса сообщений, выполните следующие действия:
1. Установите флажок «С классом сообщения». Как только этот флажок установлен, система автоматически добавляет к классу сообщений интерфейсы IF_T100_MESSAGE, IF_T100_DYN_MSG, который используется для доступа к сообщениям, хранящимся в классе сообщений.
2.Чтобы использовать сообщение из класса сообщений, перейдите на вкладку «Тексты», сохраните идентификатор исключения и нажмите кнопку «Текст сообщения».
3. В окне «Назначить атрибуты класса исключений сообщению» укажите имя класса сообщений и идентификатор сообщения (номер сообщения). Если вы хотите передать значение атрибута в сообщение, вы можете выбрать атрибут из раскрывающегося списка рядом с каждым полем атрибута. Вы можете передать до четырех атрибутов.
4. Чтобы сгенерировать исключение и передать сообщение с названием авиакомпании, вы можете написать оператор RAISE EXCEPTION.
Перехват исключения в программе.
DATA: lt_spfli TYPE spfli_tab, lv_id TYPE s_carr_id VALUE 'LR'. DO 2 TIMES. TRY. CALL FUNCTION 'Z_TEST_EXCEPTION_EXAMPLE' EXPORTING iv_id = lv_id IMPORTING et_itab = lt_spfli. CATCH cx_static_check INTO DATA(lx_msg). WRITE / lx_msg->get_text( ). ENDTRY. lv_id = 'AB'. ENDDO.
Использовали вышестоящий класс исключений cx_static_check, для обоих классов исключений.
Результат:
Использование дополнения MESSAGE для создания исключения
В SAP NetWeaver 7.5 появилось новое дополнение MESSAGE, которое можно использовать при возникновении исключений. Используя дополнение MESSAGE, вы можете передать спецификации сообщения, такие как тип сообщения, идентификатор сообщения и номер сообщения, а также заполнители для сообщения.
Если класс сообщения реализует интерфейс IF_T100_DYN_MSG, вы можете передать тип сообщения, используя дополнение TYPE, а заполнители для сообщения можно передать, используя дополнение WITH. Однако, если класс сообщения реализует интерфейс IF_T100_MESSAGE, то вы не можете передать тип сообщения
и заполнители сообщений, использующие дополнение WITH.
RAISE EXCEPTION TYPE zcx_test_exception_message MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
В пример показан кода для создания исключения, когда интерфейс IF_T100_DYN_MSG реализован в классе сообщения. В этом примере мы используем дополнение MESSAGE для передачи спецификаций сообщения. Атрибуты и тип сообщения можно передавать напрямую, не определяя их отдельно в классе исключений, поскольку интерфейс IF_T100_DYN_MSG обеспечивает встроенную поддержку.