ZDOC_2876

Телега впереди лошади

Простая иллюстрация подхода при передаче параметра  в виде ссылки:

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.