[ABAP] Leistungsverzeichnis mit Gliederung zu einem Einkaufsbeleg lesen

PARAMETERS: p_ebeln TYPE ekpo-ebeln.

START-OF-SELECTION.

  SELECT SINGLE FROM ekpo
    FIELDS
      menge,
      meins,
      bprme,
      netpr,
      peinh,
      txz01,
      packno
    WHERE ebeln EQ @p_ebeln
      AND ebelp EQ '00001'
    INTO @DATA(lv_ekpo).

  IF sy-subrc EQ 0.
    DATA: it_gliederung TYPE STANDARD TABLE OF ml_esll WITH DEFAULT KEY.

* Holen Gliederungsdaten für Listausgabe
    CALL FUNCTION 'MS_SUBDIVISION_FOR_PRINT'
      EXPORTING
        packno           = lv_ekpo-packno
      TABLES
        gliederung       = it_gliederung
      EXCEPTIONS
        packno_not_exist = 1
        OTHERS           = 2.

    IF sy-subrc = 0.

      DATA: it_leistung TYPE STANDARD TABLE OF ml_esll WITH DEFAULT KEY.

      LOOP AT it_gliederung ASSIGNING FIELD-SYMBOL(<g>).

        DATA(pos) = ( <g>-rang * 2 ).

        IF <g>-rang = 0.
          WRITE: AT /pos '#', lv_ekpo-txz01, lv_ekpo-menge, lv_ekpo-meins, lv_ekpo-netpr.
        ELSE.
          WRITE: AT /pos '#', <g>-ktext1.
        ENDIF.

        CLEAR: it_leistung.

* Holen Leistungen für Listanzeige
        CALL FUNCTION 'MS_SERVICES_FOR_PRINT'
          EXPORTING
            packno            = <g>-sub_packno
          TABLES
            leistung          = it_leistung
          EXCEPTIONS
            no_services_found = 1
            OTHERS            = 2.

        IF sy-subrc = 0.
          LOOP AT it_leistung ASSIGNING FIELD-SYMBOL(<l>).
            WRITE: AT /10 <l>-extrow, '|', <l>-srvpos, '|', <l>-menge, <l>-meins, <l>-brtwr, <l>-waers, <l>-ktext1, '|', <l>-ebeln, <l>-ebelp.
          ENDLOOP.
        ENDIF.

        WRITE: /.

      ENDLOOP.

    ENDIF.
  ENDIF.

[ABAP] SPRO-Customizing Strukturen anzeigen

* TTREE-IDs stehen in Tabelle TTREE (Definitionstabelle für Strukturen) + TTREET (Bezeichung einer Struktur)
* Hier als Beispiel vorbelegt mit 5BB3C2F5329FD21195360060B03C6B76 für Knoten 'Logistik Allgemein'
DATA: lv_img_id type ttree-id VALUE '5BB3C2F5329FD21195360060B03C6B76'.

* Lesen der ID für den Referenz-IMG
* SPRO-ID aus der Tabelle SCUS_HIER (Ersetzungstabelle für Hierarchien)
CALL FUNCTION 'S_CUS_IMG_GET_REFERENCE_IMG_ID'
  IMPORTING
    reference_img_id = lv_img_id.

* Anzeigeattribute der Hierarchiepflege
DATA(it_user_parameters) = VALUE streeprop_t( ( name = 'APPLICATION'     value = 'CU' )
                                              ( name = 'CONTROL_ENABLED' value = abap_true )
                                              ( name = 'DYNPRO_TITLE'    value = 'Überschrift' ) ).

* Anzeige einer Struktur
CALL FUNCTION 'STREE_EXTERNAL_DISPLAY'
  EXPORTING
    structure_id    = lv_img_id
  TABLES
    user_parameters = it_user_parameters.

Links

[ABAP] Sichten zu einem Material anzeigen

PARAMETERS: p_mat TYPE mara-matnr.

START-OF-SELECTION.

* Status definieren
  SELECT FROM t132 AS t
    LEFT OUTER JOIN t132t AS tt ON t~statm = tt~statm
    FIELDS
      t~statm,
      t~kzdum,
      tt~sttxt
    WHERE tt~spras = @sy-langu
    INTO TABLE @DATA(it_t132).

* Werksdaten zum Material
  SELECT FROM marc
    FIELDS
      matnr,
      werks,
      pstat
    WHERE matnr EQ @p_mat
    ORDER BY werks
    INTO TABLE @DATA(it_marc).

* Materialstammstatus
  SELECT FROM msta
    FIELDS *
    WHERE matnr EQ @p_mat
    ORDER BY werks
    INTO TABLE @DATA(it_msta).

* Daten im Inline-Browser im SAP-Fenster anzeigen
  cl_abap_browser=>show_html( EXPORTING
                                title        = 'Sichten zum Material'
                                html_string  = cl_demo_output=>new( )->write_data( it_t132 )->write_data( it_marc )->write_data( it_msta )->get( )
                                container    = cl_gui_container=>default_screen ).

* cl_gui_container=>default_screen erzwingen
  WRITE: space.

[ABAP] Geschäftspartner (Business Partner) in der Transaktion BP anzeigen

Variante 1: Anzeige über Partnernummer


PARAMETERS: p_bp TYPE bapibus1006_head-bpartner.

START-OF-SELECTION.

  IF NOT p_bp IS INITIAL.

* SAP-GP Dialog: Navigationscommando
    DATA(o_req) = NEW cl_bupa_navigation_request( ).
* Partnernummer setzen, analog zu set_partner_guid( )
    o_req->set_partner_number( p_bp ).
* Setzt die aktive Pflege (Einstieg, Partnerdaten, Beziegungen)
    o_req->set_maintenance_id( iv_value = cl_bupa_navigation_request=>gc_maintenance_id_partner ).
* Aktivität zur Anzeige / Pflege der Geschäftspartnerdaten
    o_req->set_bupa_activity( iv_value = cl_bupa_navigation_request=>gc_activity_display ).
* Setzt den aktiven Tabreiter der Geschäftspartnerpflege
*    o_req->set_bupa_sub_header_tab( 'CVIC01' ). " Tabelle TBZ3A, Objekt BUPA
* Setzt die Geschäftspartnerrolle für die Geschäftspartnerpflege
*    o_req->set_bupa_partner_role( VALUE #( role = 'FS0000' ) ). " Tabelle TB003

* SAP-GP Dialog: Startoptionen für die Pflegeoberfläche
    DATA(o_options) = NEW cl_bupa_dialog_joel_options( ).
* Setzt die Sichtbarkeit des Locators
    o_options->set_locator_visible( space ).

* Macht das Navigieren zu anderen Partnern unmöglich
*    o_options->set_navigation_disabled( abap_true ).
* Setzt das Kennzeichen für 'Anlegen von Beziehungen' erlaubt
*    o_options->set_bupr_create_not_allowed( abap_true ).
* Macht das Navigieren zu anderen Rollen unmöglich
*    o_options->set_role_switching_disabled( abap_true ).
* Maintenance
*    o_options->set_bupr_maintenance( VALUE #( create_allowed = abap_true
*                                              change_allowed = abap_true
*                                              delete_allowed = abap_true ) ).
* Macht das Navigieren zu einer anderen Aktivität unmöglich
*    o_options->set_activity_switching_off( space ).

* Startmethode für Aufrufe aus anderen Anwendungen
    cl_bupa_dialog_joel=>start_with_navigation( iv_request              = o_req
                                                iv_options              = o_options
                                                iv_in_new_internal_mode = abap_true ).
  ENDIF.

Variante 2: Anzeige über GUID des Business-Partners

PARAMETERS: p_bp TYPE bapibus1006_head-bpartner.

START-OF-SELECTION.

  IF NOT p_bp IS INITIAL.

* GP: Allgemeine Daten I
* BP-GUID zur Partnernummer holen
    SELECT SINGLE FROM but000
      FIELDS partner_guid
      WHERE partner = @p_bp
      INTO @DATA(lv_bp_guid).

    IF lv_bp_guid IS NOT INITIAL.
* SAP-GP Dialog: Navigationscommando
      DATA(o_req) = NEW cl_bupa_navigation_request( ).
      o_req->set_partner_guid( lv_bp_guid ).
      o_req->set_maintenance_id( iv_value = cl_bupa_navigation_request=>gc_maintenance_id_partner ).
      o_req->set_bupa_activity( iv_value = cl_bupa_navigation_request=>gc_activity_display ).

* SAP-GP Dialog: Startoptionen für die Pflegeoberfläche
      DATA(o_options) = NEW cl_bupa_dialog_joel_options( ).
      o_options->set_locator_visible( space ).

* Startmethode für Aufrufe aus anderen Anwendungen
      cl_bupa_dialog_joel=>start_with_navigation( iv_request              = o_req
                                                  iv_options              = o_options
                                                  iv_in_new_internal_mode = abap_true ).
    ENDIF.
  ENDIF.

Links

[ABAP] Informationen zu einer Einkäufergruppe als Popup anzeigen

PARAMETERS: p_ekgrp TYPE t024-ekgrp.

START-OF-SELECTION.

  SELECT FROM t024
    FIELDS *
    WHERE ekgrp EQ @p_ekgrp
    INTO TABLE @DATA(it_t024).

  IF sy-subrc = 0.

    TRY.
        DATA: o_pop_ekgrp TYPE REF TO cl_salv_table.

        cl_salv_table=>factory( IMPORTING r_salv_table = o_pop_ekgrp
                                CHANGING  t_table      = it_t024 ).

        o_pop_ekgrp->get_functions( )->set_all( abap_true ).
        o_pop_ekgrp->get_columns( )->set_optimize( abap_true ).
        o_pop_ekgrp->get_display_settings( )->set_list_header( 'Einkäufergruppe' ).
        o_pop_ekgrp->get_display_settings( )->set_striped_pattern( abap_true ).
        o_pop_ekgrp->get_selections( )->set_selection_mode( if_salv_c_selection_mode=>row_column ).

        o_pop_ekgrp->set_screen_popup( start_column = 1
                                       end_column   = 140
                                       start_line   = 1
                                       end_line     = 20 ).
        o_pop_ekgrp->display( ).
      CATCH cx_root INTO DATA(e_txt).
        WRITE: / e_txt->get_text( ).
    ENDTRY.

  ENDIF.

[ABAP] Adressdaten lesen

* Adressnummer mit führenden Nullen
PARAMETERS: p_adr TYPE adrc-addrnumber.

START-OF-SELECTION.

  DATA(lv_addr1_sel) = VALUE addr1_sel( addrnumber = p_adr ).
  DATA(lv_addr1_val) = VALUE addr1_val( ).

  CALL FUNCTION 'ADDR_GET'
    EXPORTING
      address_selection = lv_addr1_sel
    IMPORTING
      address_value     = lv_addr1_val
    EXCEPTIONS
      parameter_error   = 1
      address_not_exist = 2
      version_not_exist = 3
      internal_error    = 4
      OTHERS            = 5.

  IF sy-subrc = 0.
* Daten im Inline-Browser im SAP-Fenster anzeigen
    cl_abap_browser=>show_html( EXPORTING
                                  title        = 'Adressdaten'
                                  html_string  = cl_demo_output=>new( )->write_data( lv_addr1_sel )->write_data( lv_addr1_val )->get( )
                                  container    = cl_gui_container=>default_screen ).

* cl_gui_container=>default_screen erzwingen
    WRITE: space.
  ENDIF.

Links

[ABAP] Adressdaten anzeigen

* Adressnummer mit führenden Nullen
PARAMETERS: p_adr TYPE adrc-addrnumber.

START-OF-SELECTION.

  DATA: lv_okcode TYPE sy-ucomm.
  DATA: it_handle TYPE STANDARD TABLE OF addr1_dia WITH NON-UNIQUE DEFAULT KEY.
  DATA: it_values TYPE STANDARD TABLE OF addr1_data WITH DEFAULT KEY.

* Adressgruppe aus der ADRC holen
  SELECT SINGLE FROM adrc
    FIELDS addr_group
    WHERE addrnumber EQ @p_adr
    INTO @DATA(lv_adr_grp).

  it_handle = VALUE #( ( addrnumber = p_adr      " Adressnummer aus er ADRC
                         maint_mode = 'DISPLAY'  " Daten nur anzeigen, weitere Modi sind 'CREATE' und 'CHANGE'
                         country    = 'DE'       " Ausgabeformat
                         addr_group = lv_adr_grp " siehe Tabelle TSAD7 (Adreßgruppen (Business Address Services))
                       ) ).

* Dialogpflege von Adressen
  CALL FUNCTION 'ADDR_DIALOG'
    IMPORTING
      ok_code           = lv_okcode
    TABLES
      number_handle_tab = it_handle
      values            = it_values
    EXCEPTIONS
      address_not_exist = 1
      group_not_valid   = 2
      parameter_error   = 3
      internal_error    = 4
      OTHERS            = 5.

  IF sy-subrc = 0.
* Daten im Inline-Browser im SAP-Fenster anzeigen
    cl_abap_browser=>show_html( EXPORTING
                                  title        = 'Adressdaten'
                                  html_string  = cl_demo_output=>new( )->write_data( lv_okcode )->write_data( it_values )->get( )
                                  container    = cl_gui_container=>default_screen ).

* cl_gui_container=>default_screen erzwingen
    WRITE: space.
  ENDIF.

Links

[ABAP] Pivot-Darstellung von Feldwerten eines CDS-Views / SELECT-Statements (CASE, SUM, STRING_AGG, substring_regexpr, RegEx, PCRE, UNION, COLLECT)

Variante 1 (CDS-View mit CASE, SUM, GROUP BY)

* Daten werden hier mit CDS-View R_ProdValuationLedgerAccountTP (Product Valuation Ledger Account - TP) gelesen
* Suche der Periodischen Verrechnungspreise im Material Ledger über
* CDS-View r_prodvaluationledgeraccounttp (Product Valuation Ledger Account - TP).
* Das CDS-View liefert zeilenweise zu jedem Währungstyp einen Preis, die jeweils leeren Zeilen für die Preise
* (price_10, price_30, price_31) werden mit dem Wert '0.0' vorbelegt.
* Durch die Summenbildung pro Gruppe werden die Datensätze zu einer Zeile mit den zug. Preisen in Spalten zusammengefasst.
* Die Typkonvertierung abap.curr <-> abap.dec ist notwendig, da die Funktion sum( ) nur mit abap.dec arbeitet.
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Testview für PIVOT'
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType:{
    serviceQuality: #X,
    sizeCategory: #S,
    dataClass: #MIXED
}
define view entity Z_CDS_PIVOT
  as select from R_ProdValuationLedgerAccountTP
{
  key Product,
  key ValuationArea,
  key ValuationType,
  @EndUserText.label: 'Ledger'
  key Ledger,
      Currency,
  // Summe der Spalte MovingAveragePrice für Währungstyp 10
  @EndUserText.label: 'Preis WT 10'
  @Semantics.amount.currencyCode: 'Currency'
      cast(sum(case when CurrencyRole = '10' then cast(MovingAveragePrice as abap.dec( 16, 2 )) else 0.0 end) as abap.curr( 16, 2 )) as price_10,
  // Summe der Spalte MovingAveragePrice für Währungstyp 30
  @EndUserText.label: 'Preis WT 30'
  @Semantics.amount.currencyCode: 'Currency'
      cast(sum(case when CurrencyRole = '30' then cast(MovingAveragePrice as abap.dec( 16, 2 )) else 0.0 end) as abap.curr( 16, 2 )) as price_30,
  // Summe der Spalte MovingAveragePrice für Währungstyp 31
  @EndUserText.label: 'Preis WT 31'
  @Semantics.amount.currencyCode: 'Currency'
      cast(sum(case when CurrencyRole = '31' then cast(MovingAveragePrice as abap.dec( 16, 2 )) else 0.0 end) as abap.curr( 16, 2 )) as price_31
}
// Gruppierung, damit die Summenbildung oben pro Gruppe (Produkt / Währungstyp) erfolgt
group by Product,
         ValuationArea,
         ValuationType,
         Ledger,
         Currency,
         MovingAveragePrice

Variante 2 (SELECT, SUM, CASE, GROUP BY)

* Im Beispiel werden durch Anweisungen in einem SELECT-Statement mehrere Zeilen einer Rückgabemenge zu einer Zeile zusammengefasst (gruppiert).
* Kern der Funktion zur Umwandlung der Zeilenwerte in Spaltenwerte sind die Funktionen:
*  SUM( )
*  CASE
*  GROUP BY

PARAMETERS: p_matnr TYPE r_prodvaluationledgeraccounttp-product DEFAULT '1122334455'.
PARAMETERS: p_bwkey TYPE r_prodvaluationledgeraccounttp-valuationarea DEFAULT '0001'.
PARAMETERS: p_bwtar TYPE r_prodvaluationledgeraccounttp-valuationtype DEFAULT ''.
PARAMETERS: p_ledger TYPE r_prodvaluationledgeraccounttp-ledger DEFAULT '0L'.

START-OF-SELECTION.
* Suche der Periodischen Verrechnungspreise im Material Ledger über
* CDS-View r_prodvaluationledgeraccounttp (Product Valuation Ledger Account - TP).
* Das SELECT liefert zeilenweise zu jedem Währungstyp einen Preis, die jeweils leeren Zeilen für die Preise
* (price_10, price_30, price_31) werden mit dem Wert dec`0.00` vorbelegt.
* Durch die Summenbildung pro Gruppe werden die Datensätze zu einer Zeile mit den zug. Preisen in Spalten zusammengefasst.
  SELECT FROM r_prodvaluationledgeraccounttp AS l
    FIELDS
      l~product,
      l~valuationarea,
      l~valuationtype,
      l~ledger,
      l~currency,
* Summe der Spalte MovingAveragePrice für Währungstyp 10
      SUM( CASE WHEN currencyrole = '10' THEN movingaverageprice ELSE dec`0.00` END ) AS price_10,
* Summe der Spalte MovingAveragePrice für Währungstyp 30
      SUM( CASE WHEN currencyrole = '30' THEN movingaverageprice ELSE dec`0.00` END ) AS price_30,
* Summe der Spalte MovingAveragePrice für Währungstyp 31
      SUM( CASE WHEN currencyrole = '31' THEN movingaverageprice ELSE dec`0.00` END ) AS price_31
    WHERE l~product       EQ @p_matnr
      AND l~valuationarea EQ @p_bwkey
      AND l~valuationtype EQ @p_bwtar
      AND l~ledger        EQ @p_ledger
* Gruppierung, damit die Summenbildung oben pro Gruppe (Produkt / Währungstyp) erfolgt
    GROUP BY l~product,
             l~valuationarea,
             l~valuationtype,
             l~ledger,
             l~currency,
             l~movingaverageprice
    ORDER BY l~product
    INTO TABLE @DATA(it_product).

  IF sy-subrc = 0.
* Daten im Inline-Browser im SAP-Fenster anzeigen
    cl_abap_browser=>show_html( EXPORTING title       = 'Pivot'
                                          html_string = cl_demo_output=>new( )->write_data( it_product )->get( )
                                          container   = cl_gui_container=>default_screen ).

* cl_gui_container=>default_screen erzwingen
    WRITE: space.
  ENDIF.

Variante 3 (SELECT, STRING_AGG, substring_regexpr, GROUP BY)

* Im Beispiel werden durch Anweisungen in einem SELECT-Statement mehrere Zeilen einer Rückgabemenge zu einer Zeile zusammengefasst (gruppiert).
* Kern der Funktion zur Umwandlung der Zeilenwerte in Spaltenwerte sind die Funktionen:
*  STRING_AGG( )
*  substring_regexpr( ) mit PCRE-RegEx
*  GROUP BY
 
* als Konstanten für die PCRE-RegEx sind nur elementare Datentypen (keine Strings) erlaubt (hier: CHAR)
* die Längen der Zeichenketten müssen exakt stimmen,
* sonst funktioniert das Pattern-Matching bei der RegEx nicht
* zum Testen der PCRE-RegEx siehe auch: https://regex101.com/
CONSTANTS: co_part1 TYPE char11 VALUE '^(\d+\.\d+)'.
CONSTANTS: co_part2 TYPE char21 VALUE '^\d+\.\d+\|\K\d+\.\d+'.
CONSTANTS: co_part3 TYPE char31 VALUE '^\d+\.\d+\|\d+\.\d+\|\K\d+\.\d+'.
 
PARAMETERS: p_matnr TYPE i_prodvalnledgeraccounttp_2-product DEFAULT '1122334455'.
PARAMETERS: p_bwkey TYPE i_prodvalnledgeraccounttp_2-valuationarea DEFAULT '0001'.
PARAMETERS: p_bwtar TYPE i_prodvalnledgeraccounttp_2-valuationtype DEFAULT ''.
PARAMETERS: p_ledger TYPE i_prodvalnledgeraccounttp_2-ledger DEFAULT '0L'.
 
START-OF-SELECTION.
* Suche der Periodischen Verrechnungspreise im Material Ledger über
* CDS-View I_PRODVALNLEDGERACCOUNTTP_2 (Product Valuation Ledger Account - TP)
* das SELECT liefert zeilenweise zu jedem Währungstyp einen Preis
* über STRING_AGG werden die Preise zu einer Gruppe mit Trennzeichen zusammengefasst
* mit substring_regexpr kann über eine RegEx dann ein Teil (erster, mittlerer oder letzter) dieser Gruppe extrahiert werden
  SELECT FROM i_prodvalnledgeraccounttp_2 AS pa
    FIELDS
      pa~product,
      pa~valuationarea,
      pa~ledger,
      pa~productpriceunitquantity,
      pa~currency,
      pa~standardprice,
      pa~companycode,
      pa~baseunit,
* Beispiel: periodische Verrechnungspreise als Gruppe zu einem String mit Trennzeichen "," zusammenfassen
      STRING_AGG( CAST( pa~movingaverageprice AS CHAR ), ', ' ) AS avg_price_all,
* Beispiel: periodische Verrechnungspreise als Gruppe zu einem String mit Trennzeichen "|" zusammenfassen
*           und über eine PCRE-RegEx den ersten Wert bis zum Trennzeichen "|" in eine Spalte avg_price1 schreiben
      substring_regexpr( pcre = @co_part1, value = STRING_AGG( CAST( pa~movingaverageprice AS CHAR ), '|' ) ) AS avg_price1,
* Beispiel: periodische Verrechnungspreise als Gruppe zu einem String mit Trennzeichen "|" zusammenfassen
*           und über eine PCRE-RegEx den mittleren Wert von "|" bis "|" in eine Spalte avg_price2 schreiben
      substring_regexpr( pcre = @co_part2, value = STRING_AGG( CAST( pa~movingaverageprice AS CHAR ), '|' ) ) AS avg_price2,
* Beispiel: periodische Verrechnungspreise als Gruppe zu einem String mit Trennzeichen "|" zusammenfassen
*           und über eine PCRE-RegEx den letzen Wert ab "|" in eine Spalte avg_price3 schreiben
      substring_regexpr( pcre = @co_part3, value = STRING_AGG( CAST( pa~movingaverageprice AS CHAR ), '|' ) ) AS avg_price3
    WHERE pa~product       EQ @p_matnr
      AND pa~valuationarea EQ @p_bwkey
      AND pa~valuationtype EQ @p_bwtar
      AND pa~ledger        EQ @p_ledger
    GROUP BY pa~product,
             pa~valuationarea,
             pa~ledger,
             pa~productpriceunitquantity,
             pa~currency,
             pa~standardprice,
             pa~companycode,
             pa~baseunit
    ORDER BY pa~product
    INTO TABLE @DATA(it_product).
 
  IF sy-subrc = 0.
    TRY.
* SALV-Table
        DATA: o_salv TYPE REF TO cl_salv_table.
 
        cl_salv_table=>factory( IMPORTING r_salv_table = o_salv
                                CHANGING  t_table      = it_product ).
 
* Grundeinstellungen
        o_salv->get_functions( )->set_all( abap_true ).
        o_salv->get_columns( )->set_optimize( abap_true ).
        o_salv->get_display_settings( )->set_list_header( 'Pivot' ).
        o_salv->get_display_settings( )->set_striped_pattern( abap_true ).
        o_salv->get_selections( )->set_selection_mode( if_salv_c_selection_mode=>row_column ).
 
* Spaltenüberschriften: technischer Name und Beschreibungstexte, Short Text und Medium Text leer lassen für Autosize
        LOOP AT o_salv->get_columns( )->get( ) ASSIGNING FIELD-SYMBOL(<c>).
          DATA(o_col) = <c>-r_column.
          o_col->set_short_text( || ).
          o_col->set_medium_text( || ).
          IF o_col->get_long_text( ) IS INITIAL.
            o_col->set_long_text( |{ o_col->get_columnname( ) }| ).
          ELSE.
            o_col->set_long_text( |{ o_col->get_long_text( ) }| ).
          ENDIF.
        ENDLOOP.
 
        o_salv->display( ).
      CATCH cx_root INTO DATA(e_txt).
        WRITE: / e_txt->get_text( ).
    ENDTRY.
  ENDIF.

Variante 4 (SELECT, UNION, COLLECT)

TYPES: BEGIN OF ty_s_product,
         product TYPE i_prodvalnledgeraccounttp_2-product,
* Platzhalter für die Periodischen Verrechnungspreise je Währungstyp
         p1      TYPE i_prodvalnledgeraccounttp_2-movingaverageprice,
         p2      TYPE i_prodvalnledgeraccounttp_2-movingaverageprice,
         p3      TYPE i_prodvalnledgeraccounttp_2-movingaverageprice,
       END OF ty_s_product.

TYPES: ty_it_product TYPE STANDARD TABLE OF ty_s_product WITH DEFAULT KEY.

PARAMETERS: p_matnr TYPE i_prodvalnledgeraccounttp_2-product DEFAULT '1122334455'.
PARAMETERS: p_bwkey TYPE i_prodvalnledgeraccounttp_2-valuationarea DEFAULT '0001'.
PARAMETERS: p_bwtar TYPE i_prodvalnledgeraccounttp_2-valuationtype DEFAULT ''.
PARAMETERS: p_ledger TYPE i_prodvalnledgeraccounttp_2-ledger DEFAULT '0L'.

START-OF-SELECTION.

  DATA: it_product_union TYPE ty_it_product.

* Suche der Periodischen Verrechnungspreise pro Währungstyp im Material Ledger über
* CDS-View I_PRODVALNLEDGERACCOUNTTP_2 (Product Valuation Ledger Account - TP)
* Die Datensätze pro Währungstyp werden hier über ein UNION-Statement zu einer Ausgabemenge
* zusammengeführt. Dabei werden die jeweils leeren Preise für p1, p2, p3 mit dec`0.00` vorbelegt,
* damit später bei COLLECT die Werte korrekt in einer Zeile verdichtet werden.

* erstes SELECT für Währungstyp '10'
  SELECT FROM i_prodvalnledgeraccounttp_2 AS pa
    FIELDS
        pa~product,
        pa~movingaverageprice AS p1,
        dec`0.00` AS p2,
        dec`0.00` AS p3
    WHERE pa~product       EQ @p_matnr
      AND pa~valuationarea EQ @p_bwkey
      AND pa~valuationtype EQ @p_bwtar
      AND pa~ledger        EQ @p_ledger
      AND pa~currencyrole  EQ '10'
  UNION
* zweites SELECT für Währungstyp '30'
  SELECT FROM i_prodvalnledgeraccounttp_2 AS pa
    FIELDS
        pa~product,
        dec`0.00` AS p1,
        pa~movingaverageprice AS p2,
        dec`0.00` AS p3
    WHERE pa~product       EQ @p_matnr
      AND pa~valuationarea EQ @p_bwkey
      AND pa~valuationtype EQ @p_bwtar
      AND pa~ledger        EQ @p_ledger
      AND pa~currencyrole  EQ '30'
  UNION
* drittes SELECT für Währungstyp '31'
  SELECT FROM i_prodvalnledgeraccounttp_2 AS pa
    FIELDS
        pa~product,
        dec`0.00` AS p1,
        dec`0.00` AS p2,
        pa~movingaverageprice AS p3
    WHERE pa~product       EQ @p_matnr
      AND pa~valuationarea EQ @p_bwkey
      AND pa~valuationtype EQ @p_bwtar
      AND pa~ledger        EQ @p_ledger
      AND pa~currencyrole  EQ '31'
  INTO CORRESPONDING FIELDS OF TABLE @it_product_union.

  IF sy-subrc = 0.
* Daten-Aufbereitung
    DATA: it_product_pivot TYPE HASHED TABLE OF ty_s_product WITH UNIQUE KEY product.

    LOOP AT it_product_union ASSIGNING FIELD-SYMBOL(<p>).
* COLLECT verdichtet gleiche Datensätze zu einem Datensatz, verwendet intern HASHED TABLES
* Zu beachten ist dabei, dass beim Verdichten die Zahlenwerte (int, fltp, dec usw.)
* der einzelnen Zeilen summiert werden!
      COLLECT <p> INTO it_product_pivot.
    ENDLOOP.

* Daten im Inline-Browser im SAP-Fenster anzeigen
    cl_abap_browser=>show_html( EXPORTING title       = 'Pivot'
                                          html_string = cl_demo_output=>new( )->write_data( it_product_union )->write_data( it_product_pivot )->get( )
                                          container   = cl_gui_container=>default_screen ).

* cl_gui_container=>default_screen erzwingen
    WRITE: space.

  ENDIF.

Links

[ABAP] Zu einem Datum spezielle Kalenderwerte ausgeben

* liest Tabelle SCAL_TT_DATE (Date table containing dates from 01011900 to 31129999) mit folgenden Werten:
* Kalenderjahr
* Kalenderquartal
* Kalendermonat
* Kalenderwoche
* Kalendertag
* Jahr Monat
* Jahr Quartal
* Jahr Woche
* Wochentag
* Datum für ersten Tag
* Erster Tag d. Monats
* Letzter Tag Monat
* Kalendertag des J.
* Tag des Jahres
SELECT SINGLE FROM i_calendardate AS i
  FIELDS *
  WHERE i~calendardate EQ @sy-datum
  INTO @DATA(lv_cal).

IF sy-subrc = 0.
  cl_abap_browser=>show_html( EXPORTING
                                title        = 'aktuelle Kalenderdaten'
                                html_string  = cl_demo_output=>new( )->write_data( lv_cal )->get( )
                                container    = cl_gui_container=>default_screen ).

* cl_gui_container=>default_screen erzwingen
  WRITE: space.
ENDIF.