und IF-Bedingungen

Werbung
ajanzen.com
Umgang mit zur Laufzeit erstellen
Selektions-, Sortier- und IF-Bedingungen
ajanzen.com
1 Einleitung
In dem vorliegenden Dokument möchte ich auf die Möglichkeiten des Erstellens
dynamischer Selektions-, Sortier- und IF-Bedingungen eingehen.
Das Beispielcoding aus Kapitel 3 liefert keine Datenausgabe. Die Wirkung der
einzelnen Anweisungen kann im Debugger gut nachverfolgt werden.
Das komplette Beispielcoding ist in Kapitel 3 enthalten. Nähere Informationen zum
Ablauf können Kapitel 2 entnommen werden.
1
ajanzen.com
2 Informationen zur Programmlogik
Zu Beginn des Beispielprogrammes werden Informationen aus Tabelle SPFLI ermittelt.
Die WHERE-Bedingung des Tabellenzugriffes wird in Form einer Variable vom Typ
String mitgegeben. Dabei wird gezeigt, wie Literale und Variablen in den Suchstring
eingebunden werden. Außerdem ist dem Coding auch das Vorgehen der dynamischen
Angabe von Tabellennamen für einen Datenbankzugriff zu entnehmen.
Nach dem SELECT wird auf den Einsatz einer dynamischen WHERE-Bedingung in
der LOOP-Anweisung eingegangen. Aus Gründen der Einfachheit kommt hier die
WHERE-Bedingung des Datenbankzugriffes zum Einsatz.
Das nächste Beispiel befasst sich mit dem dynamischen Erstellen einer
Sortieranweisung. Die einzelnen Sortierkriterien werden in Form einer Tabelle vom
Typ ABAP_SORTORDER_TAB mitgegeben.
Häufig wird in Zusammenhang mit dynamischen IF-Anweisungen nach folgender
Syntax gesucht: IF (BEDINGUNG). Soweit mir bekannt ist, funktioniert dieses
Vorgehen leider nicht. Die entsprechende Fragestellung kann jedoch recht einfach
durch den Einsatz von Ranges gelöst werden. In dem Beispielcoding werden zwei
Möglichkeiten der Range-Verwendung aufgezeigt. Die einfache Möglichkeit setzt auf
eine Range-Struktur für ein CHAR-Datenelement. Da in der IF-Bedingung keine
Prüfung auf Datentypkompatibilität stattfindet, können über diese Range-Struktur auch
Prüfungen auf Dezimalzahlen erfolgen.
Bei der etwas komplexeren Möglichkeit wird das Range-Objekt unter Verwendung des
zu vergleichenden Feldes zur Laufzeit erstellt. Das Vorgehen kann eingesetzt werden,
wenn die einfache Möglichkeit nicht ausreicht.
2
3 Coding
*--------------------------------------------------------------------*
* Das vorliegende Programm dient der Demonstration dynamisch
* zusammengestellter Bedingungen für SELECT-, LOOP-, SORT- und IF* Anweisungen
*
* Date: 11.04.2015
*--------------------------------------------------------------------*
* Änderungen
*--------------------------------------------------------------------*
REPORT
zaj_gen_sort_when_check.
DATA: gt_sflight
TYPE flighttab.
DATA: gs_sflight
TYPE sflight.
DATA: gv_where
TYPE string.
DATA: gv_table
TYPE string.
DATA: gv_carrid_dl
TYPE s_carr_id.
DATA: gt_sort_table
TYPE abap_sortorder_tab.
DATA: gs_sort_struct
TYPE abap_sortorder.
DATA: gr_err_dyn_sql
TYPE REF TO cx_sy_dynamic_osql_semantics.
DATA: gr_err_dyn_loop
TYPE REF TO cx_sy_itab_dyn_loop.
DATA: gt_err_ill_comp
TYPE REF TO cx_sy_dyn_table_ill_comp_val.
DATA: gv_err_msg
TYPE string.
DATA: gt_char_range
TYPE STANDARD TABLE OF etrange.
DATA: gs_char_range
TYPE etrange.
DATA: gt_comp
TYPE cl_abap_structdescr=>component_table.
DATA: gs_comp
TYPE cl_abap_structdescr=>component.
DATA: gr_struct_dscr
TYPE REF TO cl_abap_structdescr.
DATA: gr_table_dscr
TYPE REF TO cl_abap_tabledescr.
DATA: gr_err_table
TYPE REF TO cx_sy_table_creation.
DATA: gr_err_struct
TYPE REF TO cx_sy_struct_creation.
DATA: gr_range_tab
TYPE REF TO data.
FIELD-SYMBOLS: <gt_range_tab> TYPE ANY TABLE.
FIELD-SYMBOLS: <gs_range_str> TYPE any.
FIELD-SYMBOLS: <gv_value>
TYPE any.
START-OF-SELECTION.
***************************************************************************
****
* Datenselektion
***************************************************************************
****
* Selektionsbedingung zusammenstellen ... dabei können sowohl Variablen als
auch
* Literale eingebunden werden
MOVE 'DL' TO gv_carrid_dl.
MOVE 'CARRID EQ `AA` OR CARRID EQ `AZ` OR CARRID EQ gv_carrid_dl' TO
gv_where.
TRY .
* Datenselektion mit fest vorgegebenen Tabelle
SELECT *
FROM sflight
INTO CORRESPONDING FIELDS OF TABLE gt_sflight
WHERE (gv_where).
IF sy-subrc NE 0.
*
In diesem Fall wird eine leere Tabelle angezeigt
ENDIF.
* Datenselektion mit einer zur Laufzeit erstellten Tabelle
MOVE 'SFLIGHT' TO gv_table.
SELECT *
FROM (gv_table)
INTO CORRESPONDING FIELDS OF TABLE gt_sflight
WHERE (gv_where).
IF sy-subrc NE 0.
*
In diesem Fall wird eine leere Tabelle angezeigt
ENDIF.
CATCH cx_sy_dynamic_osql_semantics INTO gr_err_dyn_sql.
*
Um einen Kurzdump zu vermeiden, fangen wir die Ausnahme ab
gv_err_msg = gr_err_dyn_sql->get_text( ).
MESSAGE gv_err_msg TYPE 'S' DISPLAY LIKE 'E'.
RETURN.
ENDTRY.
***************************************************************************
****
* LOOP über Tabellenfelder
***************************************************************************
****
TRY .
* Die Vorgehensweise ist wie beim SELECT
LOOP AT gt_sflight INTO gs_sflight
WHERE (gv_where).
ENDLOOP.
CATCH cx_sy_itab_dyn_loop INTO gr_err_dyn_loop.
*
Um einen Kurzdump zu vermeiden, fangen wir die Ausnahme ab
gv_err_msg = gr_err_dyn_loop->get_text( ).
MESSAGE gv_err_msg TYPE 'S' DISPLAY LIKE 'E'.
RETURN.
ENDTRY.
***************************************************************************
****
* Sortieren von Daten
***************************************************************************
****
* Sortierbedingung zusammenstellen
MOVE abap_true TO gs_sort_struct-descending.
MOVE 'CONNID' TO
gs_sort_struct-name.
APPEND gs_sort_struct TO gt_sort_table.
MOVE abap_false TO gs_sort_struct-descending.
MOVE 'FLDATE' TO
gs_sort_struct-name.
APPEND gs_sort_struct TO gt_sort_table.
TRY .
* und das eigentliche Sortieren
SORT gt_sflight BY (gt_sort_table).
CATCH cx_sy_dyn_table_ill_comp_val INTO gt_err_ill_comp.
*
Um einen Kurzdump zu vermeiden, fangen wir die Ausnahme ab
gv_err_msg = gt_err_ill_comp->get_text( ).
MESSAGE gv_err_msg TYPE 'S' DISPLAY LIKE 'E'.
RETURN.
ENDTRY.
***************************************************************************
****
* Erstellen einer dynamischen IF-Bedingung ... der einfache Weg
***************************************************************************
****
* ... der relativ einfache Weg über eine CHAR-Range-Struktur
READ TABLE gt_sflight INTO gs_sflight INDEX 1.
* ... Range vorbereiten
MOVE 'I'
TO gs_char_range-sign.
MOVE 'EQ'
TO gs_char_range-option.
MOVE gs_sflight-paymentsum
TO gs_char_range-low.
APPEND gs_char_range TO gt_char_range.
IF gs_sflight-paymentsum IN gt_char_range.
WRITE: 'CHAR-Range funktionert'.
ENDIF.
***************************************************************************
****
* Erstellen einer dynamischen IF-Bedingung ... der komplexere aber
* dynamischere Weg
***************************************************************************
****
* Range-Struktur erstellen
gs_comp-name = 'SIGN'.
* Der Typ ist hier eine Instanz der Klasse CL_ABAP_ELEMDESCR
gs_comp-type ?= cl_abap_datadescr=>describe_by_name( 'DDSIGN' ).
APPEND gs_comp TO gt_comp.
gs_comp-name = 'OPTION'.
* Der Typ ist hier eine Instanz der Klasse CL_ABAP_ELEMDESCR
gs_comp-type ?= cl_abap_datadescr=>describe_by_name( 'DDOPTION' ).
APPEND gs_comp TO gt_comp.
gs_comp-name = 'LOW'.
* Der Typ ist hier eine Instanz der Klasse CL_ABAP_ELEMDESCR
gs_comp-type ?= cl_abap_datadescr=>describe_by_data( gs_sflightpaymentsum ).
APPEND gs_comp TO gt_comp.
gs_comp-name = 'HIGH'.
* Der Typ ist hier eine Instanz der Klasse CL_ABAP_ELEMDESCR
gs_comp-type ?= cl_abap_datadescr=>describe_by_data( gs_sflightpaymentsum ).
APPEND gs_comp TO gt_comp.
TRY.
* Strukturobjekt unter Verwendung der Komponententabelle erstellen
gr_struct_dscr = cl_abap_structdescr=>create( gt_comp ).
* Über das Strukturobjekt ein Tabellenobjekt erstellen
gr_table_dscr = cl_abap_tabledescr=>create( gr_struct_dscr ).
CATCH cx_sy_struct_creation INTO gr_err_struct.
gv_err_msg = gr_err_struct->get_text( ).
MESSAGE gv_err_msg TYPE 'S' DISPLAY LIKE 'E'.
RETURN.
CATCH cx_sy_table_creation INTO gr_err_table.
gv_err_msg = gr_err_table->get_text( ).
MESSAGE gv_err_msg TYPE 'S' DISPLAY LIKE 'E'.
RETURN.
ENDTRY.
* Range-Objekt unter Verwendung der Klasse erstellen
CREATE DATA gr_range_tab TYPE HANDLE gr_table_dscr.
* Range mit Werten füllen
ASSIGN gr_range_tab->* TO <gt_range_tab>.
INSERT INITIAL LINE INTO TABLE <gt_range_tab> ASSIGNING <gs_range_str>.
ASSIGN COMPONENT 'SIGN' OF STRUCTURE
MOVE 'I'
<gs_range_str> TO <gv_value>.
TO <gv_value>.
ASSIGN COMPONENT 'OPTION' OF STRUCTURE
<gs_range_str> TO <gv_value>.
MOVE 'EQ'
TO <gv_value>.
ASSIGN COMPONENT 'LOW' OF STRUCTURE
MOVE gs_sflight-paymentsum
<gs_range_str> TO <gv_value>.
TO <gv_value>.
IF gs_sflight-paymentsum IN <gt_range_tab>.
WRITE: /, 'DATA-Range funktioniert'.
ENDIF.
Herunterladen