В системе для работы с контейнером. есть простенький класс CL_ABAP_CONTAINER_UTILITIES, обычно, в качестве примера, этот класс используют для заполнения структур расширений для различных BAPI-функций. Как мы знаем, стандартно в системе для большинства BAPI-функций, SAP использует для передачи пользовательских параметров атрибут EXTENSIONIN или EXTENSION_IN типа BAPIPAREX. При чем это может быть как структура так и таблица. Внутри данная структура/таблица имеет 5 полей, где первое поле это описание, фактически ключ для идентификации набора параметров, а следующие поля это фактически место в которое нужно записать значения своих переменных.
STRUCTURE TE_STRUC CHAR 30 0 Структурне ім'я розширення таблиці BAPI
VALUEPART1 VALUEPART CHAR 240 0 Розділ даних параметра розширення BAPI
VALUEPART2 VALUEPART CHAR 240 0 Розділ даних параметра розширення BAPI
VALUEPART3 VALUEPART CHAR 240 0 Розділ даних параметра розширення BAPI
VALUEPART4 VALUEPART CHAR 240 0 Розділ даних параметра розширення BAPI
Можно конечно, если передающихся параметров от 1 до 4, то записать их руками в соответствующие поля, но если это структура с десятком другим параметров, то передача значений превращается в написание программы, которая будет шифровать значения полей в поля структуры EXTENSION_IN. Для упрощения процесса SAP создал класс CL_ABAP_CONTAINER_UTILITIES, который позволяет выполнять простое преобразование ваших полей в поля VALUEPART1. Все бы неплохо, но иногда структура передаваемых полей выходит за рамки 240 символов и тогда приходится в ручную/программно как-то быть передаваемые поля на блоки по 240 символов с последовательным заполнением полей от VALUEPART1 под VALUEPART4. Поэтому вместо примера использования чистого CL_ABAP_CONTAINER_UTILITIES, быстро был набросан класс ZOPM_CL_CONTAINER_UTILITIES, который выполняет равномерное преобразование больших структур в структуру EXTENSION_IN и так же выполняет обратное преобразование.
Собственно сам класс, можно перенести себе в систему воспользовавшись созданием класс на базе исходного кода, в системах базиса, кажется старше 7.31, это уже возможно. В крайнем случае его можно перенести руками, работы там на 5 минут.
CLASS zopm_cl_container_utilities DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS fill_container_c
IMPORTING
!iv_name TYPE te_struc OPTIONAL
!iv_value TYPE any
RETURNING
VALUE(ex_container) TYPE bapiparex .
CLASS-METHODS read_container_c
IMPORTING
!is_container TYPE bapiparex
EXPORTING
!ev_value TYPE any .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS ZOPM_CL_CONTAINER_UTILITIES IMPLEMENTATION.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZOPM_CL_CONTAINER_UTILITIES=>FILL_CONTAINER_C
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_NAME TYPE TE_STRUC(optional)
* | [--->] IV_VALUE TYPE ANY
* | [<-()] EX_CONTAINER TYPE BAPIPAREX
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD fill_container_c.
FIELD-SYMBOLS: <fs_str> TYPE any,
<valuepart> TYPE valuepart.
DATA : l_len TYPE i,
l_ofs TYPE i,
l_index(1) TYPE c,
l_len_max TYPE i,
l_value_fld(100) TYPE c.
l_ofs = l_len = 0.
IF iv_name IS SUPPLIED. ex_container-structure = iv_name. ENDIF.
DESCRIBE FIELD iv_value LENGTH l_len_max IN CHARACTER MODE.
DO 4 TIMES.
l_len = 240.
IF l_len > l_len_max. l_len = l_len_max. ENDIF.
ASSIGN iv_value+l_ofs(l_len) TO <fs_str>.
l_index = sy-index.
CONCATENATE 'EX_CONTAINER-VALUEPART' l_index INTO l_value_fld.
ASSIGN (l_value_fld) TO <valuepart>.
CALL METHOD cl_abap_container_utilities=>fill_container_c
EXPORTING
im_value = <fs_str>
IMPORTING
ex_container = <valuepart>
EXCEPTIONS
illegal_parameter_type = 0
OTHERS = 0.
l_ofs = l_ofs + l_len.
l_len_max = l_len_max - l_len.
IF l_len_max <= 0. EXIT. ENDIF.
ENDDO.
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZOPM_CL_CONTAINER_UTILITIES=>READ_CONTAINER_C
* +-------------------------------------------------------------------------------------------------+
* | [--->] IS_CONTAINER TYPE BAPIPAREX
* | [<---] EV_VALUE TYPE ANY
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD read_container_c.
FIELD-SYMBOLS: <fs_str> TYPE any,
<valuepart> TYPE valuepart.
DATA : l_len TYPE i,
l_ofs TYPE i,
l_index(1) TYPE c,
l_len_max TYPE i,
l_value_fld(100) TYPE c.
l_ofs = l_len = 0.
DESCRIBE FIELD ev_value LENGTH l_len_max IN CHARACTER MODE.
DO 4 TIMES.
l_len = 240.
IF l_len > l_len_max. l_len = l_len_max. ENDIF.
ASSIGN ev_value+l_ofs(l_len) TO <fs_str>.
l_index = sy-index.
CONCATENATE 'IS_CONTAINER-VALUEPART' l_index INTO l_value_fld.
ASSIGN (l_value_fld) TO <valuepart>.
CALL METHOD cl_abap_container_utilities=>read_container_c
EXPORTING
im_container = <valuepart>
IMPORTING
ex_value = <fs_str>
EXCEPTIONS
illegal_parameter_type = 1
OTHERS = 2.
l_ofs = l_ofs + l_len.
l_len_max = l_len_max - l_len.
IF l_len_max <= 0. EXIT. ENDIF.
ENDDO.
ENDMETHOD.
ENDCLASS.
Далее для примере берем структуру пользовательского расширения, которая имеет свои поля, которые должны быть как-то обработаны при создании документа резервирования, функция: BAPI_RESERVATION_CREATE1 - BAPI to Create Individual Reservations. Набор пользовательских полей следующий. Как видим их значительно больше чем 4 и они длиннее чем 240 символов.
DATE_VALID ZOPM_RESB_DATE_VALID_T DATS 8
EXTERNAL_NUM ZOPM_RESB_EXTERNAL_NUMBER_T CHAR 40
AIM_ID ZOPM_RESB_AIM_OPERATION_ID_T CHAR 10
AIM_TEXT ZOPM_RESB_AIM_OPERATION_T CHAR 132
GOVERNMENT_ID ZOPM_RESB_GOVERNMENT_ID_T CHAR 10
GOVERNMENT_TEXT ZOPM_RESB_GOVERNMENT_TEXT_T CHAR 40
TRAN_ID ZOPM_RESB_TRANSPORT_ID_T CHAR 10
TRAN_TEXT ZOPM_RESB_TRANSPORT_TEXT_T CHAR 20
TRAN_NUMBER ZOPM_RESB_TRANSPORT_NUMBER_T CHAR 132
TRAN_NAME_ID ZOPM_RESB_TRANSPORT_NAME_ID_T CHAR 10
TRAN_NAME_TEXT ZOPM_RESB_TRANSPORT_NAME_TXT_T CHAR 132
TRAN_NUMBER_DOC ZOPM_RESB_TRANSPORT_NUM_DOC_T CHAR 132
PERNR_ONE PERSNO NUMC 8
PERNR_TWO PERSNO NUMC 8
PERNR_THREE PERSNO NUMC 8
Поэтому для заполнения таблицы EXTENSIONIN LIKE BAPIPAREX, используем следующий вызов. В ходе которого значения переменных из нашей структуры будут разложены по структуре EXTENSIONIN.
DATA: ls_extensionin type bapiparex,
ls_resb_ext TYPE <наша структура с полями выше>.
ls_extensionin = zopm_cl_container_utilities=>fill_container_c( iv_name = 'BAPI_ZOPM_MEREQRKPF' iv_value = ls_resb_ext ).
append ls_extensionin to pt_extensionin.
где BAPI_ZOPM_MEREQRKPF - Мой идентификатор, чтобы можно было опознать вызов внутри BAPI.
Внутри BAPI для разворачивая значений в поля нашей структуры ls_resb_ext используем вызов:
DATA: ls_resb_ext TYPE <наша структура с полями выше>,
DATA: ls_extensionin TYPE bapiparex.
clear: ls_resb_ext.
call method zopm_cl_container_utilities=>read_container_c
exporting
is_container = ls_extensionin
importing
ev_value = ls_resb_ext.
На выходе получаем внутри BAPI, поля нашей структуры ls_resb_ext, заполненные так как это было сделано перед вызовом BAPI.
PS: Можно конечно еще там накрутить раскладку полей в таблицу типа EXTENSIONIN, ну это в том случае если на входе идет таблица пользовательских полей а объем передаваемых данных больше чем 4 *240 символов. Хотя это уже дело вашего творческого подхода.