среда, 20 ноября 2013 г.

Работа с динамическими таблицами

На днях столкнулся с задачей, в которой необходимо было создать внутреннюю таблицу с заранее неизвестным количеством полей. 


В решении этой задачи мне очень  помогла интересная статья. Ниже приведу её полный текст.

Создание динамической таблицы будет основано на классах CL_ABAP_ELEMDESCR - этот класс используется для описания и создания элементарных типов данных (С, N, D, и другие), CL_ABAP_STRUCTDESCR - этот класс используется для описания и создания структур, CL_ABAP_TABLEDESCR - этот класс используется для описания и создания внутренних таблиц, из набора классов RTTS. 
   Допустим, нам необходимо сделать выборку, неизвестно каких строк, неизвестное их количество, неизвестно из какой таблицы и вывести это все на экран. Какие поля, сколько полей и из какой таблицы, будет решать пользователь. Для этого нам потребуется, создать динамическую выборку и создать динамическую таблицу в которую будут выбираться все данные.

report  z_test_lna1.
"Описание параметров СЭ
parameters
  : p_name     type fieldname
  , p_type     type c
  , p_len      type i
  , p_tbnam    type string
  .
"Описание данных
data "Структура таблицы в которой будут храниться
     "введенные пользователем описания полей, динамической табл.
  : begin   of   gs_task
  ,   name  like p_name " имя поля
  ,   type  like p_type " тип поля
  ,   len   like p_len  " длина поля
  , end     of   gs_task
  , gt_task like standard table of gs_task
            with key name
  , gt_fld  type standard table of fieldname " список полей для выборки
  , gr      type ref to data
  .
field-symbols
  : <table> type standard table
  .
at selection-screen.
  gs_task-name = p_name .
  gs_task-type = p_type .
  gs_task-len  = p_len  .
  "Заполняем таблицу данными c СЭ
  append gs_task to gt_task.

start-of-selection.
  perform table_creation. " создание таблицы
  perform table_reading.  " заполнение и вывод на экран
*&---------------------------------------------------------------------*
*&      Form  table_creation
*&---------------------------------------------------------------------*
form table_creation.
  data
    : lo_struct  type ref to cl_abap_structdescr
    , lo_table   type ref to cl_abap_tabledescr
    , ls_comp    type abap_componentdescr
    , lt_comp    type abap_component_tab
    .
  sort gt_task.
  delete adjacent duplicates from gt_task.
  loop at gt_task into gs_task.
    ls_comp-name = gs_task-name. " имя поля
    case gs_task-type.
    " используем методы (get_i, get_d, get_c, get_n) класса cl_abap_elemdescr
    " которые возвращают тип объекта для элементарного типа, так же
    " используем значение gs_task-len внутри метода для указания длины типа данных

      when 'I'. " Числовое поле
        ls_comp-type = cl_abap_elemdescr=>get_i( ).
      when 'D'. " Поле типа ДАТА
        ls_comp-type = cl_abap_elemdescr=>get_d( ).
      when 'C'. " Текстовое поле с переменной длиной
        ls_comp-type = cl_abap_elemdescr=>get_c( gs_task-len ).
      when 'N'. " Текстовое поле(для хранения чисел) с переменной длиной
        ls_comp-type = cl_abap_elemdescr=>get_n( gs_task-len ).
    endcase.
    append ls_comp to lt_comp.
    append gs_task-name to gt_fld.
  endloop.
  lo_struct = cl_abap_structdescr=>create( lt_comp ).  " создаем объект структуру
  lo_table  = cl_abap_tabledescr=>create( lo_struct ). " создаем объект таблицу
  create data gr  type handle lo_table. " создаем обект-данных полученного типа
  assign gr->* to <table>. "создаем таблицу
endform.                    "table_creation
*&---------------------------------------------------------------------*
*&      Form  table_reading
*&---------------------------------------------------------------------*
form table_reading.
  " Выборка
  select (gt_fld)  " поля указанные пользователем на СЭ
    from (p_tbnam) " таблица указанная пользователем на СЭ
         into corresponding fields of table <table>.

  field-symbols
    : <ls_wa> type any
    , <comp> type any
    .
" Вывод выбранных записей
  loop at <table> assigning <ls_wa>.
    new-line.
    do.
      assign component sy-index of structure <ls_wa> to <comp>.
      if sy-subrc ne 0.
        exit.
      endif.
      write <comp>.
    enddo.
  endloop.
endform.                    "table_reading

Комментариев нет:

Отправить комментарий