цикл в цикл с именем динамического поля

#abap

#абап

Вопрос:

ПРОБЛЕМА: у меня есть 2 таблицы, подобные этой:

ТАБЛИЦА 1: Таблица HR со многими столбцами и строками

ТАБЛИЦА 2: таблица со списком столбцов, которые мне нужно прочитать из таблицы 1

ИЗОБРАЖЕНИЕ МОИХ ТАБЛИЦ

В таблице 1 мне нужно выполнить цикл по всей строке, и мне нужно проверить все поля из таблицы 2, если в поле есть «X», мне нужно распечатать описание поля из таблицы 2.

Я пытаюсь сделать это с помощью вложенного цикла (таблица циклов 1 и таблица 2 циклов каждой итерации цикла и проверить все поля строки), и я не могу использовать переменную в таблице- (мне нужна переменная для цикла в).

МОЙ КОД:

 LOOP AT lt_hrp9229  INTO ls_hrp9229 
  LOOP AT lt_otype_fields INTO ls_otype_fields .
   IF ls_hrp9229-ls_otype_fields-FIELD_NAME = 'X'.
    ev_descript_data = ev_descript_data amp;amp; ','  amp;amp;  ls_otype_fields-Field_description.
   ENDIF.
 ENDLOOP.
ENDLOOP.
  

У меня проблема в этой строке:

 IF ls_hrp9229-ls_otype_fields-FIELD_NAME = 'X'
  

я не могу использовать динамическое имя поля из цикла.

Спасибо.

Ответ №1:

Вы можете использовать следующий код:

 FIELD-SYMBOLS <l_flag> TYPE FLAG.

ASSIGN COMPONENT ls_otype_fields-field_name OF STRUCTURE ls_hrp9229 TO <l_flag>.
IF SY-SUBRC = 0 AND <l_flag> = abap_true.
  ...
ENDIF.
  

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

1. Это кажется правильным, но этот ответ был бы еще лучше, если бы он указывал, что здесь происходит и почему это решает проблему.

2. Подробное описание компонента ASSIGN можно найти в документации ABAP, я просто хотел дать подсказку, чтобы найти соответствующие ключевые слова.

3. Если вы будете использовать этот подход более чем в одной части своего кода, я рекомендую создать вспомогательный метод или форму, чтобы получить значение динамической структуры. Это сделает ваш код более чистым.

Ответ №2:

Используйте что-то вроде этого:

 DATA: lt_hrp9229 TYPE TABLE OF HRP9229.
DATA: ev_descript_data TYPE string.

SELECT *
  FROM dd03l
  INTO TABLE @DATA(lt_otype_fields)
  WHERE tabname = 'HRP9229'.

LOOP AT lt_hrp9229 ASSIGNING FIELD-SYMBOL(<fs_9229>).
  LOOP AT lt_otype_fields ASSIGNING FIELD-SYMBOL(<fs_fields>).
    ASSIGN COMPONENT <fs_fields>-fieldname OF STRUCTURE <fs_9229> TO FIELD-SYMBOL(<field_description>).
    CHECK sy-subrc = 0.
   IF <field_description> = 'OBJID'.
    ev_descript_data = ev_descript_data amp;amp; ','  amp;amp; <fs_fields>-rollname. " pull your FIELD_DESC here instead 
   ENDIF.
 ENDLOOP.
ENDLOOP.
  

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

1. Подход к использованию компонента ASSIGN здесь кажется правильным, но я думаю, что вторая строка после этого должна гласить: IF <field_description> = 'X'. Не уверен, откуда вы взяли 'OBJID' . Ответ можно было бы дополнительно улучшить, объяснив, что на самом деле делает компонент ASSIGN и почему он решает эту проблему.

2. да, это соответствует фактическим бизнес-требованиям, я только что привел пример

Ответ №3:

Я исправил эту проблему с помощью символа поля.

  LOOP AT lt_hrp9229 INTO ls_hrp9229.
      lv_index = sy-tabix.
      LOOP AT lt_s_fields INTO ls_s_fields.
        ASSIGN COMPONENT ls_s_fields-field_name OF STRUCTURE ls_hrp9229
        TO FIELD-SYMBOL(<ls_s_fields_value>).

        IF <ls_s_fields_value> = 'X'.
          ev_descript_data = ev_descript_data amp;amp; ' , '  amp;amp; ls_s_fields-field_desc  .
        ENDIF.
      ENDLOOP.
      ls_et_hrp9229-descript_data = ev_descript_data.
      MODIFY et_hrp9229 INDEX lv_index FROM ls_et_hrp9229 TRANSPORTING descript_data .
      CLEAR ev_descript_data.
    ENDLOOP.