Dynamische Tabelle definieren mit Zeilentyp einer anderen - wie machen?

Alles rund um die Sprache ABAP®: Funktionsbausteine, Listen, ALV
17 Beiträge • Seite 1 von 2 (current) Nächste
17 Beiträge Seite 1 von 2 (current) Nächste

Dynamische Tabelle definieren mit Zeilentyp einer anderen - wie machen?

Beitrag von DeathAndPain (Top Expert / 1952 / 259 / 413 ) »
Hallo zusammen,

ich will eine FORM-Routine bauen, der eine Tabelle übergeben wird. Diese Importtabelle soll ausdrücklich nicht fest typisiert sein, noch nicht mal hinsichtlich ihrer Sortierung oder Hashung. Jetzt will ich in der Form dynamisch eine weitere Tabelle anlegen, die inhaltlich nichts anderes sein soll als eine Kopie der übergebenen Tabelle. Meine dynamische Tabelle soll aber immer eine Standardtabelle sein, egal welchen Typ die übergebene Tabelle gehabt hat.

Also im Prinzip will ich Folgendes machen:

Code: Alles auswählen.

REPORT.

FORM TEST CHANGING TESTTABLE TYPE ANY TABLE.

  DATA REF_TO_COPY_OF_TESTTABLE TYPE REF TO DATA.

  CREATE DATA REF_TO_COPY_OF_TESTTABLE TYPE STANDARD TABLE OF ( LINE OF TESTTABLE ) WITH EMPTY KEY.
  ASSIGN REF_TO_COPY_OF_TESTTABLE ->* TO FIELD-SYMBOL(<COPIED_TABLE>).

  <COPIED_TABLE> = TESTTABLE. " Daten von übergebener in Standardtabelle übertragen
ENDFORM.
Nur funktioniert der obenstehende CREATE DATA nicht, weil ich so natürlich den Datentyp des zu erzeugenden Feldes nicht angeben darf. Gibt es eine elegante Lösung dafür?

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


Re: Dynamische Tabelle definieren mit Zeilentyp einer anderen - wie machen?

Beitrag von ewx (Top Expert / 4849 / 313 / 642 ) »
DeathAndPain hat geschrieben:
01.10.2021 19:29
ich will eine FORM-Routine bauen
waaaahhhhhhhhhhhhhhhhhhhhhh 😖 😁

meine Idee wäre mit CL_ABAP_TYPEDESCR die Struktur der übergebenen Tabelle zu ermitteln und dann mit dieser Struktur eine Tabelle mit Typ "Standard" zu erzeugen.

https://codezentrale.de/abap-rtts-inter ... -erzeugen/

Re: Dynamische Tabelle definieren mit Zeilentyp einer anderen - wie machen?

Beitrag von black_adept (Top Expert / 4099 / 128 / 941 ) »
Moin D&P,
ich benutze so was in einer allgemeinen Table-Dump-Routine, der ich eine beliebige Tabelle übergebe, die als ALV angezeigt werden soll.
Das Coding dazu ist trivial und hier kann der "LIKE"-Befehl glänzen:
Code aus dem Kopf und ohne System:

Code: Alles auswählen.

CREATE DATA lr_data LIKE LINE of itab.
ASSIGN lr_data->* to <ls_line>.
CREATE DATA lr_data LIKE STANDARD TABLE OF <ls_line>.
ASSIGN lr_data->* to <lt_table>.
<lt_table> = itab.

Folgende Benutzer bedankten sich beim Autor black_adept für den Beitrag (Insgesamt 3):
ewxDeathAndPainIcke0801

live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Dynamische Tabelle definieren mit Zeilentyp einer anderen - wie machen?

Beitrag von DeathAndPain (Top Expert / 1952 / 259 / 413 ) »
Danke. Im Prinzip habe ich es dann auch so gemacht. Nur habe ich halt ein Hilfsfeld erzeugt, wohingegen Du lr_data recyclest mit der Folge, dass <ls_line> in dem Moment aufhören müsste zu existieren, in dem es für den zweiten CREATE DATA-Befehl genutzt wird (denn dann ist das zuerst erzeugte Datenfeld ja nicht mehr referenziert und müsste damit in die Garbage Collection gehen). Deine Variante könnte auch funktionieren und wäre dann noch einen Hauch eleganter.

Re: Dynamische Tabelle definieren mit Zeilentyp einer anderen - wie machen?

Beitrag von black_adept (Top Expert / 4099 / 128 / 941 ) »
DeathAndPain hat geschrieben:
06.10.2021 16:50
mit der Folge, dass <ls_line> in dem Moment aufhören müsste zu existieren, in dem es für den zweiten CREATE DATA-Befehl genutzt wird (denn dann ist das zuerst erzeugte Datenfeld ja nicht mehr referenziert und müsste damit in die Garbage Collection gehen).
Das ist aber eine sehr verquere Sichtweise, die du dir für Referenzen und dereferenzierte Daten angewöhnt hast. CREATE DATA erzeugt die Daten und am Anfang zeigt lr_ldata darauf. Mit assign lr_data->* to <ls_line> zeigt jetzt zusätzlich auch <ls_line> auf die mit CREATE DATE erzeugten Daten und somit bleibt beim Recyclen von lr_data immer noch eine Referenz stehen...
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Dynamische Tabelle definieren mit Zeilentyp einer anderen - wie machen?

Beitrag von DeathAndPain (Top Expert / 1952 / 259 / 413 ) »
Ein Feldsymbol ist keine Referenz, sondern eine Verknüpfung. Das ist ein Unterschied, ob ich ein Datenfeld vom Typ "REF TO DATA" oder nur ein mit deren Ziel verknüpftes Feldsymbol habe. Hält solch Feldsymbol das Feld tatsächlich am Leben, auch wenn es keine Referenz darauf mehr gibt? Ich behaupte nicht, dass das nicht sein kann, sondern nur, dass mir das bislang nicht bekannt ist.

Re: Dynamische Tabelle definieren mit Zeilentyp einer anderen - wie machen?

Beitrag von black_adept (Top Expert / 4099 / 128 / 941 ) »
Moin D&P,
ein Speicherbereich ist eine Ansammlung/Reservierung von Zellen/Bits/Bytes im Speicher. Eine Variable ist ein symbolischer Zeiger auf diesen Speicherbereich. Sowohl Referenzvariablen als auch Feldsymbole sind letztendlich Variablen im Sinne der Programmierung. Es gibt intern eine Tabelle, welche jede Variable ihrem Speicherbereich zuordnet.
Beispiel: DATA: lv_test TYPE mandt definiert ein 3-Byte-Bereich im Speicher und erzeugt einen Eintrag in der o.a. Tabelle, die den Variablennamen dem Speicherbereich zuordnet.
GET REFERENCE OF lv_test INTO LR_DATA sorgt dafür, dass in der Tabelle entweder der Variablenname LR_DATA eingetragen wird oder dass, falls schon vorhanden, der gleiche Speicherbereich zugeordnet wird. Mit ASSIGN lr_data->* TO <ls_data> passiert das Gleiche, so dass die Tabelle nun 3 Einträge enthält, welche alle auf den selben Speicherbereich zeigen.

Und DAS ist es, was SAP mit "Referenz auf ein Datenfeld" meint. Nicht eine Variable vom Type Ref to...
Und wenn SAP sagt, dass keine Referenz mehr vorhanden ist, bedeutet das einfach, dass die o.a. Tabelle keinen Eintrag mehr hat, der auf den Speicherbereich zeigt.

Wenn dich das Thema mehr interessiert als meine sehr verkürzte Darstellung google nach "Compilerbau" und konsumiere die dort genannte Literatur.

P.S.
Das ist übrigens auch der Grund, warum eine Methode/FORM einen Zeiger auf ein mit CREATE DATA erzeugten Speicherbereich zurückgeben kann ( Variable wird auf dem Heap erzeugt, welcher beim Verlassen der Modularisierungseinheit bestehen bleibt ) während ein Zeiger, der mit GET REFERENCE OF auf eine lokale Variable gesetzt wird, nach Verlassen der Modularisierungseinheit nicht mehr gebunden ist ( alle lokalen Variablen landen im Stack und werden beim Verlassen der Modularisierungseinheit aus dem Stack gelöscht und alle (nicht lokalen) Einträge, die auf so einen Speicherbereich zeigen werden invalidiert = auf unbound gesetzt und alle Einträge, die für lokale Variablen stehen werden aus der Tabelle gelöscht )
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Dynamische Tabelle definieren mit Zeilentyp einer anderen - wie machen?

Beitrag von DeathAndPain (Top Expert / 1952 / 259 / 413 ) »
black_adept hat geschrieben:
06.10.2021 20:40
Sowohl Referenzvariablen als auch Feldsymbole sind letztendlich Variablen im Sinne der Programmierung.
Wenn das so ist, weshalb kann ich dann keinen Watchpoint auf ein Feldsymbol anlegen... einer der größten Nachteile von Feldsymbolen (die ich ansonsten sehr schätze). Durch die effizienteren LOOP ... ASSIGNING anstelle der herkömmlichen LOOP ... INTO bringt man sich beim Debugging um die Möglichkeit, per Watchpoint auf eine Zeile mit bestimmtem Inhalt zu warten. Allenfalls kann man versuchen, sich vorher anzuschauen, die wievielte Zeile der geLOOPten Tabelle man braucht und dann den Watchpoint auf SY-TABIX setzen. Aber wehe, es gibt einen inneren (geschachtelten) LOOP, bei dem dieser SY-TABIX auch auftritt oder einen READ TABLE oder dergleichen...

Wären Feldsymbole richtige Variablen und nicht nur Zeiger auf Speicherbereiche, dann wäre auch ein Watchpoint darauf möglich.

Re: Dynamische Tabelle definieren mit Zeilentyp einer anderen - wie machen?

Beitrag von black_adept (Top Expert / 4099 / 128 / 941 ) »
DeathAndPain hat geschrieben:
07.10.2021 17:57
Wären Feldsymbole richtige Variablen und nicht nur Zeiger auf Speicherbereiche, dann wäre auch ein Watchpoint darauf möglich.
Moin D&P,
ja - das hätte SAP tatsächlich so implementieren können, aber sie haben es aus gutem Grund nicht gemacht.
Eine "normale" Variable zeigt auf einen definierten Speicherbereich. Und diese Variable zeigt auch immer dahin und der Eintrag in der o.a. Tabelle ändert sich nie. Der Watchpoint wird dann vom Kernel auf den Speicherbereich gesetzt, auf den die Variable zeigt.
Ein Feldsymbol ist eine auch eine Variable - aber im Gegensatz zu den "normalen" Variablen darf sich bei ihr der Zeiger ändern, auf den sie zeigt.
Und da liegt die Crux: Stell dir vor, du hast 2 (globale, normale) Variblen vom Typ Integer, die beide den Wert 5 haben.
Danach machst du ein Assign variable1 to <fs>. Damit zeigt <fs> auf einen Speicherbereich der den Wert 5 hat.
Wenn du jetzt ein Assign variable2 to <fs> machst besteht folgende Zweideutigkeit.
Einerseits hat sich der Speicherbereich geändert auf den <fs> zeigt. Das ist eine Änderung. Andererseits hat sich der Wert des Speicherbereichs auf den <fs> zeigt durch das umassignen nicht geändert. Doof...
Wenn ein User sieht, dass bei dem von dir angesprochenen LOOP beim nächsten Durchlauf der Wert des Feldsymbols ändert, erwartet er, dass dann ein Watchpoint angesprochen würde. Und das ist bei Feldsymbolen eben nicht der Fall, da sich beim Umassignen üblicherweise kein Wert im Speicher ändert, sondern nur der Speicherbereich, auf den das Feldsymbol zeigt. Und da das OS/Kernel halt Watchpoints maschinennah auf Speicherbereiche setzen kann und die Variablen-Speicherbereichszuordnungstabelle etwas ist, was von der Programmiersprache verwaltet wird und somit um Größenordnungen langsamer/komplizierter ist als das, was dir der Prozessor schenkt, kommt es zu dem von dir beobachteten Verhalten.
Ich finde das auch nicht schön - macht aber (leider) technisch gesehen Sinn...
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Dynamische Tabelle definieren mit Zeilentyp einer anderen - wie machen?

Beitrag von DeathAndPain (Top Expert / 1952 / 259 / 413 ) »
Ich verstehe Deine Argumentation, bin aber dennoch nicht der Meinung, dass das Sinn macht. Die sinnvolle Interpretation wäre in der Tat der Wert des Feldes gewesen, wie das bei Watchpoints halt so ist. Dann und nur dann kann man das tun, was man beim Debuggen ständig braucht, nämlich einen bestimmten Schleifendurchlauf per Watchpoint treffen.

Dass jemand die Sache missverstehen und annehmen könnte, bei einem neuerlichen ASSIGN würde ja auch eine Änderung vorliegen, selbst wenn der Wert gleich ist, ist in Kauf zu nehmen. Der Fall, dass man das braucht, ist verschwindend selten (und geht jetzt ja auch nicht, man hat also nichts gewonnen).

Davon abgesehen besteht der Löwenanteil meiner Watchpoints nicht aus einer bloßen Angabe des Feldes, sondern Prüfung auf Gleichheit. Über die interne Tabelle xyz mit Personalnummern drin (oder Materialnummern oder was immer für ein Modul man hat) wird ein LOOP gefahren, und man will wissen, warum die Logik des LOOPs bei Personalnummer 584328 nicht erwartungsgemäß funktioniert. Das ist aber die 1745. Zeile in der Tabelle. Also will man sich einen Watchpoint auf <xyz>-PERNR = '00584328' legen, damit der LOOP dann stoppt und man im Debugger landet. Geht aber nicht. Und für diesen Einsatzzweck gibt es auch keine vernünftige Debugger-Alternative, sofern SY-TABIX wegen innerer LOOPs etc. nicht verwendbar ist.

Deiner Argumentation zufolge hat die SAP gesagt, in seltenen Fällen könnte es zu Missverständnissen kommen, wie das funktioniert, also machen wir es komplett unmöglich, dann kann es auch keiner missverstehen. Das würde ich aber für eine bescheuerte Logik halten. Es gibt in ABAP viele Befehle, die man leicht missverstehen kann, wenn man sich mit ihrer Funktionsweise nicht sorgsam vertraut macht. Sollte man die deshalb alle rausschmeißen und nicht mehr nutzbar machen?

Re: Dynamische Tabelle definieren mit Zeilentyp einer anderen - wie machen?

Beitrag von black_adept (Top Expert / 4099 / 128 / 941 ) »
Moin D&P,
die Zweideutigkeit ist einer der Gründe. Der andere (Haupt)grund ist, dass der Prozessor! einen Watchpoint auf einen Speicherbereich setzten kann und einen Event feuert, der von den darüberliegenden Sprachen abgefangen werden kann. Und das ist superschnell. Das was du willst müsste über die Sprache abgefangen werden und wäre grottenlangsam, falls alle Sprache(n) die zwischen ABAP und Maschinencode liegen, das überhaupt unterstützen.
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Dynamische Tabelle definieren mit Zeilentyp einer anderen - wie machen?

Beitrag von DeathAndPain (Top Expert / 1952 / 259 / 413 ) »
Selbst wenn man die Watchpoint-Prüfung komplett auf höchster Ebene in ABAP realisiert, also für jeden Watchpoint nach jedem einzelnen Befehl einen expliziten

Code: Alles auswählen.

IF watchpoint = gesuchter_wert.
   ...
ENDIF.
ausführt, wird man das bei den meisten Programmen in der Laufzeit nicht wahrnehmen. Watchpoints sind ja ohnehin nur etwas für Test- und Debugsituationen, so dass eine schlechtere Performance an dieser Stelle später im produktiven Betrieb keine Rolle spielt. Und selbst beim Debuggen wird kaum jemand Dutzende Watchpoints gleichzeitig aktiv haben, so dass es immer nur wenige IFs sind, die es abzufragen gilt. Und ich würde vermuten, dass man die Feldsymbolprüfung irgendwo auf mittlerer Ebene realisiert bekommt - wenn der Wille dazu da ist.

Man könnte das ja so bauen, dass die ganze performancereduzierende Abfragelogik nur dann genutzt wird, wenn mindestens ein Feldsymbol-Watchpoint definiert ist. Wenn ich beim Debuggen 20 Sekunden länger warte (was viel wäre), dann ist das immer noch um Größenordnungen schneller, als wenn ich mir irgendwas basteln muss, um auf andere Weise den 1784. Loopdurchlauf meiner mit geschachtelten Loops ausgestatteten Tabelle zu treffen. Wenn es überhaupt möglich ist, etwas Passendes zu basteln (was ich für keineswegs gesichert halte, wenn ich einen Fehler im Produktivsystem debugge, wo ich nicht rasch mal was ändern kann und auch nur Debug-ohne-Replace-Rechte habe).

Re: Dynamische Tabelle definieren mit Zeilentyp einer anderen - wie machen?

Beitrag von black_adept (Top Expert / 4099 / 128 / 941 ) »
1784. Loopdurchlauf kann der Debugger - aber grundsätzlich gebe ich dir recht.
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Dynamische Tabelle definieren mit Zeilentyp einer anderen - wie machen?

Beitrag von DeathAndPain (Top Expert / 1952 / 259 / 413 ) »
Wirklich? Wie macht man das? Ich habe noch keinen Weg dafür gefunden.

Re: Dynamische Tabelle definieren mit Zeilentyp einer anderen - wie machen?

Beitrag von black_adept (Top Expert / 4099 / 128 / 941 ) »
Moin D&P,
Demo mit Miniprogramm:

Code: Alles auswählen.

REPORT.
do 10000 times.
  write sy-index.
enddo.
und du willst beim 1784. Durchlauf anhalten ( aber hast nicht wie im Minibeispiel ein sy-index, auf das du einen Watchpoint setzen kannst )
Setze also einen Breakpoint auf die Zeile WRITE sy-index.
Wenn du dort landest bist du im 1. Schleifendurchlauf. Wenn du beim 1784. anhalten willst musst du jetzt noch 1782 mal den Breakpoint auslassen.
Unbenannt.png
Wenn du jetzt weiterläufst solltest du beim nächsten Mal beim 1784. Schleifendurchlauf anhalten

Folgende Benutzer bedankten sich beim Autor black_adept für den Beitrag (Insgesamt 2):
DeathAndPainThomas R.

live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Vergleichbare Themen

2
Antw.
3191
Views
Zeilentyp einer generischen Tabelle
von horn » 08.08.2008 20:35 • Verfasst in ABAP® für Anfänger
1
Antw.
1873
Views
int. Tabelle definieren
von MarkusW » 21.02.2007 17:18 • Verfasst in ABAP® für Anfänger
4
Antw.
1576
Views
Interne Tabelle definieren
von user112610 » 23.01.2023 08:26 • Verfasst in ABAP® für Anfänger
2
Antw.
7263
Views
interne Tabelle definieren
von Gast » 16.09.2005 11:40 • Verfasst in ABAP® für Anfänger
1
Antw.
1174
Views
interne Tabelle Selection definieren
von frany*89* » 16.08.2011 04:42 • Verfasst in ABAP® für Anfänger

Aktuelle Forenbeiträge

Daten an Tabelle binden
vor 6 Stunden von Bright4.5 3 / 1478
Regex in where
vor 8 Stunden von tar 6 / 144
Programm anlegen mit Vorlage
vor 23 Stunden von DeathAndPain 2 / 126
IT0024 Qualifikationen CP-ID
vor 23 Stunden von DeathAndPain 2 / 357

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

Daten an Tabelle binden
vor 6 Stunden von Bright4.5 3 / 1478
Regex in where
vor 8 Stunden von tar 6 / 144
Programm anlegen mit Vorlage
vor 23 Stunden von DeathAndPain 2 / 126
IT0024 Qualifikationen CP-ID
vor 23 Stunden von DeathAndPain 2 / 357

Unbeantwortete Forenbeiträge

aRFC im OO-Kontext
vor 5 Wochen von ralf.wenzel 1 / 3261
Hilfe bei SWEC/SWE2
September 2024 von retsch 1 / 9821