Dynamische Tabellenstrukturen im ABAP

Die Frage ist als "gelöst" markiert. Den entsprechend Beitrag findest du hier.

Die Objektorientierung mit ABAP®: Vererbung, Dynamische Programmierung, GUI Controls (u.a. ALV im OO).
3 Beiträge • Seite 1 von 1
3 Beiträge Seite 1 von 1

Dynamische Tabellenstrukturen im ABAP

Beitrag von Uwe.Rimarski (ForumUser / 1 / 0 / 3 ) »
Hinweis: Quellcode siehe unten

Auf der Suche nach einer Möglichkeit eine dynamische Tabellenstruktur zu realisieren, habe ich mir echt einen „heißen“ gesucht. Ist schon erstaunlich was einige Kollegen da alles für „Dynamisch“ halten. :)
Hier ist nun endlich eine brauchbare Lösung für ein solches Problem.

Problembeschreibung:
Einlesen von Daten im ASCII Format mit fester Satzlänge. Die Strukturen stehen erst zur Laufzeit fest. Es gibt hierzu auf der SAP Seite weder ein DDICT Objekt dazu, noch ist es möglich eine interne Struktur zu hinterlegen, da sowohl die Daten, als auch die technische Feldbeschreibung der Struktur erst zu Laufzeit des Programms zur Verfügung stehen
Wenn die technische Feldbeschreibung vorliegt, um daraus dann Programm Interne Strukturen auf zu bauen, nennt man diesen Zeitpunkt „Design Zeit“ und nicht Laufzeit.
Somit währe dann ein Tabellenaufbau auch nicht mehr Dynamisch, oder sehr großzügig ausgedrückt: „Teildynamisch“


Gegeben:
Technische Feldbeschreibung der einzulesenden Daten als ASCII Datei zur Programmlaufzeit
Der Aufbau dieser Feldbeschreibung sieht folgendermaßen aus:
Technische Feldbeschreibung = TEC. In der folgenden Dokumentation werden die einzelnen Elemente dieser Struktur mit TEC- angesprochen. TEC-Feldname = Feldname in der technischen Beschreibung

Feldname
Feldtyp
Feldlength
Dezimals
Feldnr


Da stellt sich dann jetzt die frage: „Kleiner Mann, was nun ?“

Hier kommen jedoch die super coolen RTI Tools der SAP als Retter der Situation in spiel. Denn niemand möchte mehr gerne mit „Generate Report“ und ähnlich veralterte Werkzeuge arbeiten. Diese sind sicherlich damals Ihrer zeit weit voraus und toll gewesen, entsprechen aber nicht mehr so ganz den heutigen Anforderungen und Bedürfnissen.

Zunächst muss man verstehen das die Elemente einer Struktur (also die einzelnen Felder ) mit der Klasse CL_ABAP_ELEMDESCR verwaltet werden. Diese Klasse bietet öffentliche Methoden an, um Datentypen im ABAP Kontext anzulegen.

Die Klasse CL_ABAP_STRUCTDESCR verwaltet die Strukturen.
Nun kann man aber nicht die einzelnen Elemente einer Struktur an den Strukturverwalter liefern, und diesen dann bitten eine Struktur daraus zu machen, sondern man muss erst einmal alle Felder der benötigten Struktur mittels des Elementverwalters anlegen und das fertige Feld dann in einen Datenkontainer ablegen. Dieser Datenkontainer ist nichts anderes als wiederum eine Tabelle mit definierter Struktur.
Die Typenbeschreibung dieses Kontainers liegt im Type Pool ABAP ab.
Es handelt sich um die Typen:
ABAP_COMPONENTDESCR das ist die Struktur für jedes Feld einer Tabelle, und
ABAP_COMPONENT_TAB Dies ist die Tabelle oder auch der Datenkontainer für die Felder einer Tabelle


Nachdem die einzelnen Felder mittels des Elementverwalters in den Datenkontainer gestellt wurden,
kann nun der Strukturverwalter gebeten werden, aus diesen Feldern einen Strukturierten Typ zu erstellen.
Dies geschieht mittels der Methode CREATE. Diese erwartet als Importparameter unseren Datenkontainer bzw. unsere Tabelle mit den einzelnen Feldern für diese zu erstellende Struktur.
Von der Methode wird dann ein Verwalter vom gleichen Typ der Strukturverwalter Klasse zurück geliefert.
Es ist somit quasi ein CREATE OBJECT was da im Hintergrund abläuft.
Wir haben also eine Objektinstanz zurück bekommen. Diese Objektinstanz ist noch nicht die Struktur selber, sondern nur eine Objektvariable welche auf die Strukturverwalter Klasse referenziert.
Um nun eine Strukturvariable anzulegen bzw. zu erhalten, muss der Befehl CREATE DATA abgesetzt werden.
Allerdings haben wird ja keinen Typ dieser neu zu erstellenden Struktur, sondern nur die Objektvariable des Verwalters. Daher versetzen wir nun den Befehl nicht mit TYP = xxx sondern mit dem Schlüsselwort HANDLE
Und dem verweis auf unsere objektvariable.

Code: Alles auswählen.

DATA:
	lop_strucdescr	TYPE REF TO CL_ABAP_STRUCTDESCR ( LOP = Lokalter Objekt Pointer )
	Ldp_dynaic_record	TYPE REF TO DATA	( LDP = Lokaler Daten Pointer )
Create data Ldp_dynaic_record	type	handle	lop_strucdescr.
Nun haben wir einen Zeiger bzw. Pointer auf unsere neue Struktur. Es ist wichtig zu wissen, das es nicht die Struktur selber ist, sondern nur ein Zeiger. Der Inhalt eines solchen Zeigers ist das was uns interessiert.
Bei dem Zeiger selber, handelt es sich nur um eine Hauptspeicheradresse. Unter dieser Adresse sind dann die Daten zu finden die wir benötigen.
Deshalb wird auch mit dem Befehl:
ASSIGN lop_strucdescr->* TO <FIELD-SYMBOL> der Inhalt dieses Zeigers dem Feldsymbol zugewiesen-
Hierbei ist es wichtig zu wissen, das es oft Unfug ist, eine Zeigervariable an einem CHANGING Parameter zu übergeben. Da durch den CHANGING Parameter nicht nur der Inhalt des Zeigers, sondern auch der Zeiger selber geändert werden kann. Und somit u.U. Daten verloren gehen können. Sicherlich gibt es hier Situationen wo es durchaus Sinnvoll ist eine Objektvariable an einen CHANGING Parameter zu übergeben. Man muss sich halt darüber im klaren sein was benötigt wird.
Eine im USING Parameter übergebene Objektvariable kann durchaus ohne Schwierigkeiten innerhalb des gerufenen Bausteins den Dateninhalt verändert bekommen und an den Aufrufer zurück gegeben werden.
Hier sagt der USING Parameter nur, das die Objektvariable selber nicht geändert werden kann. Der Inhalt dieser Objektvariablen hat jedoch zunächst einmal nicht mit dem Inhalt zu tun.
Dies ist auch kein Fehler der SAP oder ähnliches, sondern eine Technik welche man verstehen muss.

Da nun unsere Struktur mittels CREATE DATA angelegt ist, benötigen wir noch eine Tabelle dafür.
Hierzu gibt es eine Tabellenverwalter Klasse mit dem Namen: CL_ABAP_TABLEDESCR
Dieser Tabellenverwalter bietet mit seiner öffentlichen Methode CREATE die Möglichkeit eine Objektvariable von genau dieser Klasse zu erstellen. Allerdings muss die CREATE Methode wissen, für welches Strukturobjekt nun ein Tabellenverwaltungsobjekt benötigt wird.

Code: Alles auswählen.

DATA:
Lop_Tab_Descr		type ref to 	cl_abap_tabledescr 

lop_tabledescr  ?=  cl_abap_tabledescr=>create( p_line_type = lop_strucdescr ).
Nachdem wir nun ein Tabellenverwaltungsobjekt haben, geht es analog der Erstellung der Strukturvariablen weiter,

Code: Alles auswählen.

DATA
Ldp_Dyn_Table		type ref to data.

Create data Ldp_dynaic_Table	type	handle	lop_Tab_descr.
Ich hoffe das ich mit meinen Ausführungen ein paar Kollegen helfen kann. Da auch mir über diese Foren immer sehr viel gegeben wurde, wollte ich nun einmal einen kleinen teil meiner Schuld abtragen.


Viele Grüße
Uwe
PS. Und nun das lauffähige Coding

Code: Alles auswählen.

REPORT  ZZUR_DYNAMISCHE_TABELLE.
TYPE-POOLS:  ABAP.

DATA:
  Ldp_Dyn_Table   type ref to data,
  Lop_Tabledescr   type ref to   cl_abap_tabledescr,
  Ldp_dynaic_record type ref to Data,
  lop_strucdescr  TYPE REF TO cl_abap_structdescr,
  LS_Component  TYPE    abap_componentdescr,
  LT_Component  TYPE    abap_component_tab.

Field-symbols:
  <dyn_Field>  TYPE  any,
  <Dyn_Rec> type any,
  <Dyn_Tab> Type any table.


LS_Component-Name  = 'NAME'.
LS_Component-TYPE  =  CL_ABAP_ELEMDESCR=>Get_C( P_LENGTH = 8 ).
APPEND  LS_Component  TO  LT_Component.

LS_Component-Name  = 'NUMMER'.
LS_Component-TYPE  =  CL_ABAP_ELEMDESCR=>Get_N( P_LENGTH = 8 ).
APPEND  LS_Component  TO  LT_Component.

LS_Component-Name  = 'PREIS'.
LS_Component-TYPE  =  CL_ABAP_ELEMDESCR=>Get_P( P_LENGTH = 13 P_DECIMALS = 2 ).
APPEND  LS_Component  TO  LT_Component.

LS_Component-Name  = 'ZAHL'.
LS_Component-TYPE  =  CL_ABAP_ELEMDESCR=>Get_I(  ).
APPEND  LS_Component  TO  LT_Component.


lop_strucdescr  = cl_abap_structdescr=>create( lt_component ).

Create data Ldp_dynaic_record type  handle  lop_strucdescr.
Lop_Tabledescr  ?=  cl_abap_tabledescr=>create( p_line_type = lop_strucdescr ).


Create data Ldp_Dyn_Table  type  handle  Lop_Tabledescr.

ASSIGN    Ldp_dynaic_record->*  to  <Dyn_Rec>.
ASSIGN    Ldp_Dyn_Table->* to  <Dyn_Tab>.


ASSIGN COMPONENT  'NAME' OF STRUCTURE  <Dyn_Rec>  TO  <dyn_Field>.
   <dyn_Field> = 'Hugo'.
UNASSIGN  <dyn_Field>.


ASSIGN COMPONENT  'NUMMER' OF STRUCTURE  <Dyn_Rec>  TO  <dyn_Field>.
   <dyn_Field> = '4711'.
UNASSIGN  <dyn_Field>.


ASSIGN COMPONENT  'ZAHL' OF STRUCTURE  <Dyn_Rec>  TO  <dyn_Field>.
   <dyn_Field> = '1'.
UNASSIGN  <dyn_Field>.


ASSIGN COMPONENT  'PREIS' OF STRUCTURE  <Dyn_Rec>  TO  <dyn_Field>.
   <dyn_Field> = '23.85'.
UNASSIGN  <dyn_Field>.

INSERT   <Dyn_Rec>  INTO  TABLE  <Dyn_tab>.

DATA:
  lv_idx   TYPE  i.
Loop at <Dyn_tab> into <Dyn_Rec>.
   Sy-SubRC = 0.
   lv_idx = 0.
   WHILE Sy-SubRC = 0.
      add  1  to  lv_idx.
      ASSIGN COMPONENT  lv_idx OF STRUCTURE  <Dyn_Rec>  TO  <dyn_Field>.
      CHECK  Sy-SubRC = 0.
      WRITE: / <dyn_Field>.
      UNASSIGN  <dyn_Field>.
   ENDWHILE.
Endloop.

Folgende Benutzer bedankten sich beim Autor Uwe.Rimarski für den Beitrag (Insgesamt 3):
TronIcke0801wfischer65


gesponsert
Stellenangebote auf ABAPforum.com schalten
kostenfrei für Ausbildungsberufe und Werksstudenten


Re: Dynamische Tabellenstrukturen im ABAP

Beitrag von LAT (ForumUser / 1 / 0 / 0 ) »
Vielen Dank. Vor allem die Erklärungen haben mir geholfen. Ich habe das schon öfter probiert und mit durchgewurschtelt bis es ging. Verstanden warum hatte ich dabei nicht.

Re: Dynamische Tabellenstrukturen im ABAP

Beitrag von wfischer65 (ForumUser / 2 / 1 / 0 ) »
Supersache, hat mir sehr geholfen. Allerdings habe ich jetzt einen Komponententyp H (Unter-Tabelle mit eigener Struktur). Bin mal gespannt ob ich auch das hinbekomme - vllt sogar rekursiv.

Seite 1 von 1

Vergleichbare Themen

8
Antw.
5852
Views
Zuweisung von Tabellenstrukturen
von av_deh » 14.04.2011 11:59 • Verfasst in ABAP® für Anfänger
0
Antw.
1311
Views
dynamische Wertehilfe in Adobe forms (Web Dynpro ABAP)
von Jan-Ole » 16.01.2006 16:31 • Verfasst in Dialogprogrammierung
5
Antw.
9996
Views
Kundeneigene ABAP-Muster Vorlage im ABAP-Editor anlegen
von Stentor » 19.07.2005 11:10 • Verfasst in Basis
3
Antw.
1825
Views
Dynamische SQL
von Gabriel99 » 22.06.2015 17:59 • Verfasst in ABAP® für Anfänger
6
Antw.
3538
Views
Dynamische Spalten
von hmaxi96 » 16.11.2015 10:03 • Verfasst in ABAP® für Anfänger

Über diesen Beitrag



Die Frage ist als "gelöst" markiert. Den entsprechend Beitrag findest du hier.

Unterstütze die Community und teile den Beitrag für mehr Leser und Austausch

Aktuelle Forenbeiträge

Zwischensumme Adobe Forms
vor 2 Tagen von Lucyalison 1 / 64
Interne Tabelle
vor 5 Tagen von black_adept 2 / 133
MaLo-Checker in ABAP
vor einer Woche von A6272 6 / 254

Newsletter Anmeldung

Keine Beiträge verpassen! Wöchentlich versenden wir lesenwerte Beiträge aus unserer Community.
Die letzte Ausgabe findest du hier.
Details zum Versandverfahren und zu Ihren Widerrufsmöglichkeiten findest du in unserer Datenschutzerklärung.

Aktuelle Forenbeiträge

Zwischensumme Adobe Forms
vor 2 Tagen von Lucyalison 1 / 64
Interne Tabelle
vor 5 Tagen von black_adept 2 / 133
MaLo-Checker in ABAP
vor einer Woche von A6272 6 / 254

Unbeantwortete Forenbeiträge

Zwischensumme Adobe Forms
vor 2 Tagen von Lucyalison 1 / 64
Group Items auf einer Filterbar
vor einer Woche von Bright4.5 1 / 107
tRFC Transaktionen SM58
vor 4 Wochen von A6272 1 / 140