После вызова Service Provider возникает вопрос о возврате сообщений в вызывающую программу.
Псевдокод
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
DATA: lo_sp_in TYPE REF TO /scwm/cl_sp_prd_inb. lo_sp_in = NEW #( iv_mode = /scdl/cl_sp=>sc_mode_classic io_message_handler = lo_adapt_handler io_attribute_handler = lo_adapt_handler ). /scmb/cl_base=>set_process_data( ... ). lo_sp_in->query( ... ). ... lo_sp_in->execute( ... ). ... "get messages |
Казалось бы, все просто, мы же передаем message_handler в конструктор, значит можем забрать сообщения из этого самого класса.
Но сообщения туда не попадают, даже если присутствовали какие-либо ошибки.
Рассмотрим несколько вариантов для получения списка сообщений на примере класса /scwm/cl_sp_prd_inb для работы со входящими поставками.
- Не самый короткий 🙂
На самом деле все сообщения хранятся в message_box классе.
Этот класс напрямую не вытащить из /scwm/cl_sp_prd_inb, нет подходящего акцессора.
У /scwm/cl_sp_prd_inb есть атрибут mo_sp_core (тип /scdl/cl_sp_prd_inb), который инициализируется в конструкторе. У mo_sp_core в атрибутах есть mo_message_box, который нам нужен.
Наследуемся от /scwm/cl_sp_prd_inb и реализуем метод get_messages, в котором через mo_sp_core вытаскиваем сообщения
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 |
CLASS lcl_service_provider DEFINITION INHERITING FROM /scwm/cl_sp_prd_inb. PUBLIC SECTION. METHODS: get_messages RETURNING VALUE(rt_message) TYPE bapirettab. ENDCLASS. CLASS lcl_service_provider IMPLEMENTATION. METHOD get_messages. TRY. DATA(lo_message_box) = mo_sp_core->/scdl/if_sp_badi~get_message_box( ). DATA(lt_messages) = lo_message_box->get_messages( ). LOOP AT lt_messages ASSIGNING FIELD-SYMBOL(<ls_msg>). CHECK <ls_msg>-msgid IS NOT INITIAL. CHECK <ls_msg>-msgno IS NOT INITIAL. CHECK <ls_msg>-msgty IS NOT INITIAL. DATA(lv_message) = VALUE string( ). MESSAGE ID <ls_msg>-msgid TYPE <ls_msg>-msgty NUMBER <ls_msg>-msgno WITH <ls_msg>-msgv1 <ls_msg>-msgv2 <ls_msg>-msgv3 <ls_msg>-msgv4 INTO lv_message. APPEND INITIAL LINE TO rt_message ASSIGNING FIELD-SYMBOL(<ls_ret_msg>). <ls_ret_msg>-id = <ls_msg>-msgid. <ls_ret_msg>-type = <ls_msg>-msgty. <ls_ret_msg>-number = <ls_msg>-msgno. <ls_ret_msg>-message = lv_message. <ls_ret_msg>-message_v1 = <ls_msg>-msgv1. <ls_ret_msg>-message_v2 = <ls_msg>-msgv2. <ls_ret_msg>-message_v3 = <ls_msg>-msgv3. <ls_ret_msg>-message_v4 = <ls_msg>-msgv4. ENDLOOP. CATCH cx_root. ENDTRY. ENDMETHOD. ENDCLASS. |
Пример использования (псевдокод):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
DATA: lo_sp_in TYPE REF TO /scwm/cl_sp_prd_inb. lo_sp_in = NEW #( iv_mode = /scdl/cl_sp=>sc_mode_classic io_message_handler = lo_adapt_handler io_attribute_handler = lo_adapt_handler ). /scmb/cl_base=>set_process_data( ... ). lo_sp_in->query( ... ). ... lo_sp_in->execute( ... ). ... "get messages rt_return = lo_sp_in->get_messages( ). |
- Напрямую использовать SP класс
Можно использовать service provider – /scdl/cl_sp_prd_inb, как указано здесь Service_Provider_Call_Example
Тогда мы самостоятельно передаем message_box в конструктор SP класса,
и наследование нам не понадобится.