Меню

Формирование коллектора сообщений и методика работы с ним

|

Разработчику на ABAP часто приходится работать со списками сообщений (message), осуществляя определённые процедуры. Авторское решение.

Введение

Разработчику на ABAP часто приходится работать со списками сообщений (message), осуществляя определённые процедуры, например:

  • Проверять списки на наличие сообщений об ошибке (e.g. при вызове BAPI ФМ).

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

  • Сохранять список сообщений в лог (как правило, стандартный лог, транзакция SLG1).

Обычно такие задачи каждый программист решает ad hoc, Z кодом. Иногда используются разные Sap - модули, довольно часто используется ГФ SAPLSMSG (ФМ MESSAGE_STORE и другие). Эта ГФ широко задействована в SD. Она позволяет накапливать сообщения и выводить их список в виде pop-up окна. Но я бы не сказал, что ее использование сильно облегчает жизнь.

Авторское Решение

Организация интерфейса

Я предлагаю для работы с сообщениями использовать интерфейс IF_RECA_MESSAGE_LIST. Этот интерфейс (и его имплементация) реализованы в рамках модуля RE-FX (модуль этот сравнительно молод, написан единообразно, по новейшим технологиям, очень удобен в разработке и полон прекрасных решений, применимых в других модулях и в собственных разработках).

Имплементация интерфейса IF_RECA_MESSAGE_LIST основана на ГФ SBAL, обслуживающей стандартный SAP лог. Это позволяет с легкостью сохранять сообщения в БД вызовом метода STORE.

Получить ссылку на объект следует методом CREATE фабрики CF_RECA_MESSAGE_LIST. Если вы не собираетесь сохранять сообщения в БД – параметры метода CREATE для вас не важны (в параметрах там объект и подобъект лога SLG1).

Методика работы

Загрузка сообщения в коллектор

Самый удобный способ положить сообщение в коллектор – метод ADD_SYMSG. Т.е. что-то такое:

Data: lo_msg type ref to IF_RECA_MESSAGE_LIST, dummy.

Lo_msg = CF_RECA_MESSAGE_LIST=>CREATE( ).

Message e123 into dummy.

Lo_msg-> ADD_SYMSG( ).

Но можно добавить сообщение вручную методом ADD.

Если вы работаете с BAPI, – есть очень удобный метод ADD_FROM_BAPI, забирающий сообщения из структуры/таблицы BAPIRET2 (N.B! Вы сразу, по выходным параметрам узнаете есть ли E и W сообщения). Вот его интерфейс (Рис.1):

Рис.1 Интерфейс метода ADD_FROM_BAPI

Если используется объект исключения (type ref to CX_ROOT), – нужен метод ADD_FROM_EXCEPTION.

И сообщения из другой инстанции коллектора можно перелить методом ADD_FROM_INSTANCE.

N.B! Если вы посмотрите интерфейс методов ADD или ADD_SYMSG, вы увидите массу необязательных параметров, помимо данных сообщения (Рис.2):

Рис.2 Интерфейс методов ADD_SYMSG

Эти параметры используются в RE-FX, но могут быть полезны и в Z разработках, e.g. ID_TABNAME и ID_FIELDNAME – для привязки к контексту, или ID_CUSTACT – для выхода в SPRO.

Получение информации из коллекторов

Имеется множество методов для получения информации о сообщениях в коллекторе и извлечения их. Один из самых удобных – метод RAISE_FIRST_MESSAGE. Т.е. вам нужно знать, есть ли сообщение об ошибке и сразу получить оное. Вы вызываете метод (Рис.3.):

Если хотите прочитать статью полностью и оставить свои комментарии присоединяйтесь к sapland

У вас уже есть учетная запись?

Войти

Обсуждения Количество комментариев8

Комментарий от  

Николай Кронский

  |  24 января 2017, 16:45

Алексей, если честно - не уловил, в чем заключается "авторское решение"?
Описанный подход является стандартным в разработках модуля RE-FX.

Комментарий от  

Александр Грибов

  |  30 января 2017, 15:15

Спасибо за статью!
 
Для быстрого отображения BAPI-сообщений можно использовать ФМ C14ALD_BAPIRET2_SHOW, это тоже очень удобно.
 
Не подскажет ли кто-то, как быстро и удобно сообщения, полученные после CALL TRANSACTION '...' MESSAGES INTO <...>?

Комментарий от  

Олег Точенюк

  |  31 января 2017, 00:52

Спасибо за статью!
 
Для быстрого отображения BAPI-сообщений можно использовать ФМ C14ALD_BAPIRET2_SHOW, это тоже очень удобно.
 
Не подскажет ли кто-то, как быстро и удобно сообщения, полученные после CALL TRANSACTION '...' MESSAGES INTO <...>?

Да таких ФМ в SAP хоть пруд пруди, так как каждый абапящий индус похоже считал своим долгом написать вывод структуры BAPIRET2_TAB в диалоговом экране, чисто по быстрому 'FINB_BAPIRET2_DISPLAY' или  'RSCRMBW_DISPLAY_BAPIRET2' или 'CBIH_IAALD_BAPIRET2_SHOW' и короче есть их там еще.
 
Что касается вашего второго вопроса, то:
 
CONVERT_BDCMSGCOLL_TO_BAPIRET2 - Данный модуль позволяет выполнить преобразование таблицы сообщений получаемой после вызова пакетного ввода типа CALL TRANSACTION в таблицу сообщений типа BAPIRET2.
 
DATA:   messtab TYPE STANDARD TABLE OF bdcmsgcoll,
             bapiret2 TYPE STANDARD TABLE OF bapiret2.
 
* Например какой-нить вызов пакетника.
CALL TRANSACTION 'FB05' USING bdcdata
    OPTIONS FROM ct_params
    MESSAGES INTO messtab.
 
* Конвертируем результаты выполнения
CALL FUNCTION 'CONVERT_BDCMSGCOLL_TO_BAPIRET2'
  TABLES
    imt_bdcmsgcoll = messtab[]
    ext_return     = bapiret2.
 
* Вывод сообщений в диалоговом окне
IF NOT gt_return[] IS INITIAL.
  CALL FUNCTION 'FINB_BAPIRET2_DISPLAY'
    EXPORTING
      it_message = bapiret2.
ENDIF.

Комментарий от  

Александр Грибов

  |  31 января 2017, 08:11

Да таких ФМ в SAP хоть пруд пруди, так как каждый абапящий индус похоже считал своим долгом написать вывод структуры BAPIRET2_TAB в диалоговом экране, чисто по быстрому 'FINB_BAPIRET2_DISPLAY' или  'RSCRMBW_DISPLAY_BAPIRET2' или 'CBIH_IAALD_BAPIRET2_SHOW' и короче есть их там еще.
 
Что касается вашего второго вопроса, то:
 
CONVERT_BDCMSGCOLL_TO_BAPIRET2 - Данный модуль позволяет выполнить преобразование таблицы сообщений получаемой после вызова пакетного ввода типа CALL TRANSACTION в таблицу сообщений типа BAPIRET2.
 
DATA:   messtab TYPE STANDARD TABLE OF bdcmsgcoll,
             bapiret2 TYPE STANDARD TABLE OF bapiret2.
 
* Например какой-нить вызов пакетника.
CALL TRANSACTION 'FB05' USING bdcdata
    OPTIONS FROM ct_params
    MESSAGES INTO messtab.
 
* Конвертируем результаты выполнения
CALL FUNCTION 'CONVERT_BDCMSGCOLL_TO_BAPIRET2'
  TABLES
    imt_bdcmsgcoll = messtab[]
    ext_return     = bapiret2.
 
* Вывод сообщений в диалоговом окне
IF NOT gt_return[] IS INITIAL.
  CALL FUNCTION 'FINB_BAPIRET2_DISPLAY'
    EXPORTING
      it_message = bapiret2.
ENDIF.

Спасибо за ответ, но в ERP 6.0 EHP7 нет такого ФМ - 'CONVERT_BDCMSGCOLL_TO_BAPIRET2'.

Комментарий от  

Олег Точенюк

  |  01 февраля 2017, 12:22

Спасибо за ответ, но в ERP 6.0 EHP7 нет такого ФМ - 'CONVERT_BDCMSGCOLL_TO_BAPIRET2'.

Да ладно, не помню я чтобы SAP удалял такие ФМ, да и вот зашел в одну из систем:

Есть такой модуль как вы видите.
 
Хотя если совсем все сложно то вот его код, там его написать то и самому вроде как без проблем.
 
FUNCTION convert_bdcmsgcoll_to_bapiret2.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*"  TABLES
*"      IMT_BDCMSGCOLL STRUCTURE  BDCMSGCOLL OPTIONAL
*"      EXT_RETURN STRUCTURE  BAPIRET2 OPTIONAL
*"----------------------------------------------------------------------
 
  DATA: lv_msgno LIKE sy-msgno,
        lv_msgv1 LIKE sy-msgv1,
        lv_msgv2 LIKE sy-msgv2,
        lv_msgv3 LIKE sy-msgv3,
        lv_msgv4 LIKE sy-msgv4.
  DATA: ls_bdcmsgcoll LIKE bdcmsgcoll.
 
  LOOP AT imt_bdcmsgcoll INTO ls_bdcmsgcoll.
    lv_msgno = ls_bdcmsgcoll-msgnr.
    lv_msgv1 = ls_bdcmsgcoll-msgv1(50).
    lv_msgv2 = ls_bdcmsgcoll-msgv2(50).
    lv_msgv3 = ls_bdcmsgcoll-msgv3(50).
    lv_msgv4 = ls_bdcmsgcoll-msgv4(50).
    PERFORM collect_message TABLES ext_return
                            USING  ls_bdcmsgcoll-msgid
                                   lv_msgno
                                   ls_bdcmsgcoll-msgtyp
                                   lv_msgv1
                                   lv_msgv2
                                   lv_msgv3
                                   lv_msgv4.
  ENDLOOP.
 
ENDFUNCTION.

Комментарий от  

Олег Точенюк

  |  01 февраля 2017, 12:22

Да ладно, не помню я чтобы SAP удалял такие ФМ, да и вот зашел в одну из систем:

Есть такой модуль как вы видите.
 
Хотя если совсем все сложно то вот его код, там его написать то и самому вроде как без проблем.
 
FUNCTION convert_bdcmsgcoll_to_bapiret2.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*"  TABLES
*"      IMT_BDCMSGCOLL STRUCTURE  BDCMSGCOLL OPTIONAL
*"      EXT_RETURN STRUCTURE  BAPIRET2 OPTIONAL
*"----------------------------------------------------------------------
 
  DATA: lv_msgno LIKE sy-msgno,
        lv_msgv1 LIKE sy-msgv1,
        lv_msgv2 LIKE sy-msgv2,
        lv_msgv3 LIKE sy-msgv3,
        lv_msgv4 LIKE sy-msgv4.
  DATA: ls_bdcmsgcoll LIKE bdcmsgcoll.
 
  LOOP AT imt_bdcmsgcoll INTO ls_bdcmsgcoll.
    lv_msgno = ls_bdcmsgcoll-msgnr.
    lv_msgv1 = ls_bdcmsgcoll-msgv1(50).
    lv_msgv2 = ls_bdcmsgcoll-msgv2(50).
    lv_msgv3 = ls_bdcmsgcoll-msgv3(50).
    lv_msgv4 = ls_bdcmsgcoll-msgv4(50).
    PERFORM collect_message TABLES ext_return
                            USING  ls_bdcmsgcoll-msgid
                                   lv_msgno
                                   ls_bdcmsgcoll-msgtyp
                                   lv_msgv1
                                   lv_msgv2
                                   lv_msgv3
                                   lv_msgv4.
  ENDLOOP.
 
ENDFUNCTION.

А да еще подпрограммка:
 
*----------------------------------------------------------------------*
***INCLUDE LMEAGF12 .
*----------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*&      Form  collect_message
*&---------------------------------------------------------------------*
FORM collect_message TABLES cht_return STRUCTURE bapiret2
                     USING  im_msgid   LIKE      sy-msgid
                            im_msgno   LIKE      sy-msgno
                            im_msgty   LIKE      sy-msgty
                            im_msgv1   LIKE      sy-msgv1
                            im_msgv2   LIKE      sy-msgv2
                            im_msgv3   LIKE      sy-msgv3
                            im_msgv4   LIKE      sy-msgv4.
 
  DATA: ls_return LIKE bapiret2.
 
  CALL FUNCTION 'BALW_BAPIRETURN_GET2'
       EXPORTING
            type             = im_msgty
            cl               = im_msgid
            number           = im_msgno
            par1             = im_msgv1
            par2             = im_msgv2
            par3             = im_msgv3
            par4             = im_msgv4
*           LOG_NO           = ' '
*           LOG_MSG_NO       = ' '
*           PARAMETER        = ' '
*           ROW              = 0
*           FIELD            = ' '
       IMPORTING
            return           = ls_return.
 
  APPEND ls_return TO cht_return.
 
ENDFORM.                               " collect_message

Комментарий от  

Александр Грибов

  |  01 февраля 2017, 12:37

Да ладно, не помню я чтобы SAP удалял такие ФМ, да и вот зашел в одну из систем:

Есть такой модуль как вы видите.
 
Хотя если совсем все сложно то вот его код, там его написать то и самому вроде как без проблем.
 
FUNCTION convert_bdcmsgcoll_to_bapiret2.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*"  TABLES
*"      IMT_BDCMSGCOLL STRUCTURE  BDCMSGCOLL OPTIONAL
*"      EXT_RETURN STRUCTURE  BAPIRET2 OPTIONAL
*"----------------------------------------------------------------------
 
  DATA: lv_msgno LIKE sy-msgno,
        lv_msgv1 LIKE sy-msgv1,
        lv_msgv2 LIKE sy-msgv2,
        lv_msgv3 LIKE sy-msgv3,
        lv_msgv4 LIKE sy-msgv4.
  DATA: ls_bdcmsgcoll LIKE bdcmsgcoll.
 
  LOOP AT imt_bdcmsgcoll INTO ls_bdcmsgcoll.
    lv_msgno = ls_bdcmsgcoll-msgnr.
    lv_msgv1 = ls_bdcmsgcoll-msgv1(50).
    lv_msgv2 = ls_bdcmsgcoll-msgv2(50).
    lv_msgv3 = ls_bdcmsgcoll-msgv3(50).
    lv_msgv4 = ls_bdcmsgcoll-msgv4(50).
    PERFORM collect_message TABLES ext_return
                            USING  ls_bdcmsgcoll-msgid
                                   lv_msgno
                                   ls_bdcmsgcoll-msgtyp
                                   lv_msgv1
                                   lv_msgv2
                                   lv_msgv3
                                   lv_msgv4.
  ENDLOOP.
 
ENDFUNCTION.

Самое время написать статью о приведении разных механизмов обработки сообщений к единому, самому удобному :)

Комментарий от  

Михаил Сидорочкин

  |  07 февраля 2017, 21:01

Еще на тему:
wiki.scn.sap.com/wiki/display