Suchergebnisse für: cl_salv_table

[ABAP] SALV-Table: Hilfsklasse zur Ermittlung der Referenz auf ALV-Table (cl_gui_alv_grid) einer SALV-Table (cl_salv_table)

bis SAP-Realease 754: Hilfsklasse lcl_salv_helper abgeleitet von cl_salv_model_base

* bis SAP-Realease 754
* https://zevolving.com/2015/06/salv-table-20-editable-yes-as-per-this-standard-sap-application/

CLASS lcl_salv_helper DEFINITION INHERITING FROM cl_salv_model_base.
  PUBLIC SECTION.

    CLASS-METHODS:
      get_alv_from_salv
        IMPORTING
          io_model       TYPE REF TO cl_salv_model
        RETURNING
          VALUE(ro_grid) TYPE REF TO cl_gui_alv_grid.
ENDCLASS.

CLASS lcl_salv_helper IMPLEMENTATION.
*---------------------------------------------------------------------*
* Wandelt eine Referenz auf cl_salv_table in ein cl_gui_alv_grid um.
* Funktioniert nur, wenn SALV-Table schon mit display( ) angezeigt
* wurde, d.h. schon ein Container dafür erzeugt wurde. Andernfalls ist
* r_adapter INITIAL.
*---------------------------------------------------------------------*
* -> io_model - Referenz auf cl_salv_table (cl_salv_model)
* <- ro_grid  - Referenz auf cl_gui_alv_grid, bei Fehler INITIAL
*---------------------------------------------------------------------*
  METHOD get_alv_from_salv.
  
* wenn Typ 'Table'
    IF io_model->model = if_salv_c_model=>table.
      TRY.
          IF abap_true = cl_wdy_wb_reflection_helper=>is_instance_of( object = io_model->r_controller->r_adapter
                                                                      type_name = 'CL_SALV_GRID_ADAPTER' ).
                                                                      
            DATA(o_grid_adap) = CAST cl_salv_grid_adapter( io_model->r_controller->r_adapter ).

            IF o_grid_adap IS BOUND.
              ro_grid = o_grid_adap->get_grid( ).
            ENDIF.
          ELSEIF abap_true = cl_wdy_wb_reflection_helper=>is_instance_of( object = io_model->r_controller->r_adapter
                                                                          type_name = 'CL_SALV_FULLSCREEN_ADAPTER' ).

            DATA(o_fs_adap) = CAST cl_salv_fullscreen_adapter( io_model->r_controller->r_adapter ).

            IF o_fs_adap IS BOUND.
              ro_grid = o_fs_adap->get_grid( ).
            ENDIF.
          ENDIF.
        CATCH cx_root.
      ENDTRY.
    ENDIF.
  ENDMETHOD.

ENDCLASS.

ab SAP-Release 755: Hilfsklasse lcl_salv_helper mit Nutzung des Interfaces if_salv_table_display_adapter

* ab SAP-Release 755
* SALV-Table: Hilfsklasse zur Ermittlung der Referenz auf ALV-Table (cl_gui_alv_grid) einer SALV-Table (cl_salv_table)
* ab SAP-Release 755 hat die Klasse CL_SALV_FULLSCREEN_ADAPTER keine Funktion get_grid( ) mehr
* somit muss das Coding ab SAP-Release 755 geändert werden
* Quellen:
* https://blogs.sap.com/2022/08/01/editable-cl_salv_table-after-release-756/
* https://tricktresor.de/blog/alv-grid-aus-salv-ermitteln-ab-release-7-55/

CLASS lcl_salv_helper DEFINITION INHERITING FROM cl_salv_model_base FINAL.
  PUBLIC SECTION.

    CLASS-METHODS:
      get_alv_from_salv
        IMPORTING
          io_salv_grid   TYPE REF TO cl_salv_table
        RETURNING
          VALUE(ro_grid) TYPE REF TO cl_gui_alv_grid.
ENDCLASS.

CLASS lcl_salv_helper IMPLEMENTATION.
*---------------------------------------------------------------------*
* Wandelt eine Referenz auf cl_salv_table in ein cl_gui_alv_grid um.
*---------------------------------------------------------------------*
* -> io_model - Referenz auf cl_salv_table (cl_salv_table)
* <- ro_grid  - Referenz auf cl_gui_alv_grid, bei Fehler INITIAL
*---------------------------------------------------------------------*
  METHOD get_alv_from_salv.

    IF io_salv_grid IS BOUND.

      TRY.
          DATA(o_model) = CAST cl_salv_model_base( io_salv_grid->extended_grid_api( ) ).

* Funktioniert nur, wenn SALV-Table schon mit display( ) angezeigt und
* somit schon ein Container dafür erzeugt wurde. Andernfalls ist r_adapter INITIAL.
          IF o_model->r_controller IS BOUND AND o_model->r_controller->r_adapter IS BOUND.

            IF o_model->r_controller->r_adapter IS INSTANCE OF if_salv_table_display_adapter.
              ro_grid = CAST if_salv_table_display_adapter( o_model->r_controller->r_adapter )->get_grid( ).
            ENDIF.

          ENDIF.

        CATCH cx_root.
      ENDTRY.

    ENDIF.

  ENDMETHOD.

ENDCLASS.

Anwendungsbeispiel

* Anwendungs-Beispiel
CLASS lcl_event DEFINITION.
  PUBLIC SECTION.
    CONSTANTS: co_btn_click TYPE string VALUE 'BTN_KLICK'.

    CLASS-METHODS: on_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
      IMPORTING
        e_object
        sender.
    CLASS-METHODS: on_user_command FOR EVENT user_command OF cl_gui_alv_grid
      IMPORTING
        e_ucomm
        sender.
ENDCLASS.

CLASS lcl_event IMPLEMENTATION.
* Toolbar-Buttons hinzufügen
  METHOD on_toolbar.
* Separator hinzufügen
    APPEND VALUE #( butn_type = cntb_btype_sep ) TO e_object->mt_toolbar.
* Edit-Button hinzufügen
    APPEND VALUE #( butn_type = cntb_btype_button
                    text = 'Klick!'
                    icon = icon_change_text
                    function = co_btn_click
                    quickinfo = 'Etwas ausgeben'
                    disabled = abap_false ) TO e_object->mt_toolbar.
  ENDMETHOD.

* User-Command
  METHOD on_user_command.
    CASE e_ucomm.
      WHEN co_btn_click.
        MESSAGE |Klick: { sender->m_guid }| TYPE 'I'.
    ENDCASE.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

  TRY.
      DATA: o_salv TYPE REF TO cl_salv_table.

* Daten holen
      SELECT FROM t000
        FIELDS *
        INTO TABLE @DATA(it_t000).

      cl_salv_table=>factory( EXPORTING r_container  = cl_gui_container=>default_screen
                              IMPORTING r_salv_table = o_salv
                              CHANGING  t_table      = it_t000 ).

      o_salv->get_functions( )->set_all( ).

      o_salv->display( ).

* Referenz auf ALV-Grid holen
      DATA(o_alv_grid) = lcl_salv_helper=>get_alv_from_salv( o_salv ).

      IF o_alv_grid IS BOUND.
* Eventhandler des ALV-Grids registrieren
        SET HANDLER lcl_event=>on_toolbar FOR o_alv_grid.
        SET HANDLER lcl_event=>on_user_command FOR o_alv_grid.

* Toolbar-Buttons refreshen
        o_alv_grid->refresh_table_display( ).
      ENDIF.
    CATCH cx_root INTO DATA(e_text).
      WRITE: / e_text->get_text( ).
  ENDTRY.

* leere Standard-Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

* Ausgabe von cl_gui_container=>default_screen erzwingen
  WRITE space.

Links

[ABAP] XLSX-Datei mit Klasse cl_ehfnd_xlsx einlesen und in SALV-Grid anzeigen

TRY.
    DATA: lv_rc TYPE i.
    DATA: it_files TYPE filetable.
    DATA: lv_action TYPE i.

* FileOpen-Dialog aufrufen
    cl_gui_frontend_services=>file_open_dialog( EXPORTING file_filter = |xlsx (*.xlsx)\|*.xlsx\|{ cl_gui_frontend_services=>filetype_all }|
                                                CHANGING  file_table  = it_files
                                                          rc          = lv_rc
                                                          user_action = lv_action ).

    IF lv_action = cl_gui_frontend_services=>action_ok.
* wenn Datei ausgewählt wurde
      IF lines( it_files ) > 0.
* ersten Tabelleneintrag lesen
        DATA: lv_filesize TYPE w3param-cont_len.
        DATA: lv_filetype TYPE w3param-cont_type.
        DATA: it_bin_data TYPE w3mimetabtype.

* Excel-Datei auf Appl. Server hochladen (binary)
        cl_gui_frontend_services=>gui_upload( EXPORTING filename   = |{ it_files[ 1 ]-filename }|
                                                        filetype   = 'BIN'
                                              IMPORTING filelength = lv_filesize
                                              CHANGING  data_tab   = it_bin_data ).

* solix -> xstring
        DATA(lv_bin_data) = cl_bcs_convert=>solix_to_xstring( it_solix = it_bin_data ).

**********************************************************************
* XLSX Handling: Kapselt cl_xlsx_document
**********************************************************************
        DATA(o_excel) = cl_ehfnd_xlsx=>get_instance( ).

* XLSX Workbook (XString --> XML)
        DATA(o_doc) = o_excel->load_doc( iv_file_data = lv_bin_data ).

* XLSX Sheets des Workbooks holen
        DATA(it_sheets) = o_doc->get_sheets( ).

        IF lines( it_sheets ) > 0.
* XLSX Sheet: erste Sheet holen
          DATA(o_sheet) = o_doc->get_sheet_by_id( iv_sheet_id = 1 ).
          DATA(lv_sheet_name) = it_sheets[ 1 ]-name.

* max. Zeilenzahl der Sheet
          DATA(lv_max_rows) = o_sheet->get_last_row_number( ).
          DATA(lv_max_cols) = o_sheet->get_last_column_number_in_row( 1 ).

          IF lv_max_rows > 0 AND lv_max_cols > 0.
* Komponenten (Spalten) der Tabelle --> generische Stringtable bauen
            DATA(it_components) = VALUE cl_abap_structdescr=>component_table( ).

* Überschriften (Header) für ALV-Grid
            DATA(it_colnames) = VALUE stringtab( ).

            DO lv_max_cols TIMES.
* Spaltenbezeichner aus 1. Zeile (Header) der Excel-Tabelle holen
              DATA(lv_col_header) = o_sheet->get_cell_content( iv_row    = 1
                                                               iv_column = sy-index ).

* alle Vorkommen, die nicht [a-zA-Z0-9_] entsprechen, durch '_' ersetzen
              REPLACE ALL OCCURRENCES OF REGEX '([^\w]|[äöüÄÖÜß])+' IN lv_col_header WITH '_'.

* Tabelle mit Überschriften für ALV-Grid füllen
              APPEND lv_col_header TO it_colnames.

* Spalte vom Typ String mit generischem Namen zur Komponententabelle hinzufügen
              APPEND VALUE #( name   = |COL{ sy-index }|
                              type   = cl_abap_elemdescr=>get_string( )
                            ) TO it_components.
            ENDDO.

**********************************************************************
* generische interne Tabelle mit hilfe dynamischer Objekte erzeugen
**********************************************************************
* Strukturdeskriptor für Komponententabelle erzeugen
            DATA(o_struct_desc) = cl_abap_structdescr=>create( it_components ).

* Tabellendeskriptor erzeugen
            DATA(o_table_desc) = cl_abap_tabledescr=>create( p_line_type = o_struct_desc ).

* dynamisches Tabellenobjekt anhand des Tabellendeskriptors erstellen
            DATA: o_table TYPE REF TO data.
            CREATE DATA o_table TYPE HANDLE o_table_desc.

* Feldsymbol auf das Tabellenobjekt vom Typ STANDARD TABLE anlegen
            FIELD-SYMBOLS <table> TYPE STANDARD TABLE.
            ASSIGN o_table->* TO <table>.

* Inhalt (ohne Header) aus XLSX in interne Tabelle schreiben
            DATA(lv_row) = 2.

            DO lv_max_rows - 1 TIMES.
              DATA(lv_col) = 1.

* neue Ausgabezeile anfügen
              APPEND INITIAL LINE TO <table>.

* neue Ausgabezeile holen und Feldsymbol zuweisen
              DATA(lv_lc) = lines( <table> ).
              ASSIGN <table>[ lv_lc ] TO FIELD-SYMBOL(<row>).

              IF <row> IS ASSIGNED.
* für alle Spalten der Tabelle
                DO lv_max_cols TIMES.
* n-te Spalte <col> der akt. Tabellenzeile <row> ermitteln
                  ASSIGN COMPONENT lv_col OF STRUCTURE <row> TO FIELD-SYMBOL(<cell>).
                  IF <cell> IS ASSIGNED.
* Inhalt der akt. Zelle in die Zelle der internen Tabelle schreiben
                    <cell> = o_sheet->get_cell_content( iv_row    = lv_row
                                                        iv_column = lv_col ).


                  ENDIF.

                  lv_col = lv_col + 1.
                ENDDO.
              ENDIF.

              lv_row = lv_row + 1.
            ENDDO.

**********************************************************************
* Anzeige der gefüllten generischen Tabelle in einem SALV-Grid
**********************************************************************
            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      = <table> ).

*             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( CONV #( lv_sheet_name ) ).
                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(lv_idx) = sy-tabix.

                  DATA(o_col) = <c>-r_column.
                  o_col->set_short_text( || ).
                  o_col->set_medium_text( || ).
                  o_col->set_long_text( CONV #( it_colnames[ lv_idx ] ) ).
                ENDLOOP.

                o_salv->display( ).
              CATCH cx_root INTO DATA(e_txt).
                WRITE: / e_txt->get_text( ).
            ENDTRY.
          ENDIF.

        ENDIF.

      ENDIF.

    ENDIF.

  CATCH cx_root INTO DATA(e_text).
    MESSAGE e_text->get_text( ) TYPE 'S' DISPLAY LIKE 'E'.
ENDTRY.

[ABAP] Editierbares SALV-Grid (IF_SALV_GUI_OM_EXTEND_GRID_API, IF_SALV_GUI_OM_EDIT_RESTRICTED)

* Quelle: https://blogs.sap.com/2022/08/01/editable-cl_salv_table-after-release-756/
* ab SAP Release 756
* Achtung: das Ganze funktioniert nur für kleine Tabellen mit max. 5000 Zellen, siehe:
*
* Methode: CL_SALV_GUI_OM_ADAPTER_TABLE->CAN_RUN_RESTRICTED_EDIT_MODE( )
* Konstante: CV_MAX_CELLS_FOR_EDITABLE (Wert: 5000).

* Eventhandler
CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
* Bezeichner der Buttons
    CONSTANTS: co_btn_edit TYPE string VALUE 'BTN_EDIT'.
    CONSTANTS: co_btn_save TYPE string VALUE 'BTN_SAVE'.

* Platzhalter für Referenz auf SALV-Grid
    CLASS-DATA: o_salv TYPE REF TO cl_salv_table.

* Eventhandler-Methode für Button-Klicks in der Toolbar des SALV-Grids
    CLASS-METHODS : on_toolbar_click FOR EVENT added_function OF cl_salv_events_table
      IMPORTING
        e_salv_function
        sender.
  PRIVATE SECTION.
* Edit-Status des SALV-Grids
    CLASS-DATA: gv_edit TYPE abap_bool VALUE abap_false.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
  METHOD on_toolbar_click.
    IF o_salv IS BOUND.

      DATA(o_api) = o_salv->extended_grid_api( ).
      DATA(o_edit) = o_api->editable_restricted( ).

      CASE e_salv_function.

        WHEN co_btn_edit.
* Edit-Modus umschalten
          IF gv_edit = abap_false.
            gv_edit = abap_true.
          ELSE.
            gv_edit = abap_false.
          ENDIF.

          TRY.
* Spalte(n) (nicht) editierbar setzen
              o_edit->set_attributes_for_columnname( EXPORTING columnname              = 'EKGRP'
                                                               all_cells_input_enabled = gv_edit ).

              o_edit->set_attributes_for_columnname( EXPORTING columnname              = 'SMTP_ADDR'
                                                               all_cells_input_enabled = gv_edit ).
            CATCH cx_salv_not_found.
          ENDTRY.

          o_edit->validate_changed_data( ).
          o_salv->refresh( ).

        WHEN co_btn_save.
* Daten auf Validität prüfen
          DATA(lv_data_is_valid) = abap_false.

          TRY.
              o_edit->validate_changed_data( IMPORTING is_input_data_valid = lv_data_is_valid ).
              o_salv->refresh( ).
            CATCH cx_salv_not_found.
          ENDTRY.

          IF lv_data_is_valid = abap_true.
* Daten hier speichern / weiterverarbeiten
            MESSAGE co_btn_save TYPE 'I'.
          ENDIF.
      ENDCASE.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

  TRY.
* Beispieldaten (Einkäufergruppen) holen
      SELECT FROM t024
        FIELDS *
        INTO TABLE @DATA(it_t024).

      IF sy-subrc = 0.
        cl_salv_table=>factory( EXPORTING r_container  = cl_gui_container=>default_screen
                                IMPORTING r_salv_table = lcl_events=>o_salv
                                CHANGING  t_table      = it_t024 ).

* Standardbuttons der SALV-Table ausblenden
        lcl_events=>o_salv->get_functions( )->set_all( abap_false ).

* Eigenen SALV-Button hinzufügen
* das Hinzufügen des Buttons funktioniert nur, wenn die SALV-Table innerhalb eines Containers (z.B. cl_gui_container=>default_screen) eingebettet ist
        lcl_events=>o_salv->get_functions( )->add_function( name = |{ lcl_events=>co_btn_edit }|
                                                            icon = |{ icon_edit_file }|
                                                            text = 'Edit'
                                                            tooltip = 'Daten editieren'
                                                            position = if_salv_c_function_position=>right_of_salv_functions ).

        lcl_events=>o_salv->get_functions( )->add_function( name = |{ lcl_events=>co_btn_save }|
                                                            icon = |{ icon_save_as_template }|
                                                            text = 'Save'
                                                            tooltip = 'Daten speichern'
                                                            position = if_salv_c_function_position=>right_of_salv_functions ).

* Eventhandler für Klicks in die Toolbar des SALV-Grids setzen
        SET HANDLER lcl_events=>on_toolbar_click FOR lcl_events=>o_salv->get_event( ).

* SALV anzeigen
        lcl_events=>o_salv->display( ).

* Toolbar der Listausgabe unterdrücken
        cl_abap_list_layout=>suppress_toolbar( ).

* Listausgabe erzwingen für Erzeugung von cl_gui_container=>default_screen
        WRITE: space.

      ENDIF.
    CATCH cx_root INTO DATA(e_txt).
      WRITE: / e_txt->get_text( ).
  ENDTRY.

[ABAP] Neue / obsolete Transaktionscodes für S/4 HANA suchen

* https://thinkdoforward.com/neue-transaktionen-mit-s-4hana-so-einfach-findest-zu-sie/
PARAMETERS: p_rel TYPE saprl DEFAULT '751'.
SELECT-OPTIONS: so_ta FOR lv_s_tcode.

START-OF-SELECTION.

  SELECT c~rel_name, c~s_tcode, c~t_tcode, tx~ttext
    INTO TABLE @DATA(it_prgn_corr2)
    FROM prgn_corr2 AS c
    INNER JOIN tstc AS t ON ( c~t_tcode = t~tcode )
    RIGHT OUTER JOIN tstct AS tx ON ( t~tcode = tx~tcode )
    WHERE c~rel_name >= @p_rel
      AND c~s_tcode IN @so_ta
      AND tx~sprsl = @sy-langu.

  SORT: it_prgn_corr2 BY s_tcode rel_name.


  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_prgn_corr2 ).

* 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( 'Überschrift' ).
      o_salv->get_display_settings( )->set_striped_pattern( abap_true ).
      o_salv->get_selections( )->set_selection_mode( if_salv_c_selection_mode=>row_column ).

      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( || ).
        o_col->set_long_text( |{ o_col->get_columnname( ) } [{ o_col->get_long_text( ) }]| ).
      ENDLOOP.

      o_salv->display( ).
    CATCH cx_root INTO DATA(e_txt).
      WRITE: / e_txt->get_text( ).
  ENDTRY.

[ABAP] Fixkontentabelle (T030) auslesen

* Kontenplan
DATA: lv_ktopl TYPE ktopl.
* Vorgangsschlüssel
DATA: lv_ktosl TYPE ktosl.
* Bewertungsmodifikationskonstante
DATA: lv_bwmod TYPE bwmod.
* Konto-Modifikation
DATA: lv_komok TYPE komok.
* Bewertungsklasse
DATA: lv_bklas TYPE bklas.
* Nummer des Sachkontos
DATA: lv_konts TYPE saknr.
* Nummer des Sachkontos
DATA: lv_konth TYPE saknr.

SELECT-OPTIONS: so_ktopl FOR lv_ktopl.
SELECT-OPTIONS: so_ktosl FOR lv_ktosl.
SELECT-OPTIONS: so_bwmod FOR lv_bwmod.
SELECT-OPTIONS: so_komok FOR lv_komok.
SELECT-OPTIONS: so_bklas FOR lv_bklas.
SELECT-OPTIONS: so_konts FOR lv_konts.
SELECT-OPTIONS: so_konth FOR lv_konts.

START-OF-SELECTION.

* T030 (Fixkontentabelle)
  SELECT *
    INTO TABLE @DATA(it_t030)
    FROM t030
    WHERE ktopl IN @so_ktopl.
*      ktosl IN @so_ktosl
*      bwmod IN @so_bwmod
*      komok IN @so_komok
*      bklas IN @so_bklas
*      konts IN @so_konts
*      konth IN @so_konth.

  IF sy-subrc = 0.
    TRY.
        DATA: o_salv TYPE REF TO cl_salv_table.

        cl_salv_table=>factory( EXPORTING
                                  r_container  = cl_gui_container=>default_screen
                                IMPORTING
                                  r_salv_table = o_salv
                                CHANGING
                                  t_table      = it_t030 ).

        o_salv->get_display_settings( )->set_striped_pattern( abap_true ).
        o_salv->get_columns( )->set_optimize( abap_true ).
        o_salv->get_functions( )->set_all( ).
        o_salv->get_selections( )->set_selection_mode( if_salv_c_selection_mode=>row_column ).
        o_salv->display( ).

        WRITE: / space.
      CATCH cx_root INTO DATA(e_text).
        WRITE: / e_text->get_text( ).
    ENDTRY.
  ENDIF.

[ABAP] ABAP2XLSX: Excel-Daten (*.xlsx) einlesen und anzeigen

**********************************************************************
* Types
**********************************************************************
TYPES: BEGIN OF ty_xl_line,
         col1 TYPE string,
         col2 TYPE string,
       END OF ty_xl_line.

TYPES: ty_it_xl_lines TYPE STANDARD TABLE OF ty_xl_line WITH DEFAULT KEY.

**********************************************************************
* Selektionsbild
**********************************************************************
PARAMETERS: p_fname TYPE file_table-filename OBLIGATORY.

* wenn die F4-Hilfe für den Dateinamen aufgerufen wird
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_fname.

  DATA: lv_rc TYPE i.
  DATA: it_files TYPE filetable.
  DATA: lv_action TYPE i.

* File-Tabelle leeren, da hier noch alte Einträge von vorherigen Aufrufen drin stehen können
  CLEAR it_files.

* FileOpen-Dialog aufrufen
  TRY.
      cl_gui_frontend_services=>file_open_dialog( EXPORTING
                                                    file_filter    = |xlsx (*.xlsx)\|*.xlsx\|{ cl_gui_frontend_services=>filetype_all }|
                                                    multiselection = abap_false
                                                  CHANGING
                                                    file_table  = it_files
                                                    rc          = lv_rc
                                                    user_action = lv_action ).

      IF lv_action = cl_gui_frontend_services=>action_ok.
* wenn Datei ausgewählt wurde
        IF lines( it_files ) > 0.
* ersten Tabelleneintrag lesen
          p_fname = it_files[ 1 ]-filename.
        ENDIF.
      ENDIF.

    CATCH cx_root INTO DATA(e_text).
      MESSAGE e_text->get_text( ) TYPE 'I'.
  ENDTRY.

START-OF-SELECTION.

  DATA(it_xl) = VALUE ty_it_xl_lines( ).

  TRY.
* Reader-Objekt erzeugen
      DATA(o_reader) = CAST zif_excel_reader( NEW zcl_excel_reader_2007( ) ).
      DATA(o_excel) = o_reader->load_file( p_fname ).

* Worksheet
      DATA(o_worksheet) = o_excel->get_active_worksheet( ).
* max. Zeile und Spalte holen
      DATA(lv_max_col) = o_worksheet->get_highest_column( ).
      DATA(lv_max_row)    = o_worksheet->get_highest_row( ).

      WRITE: / lv_max_col, ',', lv_max_row.

      DATA(lv_row) = 1.

* Worksheet zeilenweise durchlaufen
      WHILE lv_row <= lv_max_row.
* Spaltennummer (1) in Excel-Spalten-Bezeichner (A) umwandeln
        DATA(lv_col_str) = zcl_excel_common=>convert_column2alpha( 1 ).

* Zellinhalt Spalte 1 holen
        o_worksheet->get_cell( EXPORTING
                                 ip_column = lv_col_str
                                 ip_row    = lv_row
                               IMPORTING
                                 ep_value  = DATA(lv_value)
                             ).

* Spaltennummer (2) in Excel-Spalten-Bezeichner (B) umwandeln
        DATA(lv_col_str2) = zcl_excel_common=>convert_column2alpha( 2 ).
* Zellinhalt Spalte 2 holen
        o_worksheet->get_cell( EXPORTING
                                 ip_column = lv_col_str2
                                 ip_row    = lv_row
                               IMPORTING
                                 ep_value  = DATA(lv_value2)
                             ).

* Werte an interne Tabelle anfügen
        APPEND VALUE #(
                        col1 = lv_value
                        col2 = lv_value2
                      ) TO it_xl.

        lv_row = lv_row + 1.
      ENDWHILE.

* Daten in SALV-Grid anzeigen
      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_xl ).

* 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( |Excel-Werte ({ lines( it_xl ) })| ).
          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( || ).
            o_col->set_long_text( |{ o_col->get_columnname( ) } [{ o_col->get_long_text( ) }]| ).
          ENDLOOP.

          o_salv->display( ).
        CATCH cx_root INTO DATA(e_txt).
          WRITE: / e_txt->get_text( ).
      ENDTRY.
    CATCH cx_root INTO DATA(ex).    " Exceptions for ABAP2XLSX
      WRITE: / ex->get_text( ).
      WRITE: / ex->get_longtext( ).
  ENDTRY.

[ABAP] SAP-Suchhilfe verwenden

Beispiel 1 (MATCHCODE OBJECT)

* Suchhilfen anlegen, ändern: SE11

* Tabellen
*
* DD30L - Suchhilfen
* DD30T - Texte zu Suchhilfen
* DD33S - Zuordnung von Suchhilfefeldern

* MATCHCODE OBJECT verknüpft das Eingabefeld des Parameters mit einer Suchhilfe aus dem ABAP Dictionary
* Beispiel: Suchhilfe /iwbep/sh_ddshlp_elem sucht nach Suchhilfen :)
PARAMETERS: p_dd03l TYPE shlpname MATCHCODE OBJECT /iwbep/sh_ddshlp_elem.

Beispiel 2 (Suche von Suchhilfen zu einer Tabelle in der Tabelle DD30L)

* Parameterwert für Tabellenname, um Suchhilfen zu einer Tabelle zu ermitteln
PARAMETERS: p_table TYPE selmethod DEFAULT 'USR02'.

START-OF-SELECTION.

  SELECT l~shlpname,
         l~as4local,
         l~selmethod,
         t~ddtext
    INTO TABLE @DATA(it_dd30l)
    FROM dd30l AS l
    INNER JOIN dd30t AS t ON l~shlpname = t~shlpname
    WHERE t~ddlanguage = @sy-langu
      AND l~selmethod = @p_table.

  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_dd30l ).

*   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( |Suchhilfen zur Tabelle { p_table }| ).
        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
        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( || ).
          o_col->set_long_text( |{ o_col->get_columnname( ) } [{ o_col->get_long_text( ) }]| ).
        ENDLOOP.

        o_salv->display( ).
      CATCH cx_root INTO DATA(e_txt).
        WRITE: / e_txt->get_text( ).
    ENDTRY.
  ENDIF.

[ABAP] Informationen zu Business Objekten anzeigen

* Transaktion SWO1

DATA: lv_objtyp TYPE swo_objtyp.
DATA: lv_stext TYPE swc_shtext.

SELECT-OPTIONS: so_objtp FOR lv_objtyp.
SELECT-OPTIONS: so_stext FOR lv_stext.
*PARAMETERS: p_spras type sy-langu DEFAULT 'E'.

INITIALIZATION.

  so_objtp[] = VALUE #( ( sign = 'I' option = 'EQ' low = 'BUS2012' high = '' ) ).
  so_stext[] = VALUE #( ( sign = 'I' option = 'CP' low = 'Bestellung*' high = '' )
                        ( sign = 'I' option = 'CP' low = 'Eink*' high = '' ) ).

START-OF-SELECTION.

  SELECT FROM tojtb AS tb
    INNER JOIN tojtt AS tt ON tb~name = tt~name
    FIELDS tb~name,
           tb~editelem,
           tt~ntext,
           tt~stext
    WHERE tb~name IN @so_objtp
*      AND tb~activelang = @p_spras
*      AND tt~language = @p_spras
    INTO TABLE @DATA(it_tojtb).

  IF sy-subrc = 0.

    SELECT dv~objtype,   " BO Typ
           dv~verb,      " Funktion
           dv~verbtype,  " Funktionstyp ( ' ' =   Kein Verb, K = Schlüsselfeld, A = Attribut, M = Methode, E = Ereignis )
           dv~editelem,  " Element
           dv~refstruct, " Tabelle
           dv~reffield,  " Bezugsfeld
           dv~abapname,  " Funktionsbaustein
           tv~descript,  " Beschreibung
           tv~shorttext  " Kurztext
      INTO TABLE @DATA(it_bor_info)
      FROM swotdv AS dv
      INNER JOIN swottv AS tv ON dv~objtype = tv~objtype AND dv~verb = tv~verb
      WHERE dv~objtype IN @so_objtp
*        AND tv~language = @p_spras
      AND tv~shorttext IN @so_stext.

    IF sy-subrc = 0.

      SORT: it_bor_info BY verbtype verb.

      TRY.
          DATA(lv_tojtb_name) = SWITCH #( lines( it_tojtb ) WHEN 0 THEN || ELSE it_tojtb[ 1 ]-name ).
          DATA(lv_tojtb_stext) = SWITCH #( lines( it_tojtb ) WHEN 0 THEN || ELSE it_tojtb[ 1 ]-stext ).

          lv_tojtb_name = SWITCH #( lines( so_objtp ) WHEN 0 THEN || ELSE |Objekttyp: { lv_tojtb_name }| ).
          lv_tojtb_stext = SWITCH #( lines( so_objtp ) WHEN 0 THEN |keine Selektion| ELSE lv_tojtb_stext ).

* 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_bor_info ).

* 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( |{ lv_tojtb_name } ({ lv_tojtb_stext })| ).
          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
          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( || ).
            o_col->set_long_text( |{ o_col->get_columnname( ) } [{ o_col->get_long_text( ) }]| ).
          ENDLOOP.

          o_salv->display( ).
        CATCH cx_root INTO DATA(e_txt).
          WRITE: / e_txt->get_text( ).
      ENDTRY.
    ENDIF.
  ENDIF.

[ABAP] IMG-Aktivität (Customizing-Punkt) zu einer Transaktion ermitteln

* Tabellen:
*  CUS_ACTEXT (Customizing Aktivität - zugeordnetes Erweiterungs-Objekt)
*  CUS_ACTH   (Customizing Aktivität - Kopfdaten)
*  CUS_ACTOBJ (Customizing Aktivität - Liste der Objekte)
*  CUS_ACTOBT (Customizing Aktivität - Liste der Objekte)
*  CUS_ACTT   (Texttabelle zu den Customizing Aktivitäten)

* TCode
PARAMETERS: p_tc TYPE tstc-tcode DEFAULT 'OMBT'.

START-OF-SELECTION.

  SELECT o~tcode,
         o~act_id,
         o~objectname,
         o~text AS etext,
         t~text,
         e~exit_name,
         e~impl_name,
         e~enhancement
    INTO TABLE @DATA(it_activities)
    FROM cus_actobt AS o
    INNER JOIN cus_acth AS h ON o~act_id = h~act_id
    INNER JOIN cus_actt AS t ON h~act_id = t~act_id
    LEFT OUTER JOIN cus_actext AS e ON o~act_id = e~act_id
    WHERE o~tcode = @p_tc
      AND o~spras = @sy-langu
      AND t~spras = @sy-langu.

  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_activities ).

* 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( 'IMG-Aktivitäten zur Transaktion' ).
      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
      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( || ).
        o_col->set_long_text( |{ o_col->get_columnname( ) } [{ o_col->get_long_text( ) }]| ).
      ENDLOOP.

      o_salv->display( ).
    CATCH cx_root INTO DATA(e_txt).
      WRITE: / e_txt->get_text( ).
  ENDTRY.

[ABAP] Abhängige Objekte in Transportaufträgen ermitteln

* Der Report sucht nach Objektabhängigkeiten in Transportaufträgen

* Tabellen:
*  E070 (Transportsystem: Header von Aufträgen/Aufgaben)
*  E07T (Transportsystem: Kurzbeschreibungen von Aufträgen/Aufgaben)
*  E070C (Transportsystem: Quell-/Zielmandant von Aufträgen/Aufgaben)
*  E071 (Transportsystem: Objekt-Einträge von Aufträgen/Aufgaben)
*  TADIR (Katalog der Repository-Objekte)
*  TPLOG (Logging der tp Aufrufe)

* https://www.berater-wiki.de/Transportauftrag
* https://www.berater-wiki.de/Access_Tabellenbeziehung_Transportauftrag/-Aufgabe
* http://sapyourself.com/2014/06/11/transporte-transporteur-ermitteln-und-analysieren-tabelle-tplog/

PARAMETERS: p_tr TYPE e070-trkorr DEFAULT 'XYZ'.

START-OF-SELECTION.

* TRFUNCTION
*  K  Workbench-Auftrag
*  W  Customizing-Auftrag
*  C  Umzug von Objekten ohne Paketwechsel
*  O  Umzug von Objekten mit Paketwechsel
*  E  Umzug eines kompletten Pakets
*  T  Transport von Kopien
*  S  Entwicklung/Korrektur
*  R  Reparatur
*  X  Unklassifizierte Aufgabe
*  Q  Customizing-Aufgabe
*  G  Stückliste für CTS-Projekt
*  M  Auftrag für Mandantentransport
*  P  Stückliste für Upgrade
*  D  Stückliste für Patch
*  F  Stückliste
*  L  Löschtransport
* TRSTATUS
*  D  Änderbar
*  L  Änderbar, geschützt
*  O  Freigabe gestartet
*  R  Freigegeben
*  N  Freigegeben (Importschutz für reparierte Objekte aktiv)
* KORRDEV
*  CUST  mandantenabhängiges Customizing
*  SYST  Repository, mandantenunabbhängige Objekte
* LOCKFLAG
*     nicht gesperrt
*  X  gesperrt
*  0  nicht importiert
*  1  importiert mit Fehler
*  2  erfolgreich importiert
*  3  erfolgreich aktiviert /After-Import-Methode ausgeführt
*  6  erfolgreich in Schattentabellen importiert
*  7  erfolgreich in neue Schattentabellen importiert
*  8  inaktiver Anteil erfolgreich importiert
  SELECT e~trkorr,      " Auftrag/Aufgabe
         e~trfunction,  " Typ des Auftrags/Aufgabe
         e~trstatus,    " Status des Auftrags/der Aufgabe
         e~tarsystem,   " Transportziel eines Auftrags
         e~korrdev,     " Kategorie des Auftrags/der Aufgabe
         e~as4user,     " Inhaber eines Auftrags oder einer Aufgabe
         e~as4date,     " Datum der letzten Änderung
         e~as4time,     " Uhrzeit der letzten Änderung
         e~strkorr,     " Übergeordneter Auftrag
         t~as4text,     " Kurzbeschreibung von Repository-Objekten
         c~client,      " Quellmandant eines Auftrags
         c~tarclient,   " Zielmandant eines Auftrags
         o~as4pos,      " Dictionary: Zeilenposition
         o~pgmid,       " Programm-ID in Aufträgen und Aufgaben
         o~object,      " Objekttyp
         o~obj_name,    " Objektname in der Objektliste
         o~objfunc,     " Objektfunktion
         o~lockflag,    " Sperrstatus oder Importstatus zu einem Objekteintrag
         o~activity     " Aktivität, mit der Eintrag in Objektliste geschrieben wurde
    INTO TABLE @DATA(it_e070)
    FROM e070 AS e                                    " Transportsystem: Header von Aufträgen/Aufgaben
    INNER JOIN e07t AS t ON e~trkorr = t~trkorr       " Transportsystem: Kurzbeschreibungen von Aufträgen/Aufgaben
    INNER JOIN e070c AS c ON e~trkorr = c~trkorr      " Transportsystem: Quell-/Zielmandant von Aufträgen/Aufgaben
    LEFT OUTER JOIN e071 AS o ON e~trkorr = o~trkorr  " Transportsystem: Objekt-Einträge von Aufträgen/Aufgaben
    WHERE e~trkorr  = @p_tr
       OR e~strkorr = @p_tr
      AND t~langu   = @sy-langu.

  IF sy-subrc = 0.
* sortieren nach Auftrag und Datum / Uhrzeit
    SORT: it_e070 BY trkorr as4date as4time.

    SELECT *
      INTO TABLE @DATA(it_e071)
      FROM e071
      FOR ALL ENTRIES IN @it_e070
      WHERE object   = @it_e070-object
        AND obj_name = @it_e070-obj_name
        AND objfunc  = @it_e070-objfunc.

    IF sy-subrc = 0.

      DATA: o_salv TYPE REF TO cl_salv_table.

      cl_salv_table=>factory( EXPORTING
                                r_container  = cl_gui_container=>default_screen
                              IMPORTING
                                r_salv_table = o_salv
                              CHANGING
                                t_table      = it_e071 ).

      o_salv->get_functions( )->set_all( abap_true ).
      o_salv->get_columns( )->set_optimize( abap_true ).
      o_salv->get_display_settings( )->set_list_header( 'Abhängige Transporte / Aufgaben' ).
      o_salv->get_display_settings( )->set_striped_pattern( abap_true ).
      o_salv->get_selections( )->set_selection_mode( if_salv_c_selection_mode=>row_column ).

      LOOP AT o_salv->get_columns( )->get( ) ASSIGNING FIELD-SYMBOL(<c>).
        <c>-r_column->set_short_text( '' ).
        <c>-r_column->set_medium_text( '' ).
        <c>-r_column->set_long_text( |{ <c>-r_column->get_columnname( ) } [{ <c>-r_column->get_long_text( ) }]| ).
      ENDLOOP.

      o_salv->display( ).

      WRITE: space.

    ENDIF.

  ENDIF.