Условное агрегирование полей VBAK / VBAP в одну строку в информационном наборе - PullRequest
2 голосов
/ 02 июля 2019

Я сталкиваюсь со следующей проблемой.


Что я хочу сделать

Я хочу создать информационный набор, который бы перегруппировал для данного Заказа на поставку данные из таблицы VBAK с несколькими строками из таблицы VBPA, которые следует отправлять в разные поля.

Tables join

Пример: для следующего PO 111005229 я хотел бы получить в первом поле поле KUNNR, для которого PARVW = 'ER', а во втором поле поле ADRNR, для которого PARVW = 'BP'.

Желаемый вывод:

enter image description here


Что я пробовал

Объединение обеих таблиц в SQ02

Я попытался объявить 2 таблицы VBAK и VBAP во время работы TCode SQ02 и выбрать нужные поля:
enter image description here

Это не работает:

  • так же, как в SE16N, запрос возвращает каждую строку заказа на покупку, когда требуется одна строка с отфильтрованными данными;
  • при использовании CHECK VBPA-PARVW = 'ER'. в части кода Record processing в надежде, что это сократит количество строк до 1 для данного заказа, никакого значения вообще не возвращается.

Объявление только таблицы VBAK в SQ02

Я также попытался объявить только таблицу VBAK в SQ02, создать дополнительное поле PERNR_ER, которое я хочу, и приступить к объединению VBAK с VBPA с openSQL кодом, связанным с этими конкретными полями.

Я создал дополнительные поля PARVW_ER и PERNR_ER со следующим встроенным кодом:

SELECT PARVW
    INTO PARVW_ER
    FROM VBPA
    WHERE VBELN = VBPA~VBELN.
    AND PARVW = 'ER'.
ENDSELECT.

SELECT PERNR
    INTO PERNR_ER
    FROM VBPA
    WHERE VBELN = VBPA~VBELN.
    AND PARVW = 'ER'.
ENDSELECT.

, который дает в качестве вывода

enter image description here

Я тоже пробовал

TYPES: begin of TY_TABLE,
    PARVW LIKE VBPA-PARVW,
    PERNR LIKE VBPA-PERNR,
    END OF TY_TABLE.

DATA: WA_TABLE TYPE TY_TABLE,
      IT_TABLE  TYPE TABLE OF TY_TABLE.

SELECT PARVW PERNR
    APPENDING CORRESPONDING FIELDS OF TABLE IT_TABLE
    FROM VBPA
    WHERE VBELN = VBPA~VBELN.

LOOP AT IT_TABLE INTO WA_TABLE.
  IF WA_TABLE-PARVW = 'ER'.
    PARVW_ER = WA_TABLE-PARVW.
    PERNR_ER = WA_TABLE-PERNR.
  ENDIF.
ENDLOOP.

но он вернул то же самое.


Как мне поступить, чтобы получить ожидаемый результат?

Ответы [ 3 ]

1 голос
/ 04 июля 2019

Этого можно добиться с помощью простого двойного цикла FOR:

TYPES: BEGIN OF ty_res,
         vbeln  TYPE vbeln,
         field1 TYPE vbpa-pernr,
         field2 TYPE vbpa-adrnr,
       END OF ty_res,
       tt_res TYPE STANDARD TABLE OF ty_res WITH EMPTY KEY.

DATA(lt_vbpa) = VALUE tab_vbpa( ).

APPEND VALUE #( vbeln = '111005229' parvw = 'SP' kunnr = '100007760' adrnr = '9000002718' ) TO lt_vbpa.
APPEND VALUE #( vbeln = '111005229' parvw = 'BP' kunnr = '100007760' adrnr = '38110' ) TO lt_vbpa.
APPEND VALUE #( vbeln = '111005229' parvw = 'PY' kunnr = '100007760' adrnr = '38110' ) TO lt_vbpa.
APPEND VALUE #( vbeln = '111005229' parvw = 'SH' kunnr = '100007760' adrnr = '38110' ) TO lt_vbpa.
APPEND VALUE #( vbeln = '111005229' parvw = 'ER' pernr = '8071' ) TO lt_vbpa.

DATA(result) = VALUE tt_res( FOR ls_vbpa_bp IN lt_vbpa WHERE ( parvw = 'BP' )
                             FOR ls_vbpa_er IN lt_vbpa WHERE ( parvw = 'ER' )
( vbeln  = ls_vbpa_bp-vbeln
  field1 = ls_vbpa_er-pernr
  field2 = ls_vbpa_bp-adrnr ) ).

result itab содержит желаемый результат.

Тем не менее, это будет работать только в этом особом случае, когда у вас есть только одна строка с функцией BP и одна с ER функцией партнера, которые прикреплены с соответствующим PERNR/ADRNR значения. В остальных случаях вам понадобится группировка.

1 голос
/ 04 июля 2019

Этот совет из комментария @SandraRossi помог мне:

Я думаю, что вы не знаете о преобразованиях между внешним и внутренним формат. Для PARVW, если вы связаны с английским языком, когда вы видите ER, это означает внутреннее значение ZM (см. таблицу TPAUM).

Я не знал, что даже с кодом транзакции SE16N в полях могут отображаться преобразованные данные, то есть на моем языке ER.

Таким образом, решение состояло в том, чтобы просто фильтровать по ZM:

SELECT PERNR
    INTO PERNR_ER
    FROM VBPA
    WHERE VBPA~VBELN = VBAK-VBELN AND PARVW = 'ZM'.
ENDSELECT.
1 голос
/ 02 июля 2019

Используйте INNER JOIN в той же таблице, а затем отфильтруйте ненужные строки по PARVW.

REPORT YYY.

TABLES: vbpa.

START-OF-SELECTION.
  vbpa = VALUE #( vbeln = '111005229' parvw = 'SP' kunnr = '100007760' adrnr = '9000002718' ).
  INSERT vbpa.
  vbpa = VALUE #( vbeln = '111005229' parvw = 'BP' kunnr = '100007760' adrnr = '38110' ).
  INSERT vbpa.
  vbpa = VALUE #( vbeln = '111005229' parvw = 'PY' kunnr = '100007760' adrnr = '38110' ).
  INSERT vbpa.
  vbpa = VALUE #( vbeln = '111005229' parvw = 'SH' kunnr = '100007760' adrnr = '38110' ).
  INSERT vbpa.
  vbpa = VALUE #( vbeln = '111005229' parvw = 'ER' pernr = '8071' ).
  INSERT vbpa.

  SELECT t1~vbeln, t2~pernr AS field1, t1~adrnr AS field2
    FROM vbpa AS t1
    INNER JOIN vbpa AS t2
    ON t1~vbeln = t2~vbeln
    INTO TABLE @DATA(l_tab_vbpa)
      WHERE t1~parvw = 'BP'
        AND t2~parvw = 'ER'.

  LOOP AT l_tab_vbpa ASSIGNING FIELD-SYMBOL(<str_vbpa>).
    WRITE: / <str_vbpa>-vbeln, <str_vbpa>-field1, <str_vbpa>-field2.
  ENDLOOP.

  ROLLBACK WORK.

Результат

Проверка

111005229 00008071 38110

...