Автор Тема: CL_ABAP_CONTAINER_UTILITIES / ZOPM_CL_CONTAINER_UTILITIES - Работа с контейнером  (Прочитано 8189 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 809
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
В системе для работы с контейнером. есть простенький класс CL_ABAP_CONTAINER_UTILITIES, обычно, в качестве примера, этот класс используют для заполнения структур расширений для различных BAPI-функций. Как мы знаем, стандартно в системе для большинства BAPI-функций, SAP использует для передачи пользовательских параметров атрибут EXTENSIONIN  или EXTENSION_IN типа BAPIPAREX. При чем это может быть как структура так и таблица. Внутри данная структура/таблица имеет 5 полей, где первое поле это описание, фактически ключ для идентификации набора параметров, а следующие поля это фактически место в которое нужно записать значения своих переменных.
Код: You are not allowed to view links. Register or Login
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 минут.
Код: You are not allowed to view links. Register or Login
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 символов.
Код: You are not allowed to view links. Register or Login
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.
Код: You are not allowed to view links. Register or Login
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 используем вызов:
Код: You are not allowed to view links. Register or Login
  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 символов. Хотя это уже дело вашего творческого подхода.

Sapforum.Biz