Простая иллюстрация подхода при передаче параметра в виде ссылки:
DATA lt_messages TYPE bapiret2_tab.
DATA(lo_messages) = NEW zcl_message_collection( ir_messages = REF #( lt_messages ) ).
if ...
MESSAGE e011(zca_test)
INTO lo_messages->new_message
WITH '#1V1'
'#1V2'.
lo_messages->add( ).
RETURN.
endif.
if ...
MESSAGE w012(zca_test) INTO lo_messages->new_message.
lo_messages->add( ).
endif.
if ...
MESSAGE i013(zca_test) INTO lo_messages->new_message.
lo_messages->add( ).
endif.
Чего можно таким добиться?
Например: это маленькое ухищрение позволяет однократно указывать обрабатываемую таблицу. Это делает код чуть менее многословным. Альтернатива:
APPEND lo_messages->convert_sy2bapi( ) INTO lt_messages. ...или... lo_messages->add( CHANGING messages = lt_messages).
Насколько это красиво? Чисто и просто… Впрочем, есть тут некоторая неочевидность. Мы запускаем метод в классе без указния локальной переменной в качестве параметра, а эта локальная переменная меняется.
Если собирать ошибки внутри вспомогательного класса, а потом их получать вместе, то становится сложнее прекратить обработку немедленно. Выглядит как-то корявенько:
DATA(lo_messages) = NEW zcl_message_collection( ). IF ... MESSAGE e011(zca_test) INTO lo_messages->new_message. lo_messages->add( ). lt_messages = lo_messages->get( ). RETURN. ENDIF. IF ... MESSAGE w012(zca_test) INTO lo_messages->new_message. lo_messages->add( ). ENDIF. "finally lt_messages = lo_messages->get( ).
Пример реализации:
class ZCL_MESSAGE_COLLECTION definition
public
final
create public .
public section.
data NEW_MESSAGE type BAPI_MSG .
methods CONSTRUCTOR
importing
!IV_PARAMETER type BAPI_PARAM optional
!IR_MESSAGES type ref to BAPIRET2_TAB optional .
methods ADD
importing
!FIELD type BAPI_FLD optional
!ROW type BAPI_LINE optional .
methods GET
returning
value(RT_MESSAGES) type BAPIRET2_TAB .
protected section.
private section.
data MT_MESSAGES type BAPIRET2_TAB .
data MV_PARAMETER type BAPI_PARAM .
data MR_MESSAGES type ref to BAPIRET2_TAB .
ENDCLASS.
CLASS ZCL_MESSAGE_COLLECTION IMPLEMENTATION.
METHOD add.
FIELD-SYMBOLS: <messages> TYPE bapiret2_tab.
IF mr_messages IS BOUND.
ASSIGN mr_messages->* TO <messages>.
ELSE.
ASSIGN mt_messages TO <messages>.
ENDIF.
APPEND INITIAL LINE TO <messages> ASSIGNING FIELD-SYMBOL(<message>).
<message>-type = sy-msgty.
<message>-id = sy-msgid.
<message>-number = sy-msgno.
<message>-message = new_message.
<message>-log_no = space.
<message>-log_msg_no = space.
<message>-message_v1 = sy-msgv1.
<message>-message_v2 = sy-msgv2.
<message>-message_v3 = sy-msgv3.
<message>-message_v4 = sy-msgv4.
<message>-parameter = mv_parameter.
<message>-row = row.
<message>-field = field.
<message>-system = space.
ENDMETHOD.
METHOD constructor.
mv_parameter = iv_parameter.
mr_messages = ir_messages.
ENDMETHOD.
METHOD GET.
rt_messages = mt_messages.
ENDMETHOD.
ENDCLASS.