[ABAP] Dynamisches Selektionsbild erstellen

DATA: lv_tablename TYPE string VALUE 'SPFLI'.       " Tabelle, die ausgelesen werden soll

DATA: lv_selection_id TYPE rsdynsel-selid.          " Selection-ID zur Unterscheidung mehrerer Sets
DATA: lv_number_of_fields TYPE i.                   " Anzahl der Felder

DATA: it_expressions TYPE rsds_texpr.               " Expressions
DATA: it_field_ranges TYPE rsds_trange.             " Ranges
DATA: it_tables TYPE STANDARD TABLE OF rsdstabs.    " Init: Tabellen
DATA: it_fields TYPE STANDARD TABLE OF rsdsfields.  " Init: Felder
DATA: it_where_clauses TYPE rsds_twhere.            " Daten für Where-Tabelle

INITIALIZATION.
* Tabelle hinzufügen
  it_tables = VALUE #( ( prim_tab = lv_tablename ) ).

* freien Selektionsbildschirm initialisieren
  CALL FUNCTION 'FREE_SELECTIONS_INIT'
    EXPORTING
      kind                     = 'T' " T: TABLES_TAB G: FIELD_GROUPS_KEY, F: FIELDS_TAB
      expressions              = it_expressions
*      field_groups_key         =
    IMPORTING
      selection_id             = lv_selection_id
      field_ranges             = it_field_ranges
    TABLES
      tables_tab               = it_tables
      fields_tab               = it_fields
    EXCEPTIONS
      fields_incomplete        = 1
      fields_no_join           = 2
      field_not_found          = 3
      no_tables                = 4
      table_not_found          = 5
      expression_not_supported = 6
      incorrect_expression     = 7
      illegal_kind             = 8
      area_not_found           = 9
      inconsistent_area        = 10
      kind_f_no_fields_left    = 11
      kind_f_no_fields         = 12
      too_many_fields          = 13
      dup_field                = 14
      field_no_type            = 15
      field_ill_type           = 16
      dup_event_field          = 17
      node_not_in_ldb          = 18
      area_no_field            = 19
      OTHERS                   = 20.

  IF sy-subrc = 0.
* freien Selektionsbildschirm anzeigen
    CALL FUNCTION 'FREE_SELECTIONS_DIALOG'
      EXPORTING
        selection_id            = lv_selection_id
        title                   = 'Beispielselektion'
        frame_text              = 'Bitte auswählen'
        status                  = 1                 " normaler Selektionsmodus
        as_window               = abap_false        " abap_true -> als Fenster anzeigen
        no_intervals            = abap_true         " keine Intervalle im Selektionsbild anzeigen, kann über Button "Intervalle" geändert werden
      IMPORTING
        where_clauses           = it_where_clauses
        expressions             = it_expressions
        field_ranges            = it_field_ranges
        number_of_active_fields = lv_number_of_fields
      TABLES
        fields_tab              = it_fields
      EXCEPTIONS
        internal_error          = 1
        no_action               = 2
        selid_not_found         = 3
        illegal_status          = 4
        OTHERS                  = 5.

    IF sy-subrc = 0.
      TRY.
* Daten ausgeben
          DATA: o_it TYPE REF TO data.
          DATA: o_row TYPE REF TO data.
          FIELD-SYMBOLS: <fs_table> TYPE ANY TABLE. " Feldsymbol für Arbeit mit Tabelle
          FIELD-SYMBOLS: <fs_row> TYPE any.         " Feldsymbol für Arbeit mit Zeile

* dynamische Tabelle vom Typ lv_tablename erzeugen
          CREATE DATA o_it TYPE STANDARD TABLE OF (lv_tablename).
* Feldsymbol auf die dynamische Tabelle anlegen
          ASSIGN o_it->* TO <fs_table>.

          IF <fs_table> IS ASSIGNED.
* dynamische Workarea vom Typ der Tabellenzeile erzeugen
            CREATE DATA o_row LIKE LINE OF <fs_table>.
* Feldsymbol auf die Workarea anlegen
            ASSIGN o_row->* TO <fs_row>.

            IF <fs_row> IS ASSIGNED.

              IF lines( it_where_clauses ) > 0.
                DATA(ls_where_clause) = it_where_clauses[ tablename = lv_tablename ].
                SELECT * FROM (lv_tablename) INTO TABLE <fs_table> WHERE (ls_where_clause-where_tab).
              ELSE.
                SELECT * FROM (lv_tablename) INTO TABLE <fs_table>.
              ENDIF.

              IF sy-subrc = 0.
* herausfinden, wieviele Spalten die Tabelle hat
                DATA(o_struct) = CAST cl_abap_structdescr( cl_abap_typedescr=>describe_by_data( <fs_row> ) ).
                DATA(it_comp) = o_struct->get_components( ).

* alle Datensätze der Tabelle durchgehen
                LOOP AT <fs_table> INTO <fs_row>.

* spaltenweise jeden Datansatz durchgehen
                  LOOP AT it_comp ASSIGNING FIELD-SYMBOL(<fs_col>).
* den Inhalt der Strukturkomponente (Zeile) ausgeben
                    ASSIGN COMPONENT <fs_col>-name OF STRUCTURE <fs_row> TO FIELD-SYMBOL(<fs_cell>).

                    IF <fs_cell> IS ASSIGNED.
                      WRITE: <fs_cell>.
                    ENDIF.
                  ENDLOOP.

                  NEW-LINE.

                ENDLOOP.
              ELSE.
                WRITE: / 'Keine Daten verfügbar.'.
              ENDIF.
            ENDIF.
          ENDIF.
        CATCH cx_root INTO DATA(e_text).
          MESSAGE e_text->get_text( ) TYPE 'S' DISPLAY LIKE 'E'.
      ENDTRY.
    ENDIF.
  ENDIF.

Links