[ABAP] RANGES

Ein RANGE definiert eine spezielle interne Tabelle vom Typ STANDARD TABLE mit Header Line zur Abbildung von Intervallen (z.B. für SELECT-OPTIONS und WHERE … IN).
Die Definition von RANGES an sich ist obsolet.

Weiterführende Infos: Link und Link

Tabellenfelder einer RANGE-Tabelle

  • SIGN (Bereichabgrenzung)
    • Typ: DDSIGN
    • Domäne: DDSIGN
    • Werte
      • I Bereichsabgrenzung eingeschlossen (Inclusive)
      • E Bereichsabgrenzung ausgeschlossen (Exclusive)
  • OPTION (Optionen)
    • Typ: DDOPTION
    • Domäne: DDOPTION
    • Werte
      • EQ gleich
      • BT zwischen … und …
      • CP enthält das Template
      • LE kleiner oder gleich
      • GE größer oder gleich
      • NE ungleich
      • NB nicht zwischen … und …
      • NP enthält das Template nicht
      • GT größer
      • LT kleiner
  • LOW (niedrigster Wert des Intervalls)
    • Typ: C
    • Länge: 1…n (abh. vom Such-Datentyp)
  • HIGH (höchster Wert des Intervalls)
    • Typ: C
    • Länge: 1…n (abh. vom Such-Datentyp)
      (leer, wenn z.B. OPTION = EQ)

DDIC-Zeilentypen, die RANGEs abbilden

* SELOPT
* RSDSSELOPT
* RSIS_S_RANGE

DDIC-Tabellentypen, die RANGEs abbilden

* RSELOPTION
* CMS_TAB_BII_CAG_TYP_RNG
* FIWTIN_T_SELOPT
* PIQ_SELOPT_T
* PSI_WE_SELOPT_TT

Hilfsklasse mit Konstanten für die Selektionstabellen bzw. Ranges-Tabellen

IF_FSBP_CONST_RANGE (Konstanten für die Selektionstabellen bzw. Ranges-Tabellen)

* OPTION_BETWEEN		'BT'
* OPTION_CONTAINS_PATTERN	'CP'
* OPTION_EQUAL			'EQ'
* OPTION_GREATER		'GT'
* OPTION_GREATER_EQUAL		'GE'
* OPTION_LESS			'LT'
* OPTION_LESS_EQUAL		'LE'
* OPTION_NOT_BETWEEN		'NB'
* OPTION_NOT_CONTAINS_PATTERN	'NP'
* OPTION_NOT_EQUAL		'NE'
* SIGN_EXCLUDE			'E'
* SIGN_INCLUDE			'I'

Beispiel 1 (Übergabe von RANGES (SELECT-OPTIONS) an Klassenmethoden)

REPORT zrange_demo.

* Klasse für Demo der Übergabe von RANGEs (SELECT-OPTIONS)
CLASS lcl_matnr DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      get_data
        IMPORTING
          i_it_matnr TYPE STANDARD TABLE. " RANGE (SELECT-OPTIONS) als STANDARD TABLE übergeben
ENDCLASS.

CLASS lcl_matnr IMPLEMENTATION.
  METHOD get_data.
    DATA: it_mara TYPE STANDARD TABLE OF mara WITH DEFAULT KEY.

* STANDARD TABLE im SQL verwenden
     SELECT * FROM mara INTO TABLE @it_mara
       WHERE matnr IN @i_it_matnr.

     ...

  ENDMETHOD.
ENDCLASS.

* SELECT-OPTIONS festlegen
DATA: lv_matnr TYPE mara-matnr.
* RANGE so_matnr für MATNR definieren
SELECT-OPTIONS: so_matnr FOR lv_matnr.

INITIALIZATION.
* RANGE so_matnr initialisieren
  so_matnr[] = VALUE #( ( sign   = 'I'
                          option = 'EQ'
                          low    = '0000012345'
                          high   = '' ) ).

START-OF-SELECTION.
* Datenbereich des RANGE so_matnr übergeben
  lcl_matnr=>get_data( i_it_matnr = so_matnr[] ).

Beispiel 2 (RANGE OF)

* erzeugt eine interne Tabelle vom Typ STANDARD TABLE mit Header Line mit den Datenfeldern
* SIGN (C(1)) | OPTION (C(2)) | LOW (C(10)) | HIGH (C(10))
DATA: it_kunnr TYPE RANGE OF kunnr.

Beispiel 3 (STANDARD TABLE)

TYPES: BEGIN OF ty_range,
         sign   TYPE ddsign,
         option TYPE ddoption,
         low    TYPE char18, " char18 für 18-stellige MATNR
         high   TYPE char18, " char18 für 18-stellige MATNR
       END OF ty_range.

* erzeugt eine interne Tabelle vom Typ STANDARD TABLE mit den Datenfeldern
* SIGN (C(1)) | OPTION (C(2)) | LOW (C(18)) | HIGH (C(18))
DATA: it_matnr TYPE STANDARD TABLE OF ty_range WITH DEFAULT KEY.

Beispiel 4 (STANDARD TABLE mit generischen DDIC-Strukturen)

DATA(rg_so_carrid) = VALUE rseloption( ( sign   = 'I'
                                         option = 'EQ'
                                         low    = 'AA'
                                         high   = '' ) ).

Beispiel 5 (Verwendung in OpenSQL-WHERE-Condition)

DATA(rg_carrid) = VALUE rseloption( ( sign = 'I' option = 'EQ' low = 'AA' high = '' )
                                    ( sign = 'I' option = 'EQ' low = 'LH' high = '' )
                                  ).

SELECT *
  INTO TABLE @DATA(it_sflight)
  FROM sflight
  WHERE carrid IN @rg_carrid.

cl_demo_output=>display( it_sflight ).

Beispiel 6 (Verwendung eines RANGESs zum Filtern von internen Tabellen)

* Liste mit Namen
DATA(it_names) = VALUE string_table( ( |Horst| ) ( |Heiner| ) ( |Ida| ) ( |Lotte| ) ( |Hanna| ) ).

* Range mit Suchbegriffen
DATA(rg_search) = VALUE rseloption( ( sign = 'I' option = 'EQ' low = 'Ida' high = '' )
                                    ( sign = 'I' option = 'EQ' low = 'Lotte' high = '' )
                                  ).

* Filtern der Liste mittels WHERE-Condition + RANGE
LOOP AT it_names ASSIGNING FIELD-SYMBOL(<n>) WHERE table_line IN rg_search.
  WRITE: / <n>.
ENDLOOP.

[ABAP] Daten aus einer internen Tabelle löschen

Typen & Daten

* Typen
TYPES : BEGIN OF ty_s_sflight,
          carrid   TYPE sflight-carrid,
          connid   TYPE sflight-connid,
          seatsmax TYPE sflight-seatsmax,
          flag     TYPE abap_bool,
        END OF ty_s_sflight.

TYPES: ty_it_sflight TYPE STANDARD TABLE OF ty_s_sflight WITH DEFAULT KEY.

* Daten
DATA(it_sflight) = VALUE ty_it_sflight( ).

* Select
SELECT carrid,
       connid,
       seatsmax,
       CASE WHEN seatsmax > 200 THEN @abap_true " CASE-Anweisung zum Setzen der Spalte "flag"
       END AS flag
  INTO TABLE @it_sflight
  FROM sflight.

Variante 1 (INDEX)

* Eintrag mit Index 1
DELETE it_sflight INDEX 1.

cl_demo_output=>display( it_sflight ).

Variante 2 (Struktur)

* Genau einen Eintrag entsprechend der Struktur
DELETE TABLE it_sflight FROM VALUE #( carrid = 'LH' connid = '400' seatsmax = 280 flag = abap_true ).

cl_demo_output=>display( it_sflight ).

Variante 3 (TABLE KEY)

* Einträge mit Primärschlüssel aus Tabelle löschen
DELETE TABLE it_sflight WITH TABLE KEY carrid = 'LH' connid = '400' flag = abap_true.

cl_demo_output=>display( it_sflight ).

Variante 4 (WHERE)

* Alle Einträge mit leerem flag löschen
DELETE it_sflight WHERE flag IS INITIAL.
* Alle Einträge innerhalb eines Bereiches löschen
DELETE it_sflight WHERE seatsmax > 200 AND seatsmax < 350.
* Alle Einträge die nicht der Bedingung entsprechen
DELETE it_sflight WHERE NOT carrid = 'AA'.

cl_demo_output=>display( it_sflight ).

Variante 5 (RANGE)

* alle Carrier, die nicht 'AA' sind aus der iTab löschen
DELETE it_sflight WHERE NOT carrid IN VALUE rseloption( ( sign   = 'I'
                                                          option = 'EQ'
                                                          low    = 'AA'
                                                          high   = '' ) ).

cl_demo_output=>display( it_sflight ).

Variante 6 (RANGE mit Pattern)

* Alle Einträge beginnend mit 'A' und 'L' löschen
DELETE it_sflight WHERE carrid IN VALUE rseloption( ( sign   = 'I'
                                                      option = 'CP'
                                                      low    = 'A*'
                                                      high   = '' )
                                                    ( sign   = 'I'
                                                      option = 'CP'
                                                      low    = 'L*'
                                                      high   = '' ) ).

cl_demo_output=>display( it_sflight ).

Variante 7 (RANGE leer)

* Achtung: löscht alle Einträge in it_sflight!
DELETE it_sflight WHERE carrid IN VALUE rseloption( ).

cl_demo_output=>display( it_sflight ).

Variante 8 (Pattern CP)

* alle Einträge, deren carrid mit 'L' beginnen
DELETE it_sflight WHERE carrid CP 'L*'.

cl_demo_output=>display( it_sflight ).

Variante 9 (dynamische WHERE-Condition)

* Stringtab mit WHERE-Conditions -> Leerzeichen beachten!
DATA(it_where) = VALUE stringtab(
                                  ( |testfehler = 'AA'| )
                                  ( |carrid EQ 'AA' AND connid CP '001*' | )
                                  ( |seatsmax > 300| )
                                ).

LOOP AT it_where ASSIGNING FIELD-SYMBOL(<w>).

  WRITE: / <w>.

  TRY.
* dynamische WHERE-Condition ausführen
* fehlerhafte WHERE-Conditions werfen eine Exception
      DELETE it_sflight WHERE (<w>).
    CATCH cx_root INTO DATA(e_txt).
      WRITE: / e_txt->get_text( ).
  ENDTRY.

ENDLOOP.

cl_demo_output=>display( it_sflight ).

Variante 10 (Pseudokomponente TABLE_LINE)

* Die Tabellenzeile mit der Struktur ty_s_sflight wird gelöscht
DELETE it_sflight WHERE table_line = VALUE ty_s_sflight( carrid = 'LH' connid = '400' seatsmax = 280 flag = abap_true ).

cl_demo_output=>display( it_sflight ).

Variante 11 (CO [Contains Only])

* Carrier darf nur Zeichen 'A' und/oder 'Z' und/oder ' ' enthalten
* -> löscht Einträge für 'AA ', 'AZ '
DELETE it_sflight WHERE carrid CO 'AZ '.

cl_demo_output=>display( it_sflight ).