Dynamische Programmierung (ABAP): Unterschied zwischen den Versionen

Aus MattWiki
Keine Bearbeitungszusammenfassung
 
(13 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
Nachfolgend sind verschiedene Ausprägungen dynamischer Programmierung beschrieben.
Nachfolgend sind verschiedene Ausprägungen dynamischer Programmierung beschrieben.
Für Definition von Field-Symbols zur Datenspeicherung und zum Abrufen von Daten aus untypisierten Variablen siehe [[Field-Symbols (ABAP)]]
Lesen eines InfoProviders: [[InfoProvider lesen (ABAP)]]


== Feldsymbole und Datenrefs ==
== Feldsymbole und Datenrefs ==
Zeile 6: Zeile 10:
REPORT zmattdynprogwa.
REPORT zmattdynprogwa.


DATA: lv_table_name TYPE string VALUE 'SCARR'.
DATA: gv_table_name TYPE string VALUE 'SCARR'.


" Datenreferenz erstellen. Diese kann auf einen typisierten oder
" Datenreferenz erstellen. Diese kann auf einen typisierten oder
" untypisierten Datenspeicher zeigen. Hier: untypisiert.
" untypisierten Datenspeicher zeigen. Hier: untypisiert.
DATA: lr_table_line TYPE REF TO data.
DATA: gr_table_line TYPE REF TO data.


" Generisches Feldsymbol ohne initiale Typisierung
" Generisches Feldsymbol ohne Typisierung
FIELD-SYMBOLS: <ls_table_line> TYPE any.
FIELD-SYMBOLS: <gs_table_line> TYPE any.


" Reservieren von Hauptspeicher passend zum Typ der Datenreferenz.
" Reservieren von Hauptspeicher passend zum Typ der Datenreferenz.
CREATE DATA lr_table_line TYPE (lv_table_name).
CREATE DATA gr_table_line TYPE (gv_table_name).


" Da das Feldsymbol vom Type Any ist, muss im Assign der Zusatz
" Da das Feldsymbol vom Type Any ist, muss im Assign der Zusatz
" Casting Type eingefügt werden, der das Feldsymbol typisiert.
" Casting Type eingefügt werden, der das Feldsymbol typisiert.
ASSIGN lr_table_line->* TO <ls_table_line> CASTING TYPE (lv_table_name).
ASSIGN gr_table_line->* TO <gs_table_line> CASTING TYPE (gv_table_name).


" SELECT SINGLE gibt genau eine Zeile für eine Struktur zurück
" SELECT SINGLE gibt genau eine Zeile für eine Struktur zurück
SELECT SINGLE * FROM (lv_table_name) INTO <ls_table_line>
SELECT SINGLE * FROM (gv_table_name) INTO <gs_table_line>
   WHERE mandt = '001' AND carrid = 'BA'.
   WHERE mandt = '001' AND carrid = 'BA'.


WRITE <ls_table_line>.
WRITE <gs_table_line>.
</syntaxhighlight>
</syntaxhighlight>


Zeile 37: Zeile 41:


" Untypisierte Datenreferenz
" Untypisierte Datenreferenz
DATA: lr_table TYPE REF TO data.
DATA: gr_table TYPE REF TO data.


" Generisches Feldsymbol für interne Tabelle
" Generisches Feldsymbol für interne Tabelle
FIELD-SYMBOLS: <lt_table> TYPE table.
FIELD-SYMBOLS: <gt_table> TYPE table.


" Reservieren von Hauptspeicher für eine interne
" Reservieren von Hauptspeicher für eine interne
" Tabelle passend zum Typ der Datenreferenz.
" Tabelle passend zum Typ der Datenreferenz.
CREATE DATA lr_table TYPE TABLE OF (pa_tab).
CREATE DATA gr_table TYPE TABLE OF (pa_tab).


ASSIGN lr_table->* TO <lt_table>.
ASSIGN gr_table->* TO <gt_table>.


SELECT * FROM (pa_tab) INTO TABLE <lt_table>.
SELECT * FROM (pa_tab) INTO TABLE <gt_table>.
</syntaxhighlight>
</syntaxhighlight>
Ausgabe der internen Tabelle z.B. mit einem [[ALV-Control_(ABAP)|ALV-Control]].
Ausgabe der internen Tabelle z.B. mit einem [[ALV-Control_(ABAP)|ALV-Control]].
Zeile 69: Zeile 73:
" Objektreferenz für Tabellenbeschreibung
" Objektreferenz für Tabellenbeschreibung
" Untypisierte Datenreferenz ohne Speicherplatzreservierung
" Untypisierte Datenreferenz ohne Speicherplatzreservierung
DATA: lo_struct TYPE REF TO cl_abap_structdescr,
DATA: go_struct TYPE REF TO cl_abap_structdescr,
       lo_table TYPE REF TO cl_abap_tabledescr,
       go_table TYPE REF TO cl_abap_tabledescr,
       lr_table TYPE REF TO data.
       gr_table TYPE REF TO data.


" Generisches Feldsymbol für interne Tabelle
" Generisches Feldsymbol für interne Tabelle
FIELD-SYMBOLS: <lt_table> TYPE table.
FIELD-SYMBOLS: <gt_table> TYPE table.


" RTTS: Erzeugung der Struktur des Zeilentypobjekts basierend
" RTTS: Erzeugung der Struktur des Zeilentypobjekts basierend
lo_struct ?= cl_abap_structdescr=>describe_by_name( pa_tab ).
go_struct ?= cl_abap_structdescr=>describe_by_name( pa_tab ).


" RTTS: Erzeugung einer internen Tabelle / Tabellentypobjekt
" RTTS: Erzeugung einer internen Tabelle / Tabellentypobjekt
" basierend auf dem Zeilentypobjekt
" basierend auf dem Zeilentypobjekt
lo_table = cl_abap_tabledescr=>create( lo_struct ).
go_table = cl_abap_tabledescr=>create( go_struct ).


" Reservieren von Hauptspeicher passend zum Typ der Datenreferenz.
" Reservieren von Hauptspeicher passend zum Typ der Datenreferenz.
" TYPE HANDLE ermöglicht die Typisierung der Datenreferenz mit
" TYPE HANDLE ermöglicht die Typisierung der Datenreferenz mit
" einem dynamisch erzeugten Typ.
" einem dynamisch erzeugten Typ.
CREATE DATA lr_table TYPE HANDLE lo_table.
CREATE DATA gr_table TYPE HANDLE go_table.


ASSIGN lr_table->* TO <lt_table>.
ASSIGN gr_table->* TO <gt_table>.


SELECT * FROM (pa_tab) INTO TABLE <lt_table>.
SELECT * FROM (pa_tab) INTO TABLE <gt_table>.
</syntaxhighlight>
</syntaxhighlight>
Ausgabe der internen Tabelle z.B. mit einem [[ALV-Control_(ABAP)|ALV-Control]].
Ausgabe der internen Tabelle z.B. mit einem [[ALV-Control_(ABAP)|ALV-Control]].


== Dynamische Tokens ==
== Dynamische Tokens ==
=== Dynamisches Feld ===
{| class="wikitable"
!Ausdruck
!Beschreibung
|-
|ASSIGN (feld-token) TO ...
|Feld-Token für Angabe der Referenz
|-
|SELECT (feld-token) FROM (dbtab) ...
|Feld-Token aus Datenbanktabelle lesen
|-
|DELETE (feld-token) FROM (dbtab) ...
|s.o.
|-
|MODIFY (dbtab) ...
|s.o.
|-
|UPDATE (dbtab) ...
|s.o.
|}
=== Dynamischer Typ ===
=== Dynamischer Typ ===
{| class="wikitable"
{| class="wikitable"
Zeile 132: Zeile 115:
REPORT zmattdynprogcomp.
REPORT zmattdynprogcomp.


DATA: lt_sflight TYPE TABLE OF sflight,
DATA: gt_sflight TYPE TABLE OF sflight,
       ls_sflight LIKE LINE OF lt_sflight,
       gs_sflight LIKE LINE OF gt_sflight,
       lv_stru_comp TYPE string VALUE 'FLDATE'.
       gv_stru_comp TYPE string VALUE 'FLDATE'.


FIELD-SYMBOLS: <ls_stru_comp> TYPE any.
FIELD-SYMBOLS: <gs_stru_comp> TYPE any.


SELECT * FROM sflight INTO TABLE lt_sflight UP TO 10 ROWS.
SELECT * FROM sflight INTO TABLE gt_sflight UP TO 10 ROWS.


LOOP AT lt_sflight INTO ls_sflight.
LOOP AT gt_sflight INTO gs_sflight.
   " Aus Struktur die Komponente lv_stru_comp lesen und Feldsymbol zuweisen.
   " Aus Struktur die Komponente lv_stru_comp lesen und Feldsymbol zuweisen.
   ASSIGN COMPONENT lv_stru_comp OF STRUCTURE ls_sflight TO <ls_stru_comp>.
   ASSIGN COMPONENT gv_stru_comp OF STRUCTURE gs_sflight TO <gs_stru_comp>.
   WRITE: <ls_stru_comp>.
   WRITE: <gs_stru_comp>.
ENDLOOP.
ENDLOOP.
</syntaxhighlight>
=== Dynamische Feldliste / Dynamische Bedingung ===
{| class="wikitable"
!Ausdruck
!Beschreibung
|-
|SELECT (feldliste) FROM ...
|Liste von Spalten, die aus der Datenbanktabelle geholt werden sollen
|-
|SELECT * FROM dbtab WHERE (Bedingungen-Liste)...
|Dynamische Liste von Bedingungen
|}
<syntaxhighlight lang="abap">
REPORT zmattdynprogitabcol.
" Benutzereingabe: Ein oder mehrere Felder mit Leerzeichen getrennt.
PARAMETERS: pa_token TYPE c LENGTH 70.
DATA: gr_cx TYPE REF TO cx_root,
      gt_fields TYPE stringtab,
      gt_sbook TYPE TABLE OF sbook,
      gv_message TYPE string.
" Liste mit Spaltennamen erstellen
APPEND pa_token TO gt_fields.
TRY.
    SELECT (gt_fields)
      FROM sbook
      INTO CORRESPONDING FIELDS OF TABLE gt_sbook.
    WRITE: / 'Insgesamt ', sy-dbcnt, ' Einträge gefunden'.
  CATCH cx_sy_dynamic_osql_semantics cx_sy_open_sql_db
    INTO gr_cx.
    gv_message = gr_cx->get_text( ).
    MESSAGE gv_message TYPE 'E'.
ENDTRY.
</syntaxhighlight>
</syntaxhighlight>


[[Category:ABAP]]
[[Category:ABAP]]

Aktuelle Version vom 24. Juli 2019, 12:12 Uhr

Nachfolgend sind verschiedene Ausprägungen dynamischer Programmierung beschrieben.

Für Definition von Field-Symbols zur Datenspeicherung und zum Abrufen von Daten aus untypisierten Variablen siehe Field-Symbols (ABAP)

Lesen eines InfoProviders: InfoProvider lesen (ABAP)

Feldsymbole und Datenrefs

Dynamisch festgelegte Struktur

REPORT zmattdynprogwa.

DATA: gv_table_name TYPE string VALUE 'SCARR'.

" Datenreferenz erstellen. Diese kann auf einen typisierten oder
" untypisierten Datenspeicher zeigen. Hier: untypisiert.
DATA: gr_table_line TYPE REF TO data.

" Generisches Feldsymbol ohne Typisierung
FIELD-SYMBOLS: <gs_table_line> TYPE any.

" Reservieren von Hauptspeicher passend zum Typ der Datenreferenz.
CREATE DATA gr_table_line TYPE (gv_table_name).

" Da das Feldsymbol vom Type Any ist, muss im Assign der Zusatz
" Casting Type eingefügt werden, der das Feldsymbol typisiert.
ASSIGN gr_table_line->* TO <gs_table_line> CASTING TYPE (gv_table_name).

" SELECT SINGLE gibt genau eine Zeile für eine Struktur zurück
SELECT SINGLE * FROM (gv_table_name) INTO <gs_table_line>
  WHERE mandt = '001' AND carrid = 'BA'.

WRITE <gs_table_line>.

Dynamisch festgelegte interne Tabelle

REPORT zmattdynprogitab.

PARAMETERS: pa_tab TYPE string.

" Untypisierte Datenreferenz
DATA: gr_table TYPE REF TO data.

" Generisches Feldsymbol für interne Tabelle
FIELD-SYMBOLS: <gt_table> TYPE table.

" Reservieren von Hauptspeicher für eine interne
" Tabelle passend zum Typ der Datenreferenz.
CREATE DATA gr_table TYPE TABLE OF (pa_tab).

ASSIGN gr_table->* TO <gt_table>.

SELECT * FROM (pa_tab) INTO TABLE <gt_table>.

Ausgabe der internen Tabelle z.B. mit einem ALV-Control.

RTTS / RTTI / RTTC

RTTS: Runtime Type Services → Bieten Services für RTTI und RTTC

RTTI: Runtime Type Identification → Typen von Variablen zur Laufzeit beschreiben

RTTC: Runtime Type Creation → Typen von Variablen zur Lautzeit erzeugen

Beispiel:

REPORT zmattdynprogitab2.

PARAMETERS: pa_tab TYPE string.

" Objektreferenz für Beschreibung des Zeilentyps per Strukturtyp
" Objektreferenz für Tabellenbeschreibung
" Untypisierte Datenreferenz ohne Speicherplatzreservierung
DATA: go_struct TYPE REF TO cl_abap_structdescr,
      go_table TYPE REF TO cl_abap_tabledescr,
      gr_table TYPE REF TO data.

" Generisches Feldsymbol für interne Tabelle
FIELD-SYMBOLS: <gt_table> TYPE table.

" RTTS: Erzeugung der Struktur des Zeilentypobjekts basierend
go_struct ?= cl_abap_structdescr=>describe_by_name( pa_tab ).

" RTTS: Erzeugung einer internen Tabelle / Tabellentypobjekt
" basierend auf dem Zeilentypobjekt
go_table = cl_abap_tabledescr=>create( go_struct ).

" Reservieren von Hauptspeicher passend zum Typ der Datenreferenz.
" TYPE HANDLE ermöglicht die Typisierung der Datenreferenz mit
" einem dynamisch erzeugten Typ.
CREATE DATA gr_table TYPE HANDLE go_table.

ASSIGN gr_table->* TO <gt_table>.

SELECT * FROM (pa_tab) INTO TABLE <gt_table>.

Ausgabe der internen Tabelle z.B. mit einem ALV-Control.

Dynamische Tokens

Dynamischer Typ

Ausdruck Beschreibung
ASSIGN ... CASTING TYPE (typ) Bei der Zuweisung einer Variable zu einem Feldsymbol kann der Typ mit einem Token angegeben werden.
CREATE DATA ... TYPE (typ-token) Typ der Datenreferenz angegeben als Token.

Dynamische Komponente

REPORT zmattdynprogcomp.

DATA: gt_sflight TYPE TABLE OF sflight,
      gs_sflight LIKE LINE OF gt_sflight,
      gv_stru_comp TYPE string VALUE 'FLDATE'.

FIELD-SYMBOLS: <gs_stru_comp> TYPE any.

SELECT * FROM sflight INTO TABLE gt_sflight UP TO 10 ROWS.

LOOP AT gt_sflight INTO gs_sflight.
  " Aus Struktur die Komponente lv_stru_comp lesen und Feldsymbol zuweisen.
  ASSIGN COMPONENT gv_stru_comp OF STRUCTURE gs_sflight TO <gs_stru_comp>.
  WRITE: <gs_stru_comp>.
ENDLOOP.

Dynamische Feldliste / Dynamische Bedingung

Ausdruck Beschreibung
SELECT (feldliste) FROM ... Liste von Spalten, die aus der Datenbanktabelle geholt werden sollen
SELECT * FROM dbtab WHERE (Bedingungen-Liste)... Dynamische Liste von Bedingungen
REPORT zmattdynprogitabcol.

" Benutzereingabe: Ein oder mehrere Felder mit Leerzeichen getrennt.
PARAMETERS: pa_token TYPE c LENGTH 70.

DATA: gr_cx TYPE REF TO cx_root,
      gt_fields TYPE stringtab,
      gt_sbook TYPE TABLE OF sbook,
      gv_message TYPE string.

" Liste mit Spaltennamen erstellen
APPEND pa_token TO gt_fields.

TRY.
    SELECT (gt_fields)
      FROM sbook
      INTO CORRESPONDING FIELDS OF TABLE gt_sbook.
    WRITE: / 'Insgesamt ', sy-dbcnt, ' Einträge gefunden'.
  CATCH cx_sy_dynamic_osql_semantics cx_sy_open_sql_db
    INTO gr_cx.

    gv_message = gr_cx->get_text( ).
    MESSAGE gv_message TYPE 'E'.
ENDTRY.