Interne Tabelle selektieren


Getting started ... Alles für einen gelungenen Start.

Moderatoren: Jan, Steff

Interne Tabelle selektieren

Beitragvon flo1304 » 14.03.2019, 09:04

Hallo Zusammen,

ich lerne erst seit kurzem ABAP und möchte gerne wissen, ob und wenn ja, wie folgendes Möglich ist.

Ich habe 3 interne Tabellen, welche alle eine unterschiedliche Struktur haben, aber alle ein identisches Feld (Kundennummer) enthalten, welches auch überall durch das selbe Datenelement definiert ist.

Was ich nun möchte, ich möchte aus der Internen Tabelle 1 alle Einträge filtern, welche die Kundennummer aus der Interne Tabelle 2 haben und diese Einträge dann in die interne Tabelle 3 schreiben.

ich habe versucht das ganze mit einem LOOP und WHERE Bedingung IN itab umzuzsetzen, aber irgendwie mag es nicht so gelingen.

Könntet Ihr mir helfen? Vielen Dank!
Das Forum hat mir schon öfters mal weitergeholfen, aber diesmal bin ich bei den Themen leider nicht fündig geworden.

Liebe Grüße
Flo
flo1304
ForumUser
 
Beiträge: 1
Registriert: 13.03.2019, 14:19
Dank erhalten: 0 mal
Ich bin: Student/in

Sponsor

Alte ABAP-Entwicklerweisheit: Weißt du weder aus noch ein, baust du einen BADI ein

Re: Interne Tabelle selektieren

Beitragvon LostDarkness » 14.03.2019, 09:34

Guten Morgen Flo,

Ich bin selbst nicht so der Erfahrenste und weiß das Loops in Loops ungern gesehen sind,
aber mein gedanklicher Ansatz diesbezüglich wäre quasi so etwas wie folgendes Beispiel von mir mit Materialnummern.

Code: Alles auswählen
DATA: itab1 TYPE TABLE OF mara,
      itab2 TYPE TABLE OF marc,
      itab3 TYPE TABLE OF makt,
      wa_itab1 LIKE LINE OF itab1,
      wa_itab2 LIKE LINE OF itab2,
      wa_itab3 LIKE LINE OF itab3.

SELECT * FROM mara INTO CORRESPONDING FIELDS OF TABLE itab1.

SELECT * from marc INTO CORRESPONDING FIELDS OF TABLE itab2.

LOOP AT itab1 INTO wa_itab1.
  LOOP AT itab2 INTO wa_itab2 WHERE matnr = wa_itab1-matnr.
    wa_itab3-matnr = wa_itab2-matnr.
    APPEND wa_itab3 TO itab3.
  ENDLOOP.
ENDLOOP.

 


Bearbeitung mit Field-Symbols wäre natürlich noch schöner.
Angaben ohne Gewähr. :)

Liebe Grüße
Gerrit
LostDarkness
ForumUser
 
Beiträge: 43
Registriert: 07.06.2018, 10:21
Dank erhalten: 1 mal
Ich bin: Entwickler/in

Re: Interne Tabelle selektieren

Beitragvon qyurryus » 14.03.2019, 11:59

Alternatives Beispiel mit Feld-Symbolen.

Code: Alles auswählen
loop at table1 assigning field-symbol(<table1>).
  " wenn es einen Eintrag mit der selben Materialnummer in Tabelle 2 gibt, hänge die Zeile
  if line_exists( table2&#91; kunnr= <table1>-kunnr&#93; ).
    " neue zeile in tabelle 3 erzeugen
    append initial line to table3 assigning field-symbol(<table3>).
    " gleichnamige felder von tabelle1-zeile zu tabelle3-zeile schieben
    move-corresponding <table1> to <table3>.
  endif.
endloop.
qyurryus
ForumUser
 
Beiträge: 15
Registriert: 27.08.2018, 12:12
Dank erhalten: 3 mal
Ich bin: Entwickler/in

Re: Interne Tabelle selektieren

Beitragvon DeathAndPain » 15.03.2019, 10:41

Schöne Lösung, qyurryus, auch wenn ich hier CHECK statt IF verwendet hätte.

LostDarkness hat geschrieben:Ich bin selbst nicht so der Erfahrenste und weiß das Loops in Loops ungern gesehen sind

Das halte ich für ein Gerücht. Geschachtelte SELECTs sind nicht gern gesehen, geschachtelte LOOPs hingegen sind kein Problem.

Wenn sie hier gelegentlich kritisiert werden, dann nur in Fällen, bei denen sie nur deswegen formuliert wurden, weil der Programmierer nicht richtig verstanden hat, wie er die Aufgabe in Code gießen muss und daher eine unnötige Komplexität einführt. Dein Beispiel ist leider solch ein Fall, da Du einen LOOP machst, obwohl Du nur ein einziges, auf Gleichheit geprüftes Suchergebnis haben möchtest (nämlich ob solch Zeile in Tabelle 2 überhaupt existiert). Da ist ein LOOP immer fehl am Platze, egal ob es außenrum noch einen gibt oder nicht. Nach alter Syntax nimmt man stattdessen einen READ TABLE, nach neuer ein ABAP 7.40-Konstrukt. qyurryus' Lösung über den LINE_EXISTS( ) ist hier die beste. Bei Releases, bei denen es den noch nicht gibt, nimmt man stattdessen einen READ TABLE TRANSPORTING NO FIELDS und prüft dann den SY-SUBRC.

Es gibt aber viele Fälle, in denen geschachtelte LOOPs notwendig und sinnvoll sind, und da spricht auch gar nichts dagegen.
DeathAndPain
Expert
 
Beiträge: 972
Registriert: 05.05.2006, 10:14
Dank erhalten: 222 mal
Ich bin: Entwickler/in

Re: Interne Tabelle selektieren

Beitragvon ralf.wenzel » 16.03.2019, 05:31

Was schreibst du denn da? Natürlich sollte man nested loops vermeiden, darum warnt das System auch davor, wenn es welche erkennt. Überleg mal, wie oft eine Operation durchgeführt wird, wenn du zwei Tabellen a 1.000 Sätze hast und sie im inneren loop stehen.

Eine wichtige Maßnahme zur Beschleunigung sind sortierte Tabellen und eine where-Bedingung im inneren loop, aber selbst dann hast du bei hinreichend vielen Treffern das a*b-Problem.

Hat man sowas nicht, macht man Folgendes: Man sortiert beide Tabellen und wirft aus der äußeren alle doppelten KUNNR-Sätze raus. Sodann macht man im loop einen READ TABLE BINARY SEARCH um einen Aufsetzpunkt zu finden und macht von diesem Satz aus einen inneren loop bis zum letzten Sstz dieser KUNNR. So kann man sicher sein, jeden Satz im inneren loop nur 1x zu treffen. Das ist quasi ein LOOP AT ... WHERE für alte Releases.


Ralf
ralf.wenzel
Top Expert
 
Beiträge: 3374
Registriert: 18.09.2004, 13:03
Wohnort: Hamburg
Dank erhalten: 213 mal
Ich bin: Freiberufler/in

Re: Interne Tabelle selektieren

Beitragvon DeathAndPain » 18.03.2019, 14:47

Was schreibst du denn da? Natürlich sollte man nested loops vermeiden, darum warnt das System auch davor, wenn es welche erkennt.

Ich bin schon vom System vor allem möglichen Mist gewarnt worden, aber noch nie vor einem nested loop. Noch nicht mal in ausblendbarer Form.

Überleg mal, wie oft eine Operation durchgeführt wird, wenn du zwei Tabellen a 1.000 Sätze hast und sie im inneren loop stehen.

Abhängig davon, was die zu lösende Aufgabenstellung ist, kann das aber notwendig sein. Dann ist es erforderlich und ganz normal. Deswegen habe ich in meiner Antwort ja geschrieben, dass man das Problem verstehen und logisch korrekt modellieren muss, damit man keine unnötigen nested loops hat, die sich eben nicht aus der Aufgabenstellung ergeben, sondern die Komplexität (und Laufzeit) nur ohne Not aufblähen.

Aber wenn Du beispielsweise zu bestimmten Verkäufergruppen alle Materialien wissen willst, die von den jeweiligen VKGRP in einem bestimmten Zeitraum verkauft worden sind, dann wird Dir nichts anderes übrigbleiben, als zunächst einmal zu dieser VKGRP aus der VBAK alle relevanten Aufträge zu lesen. Performanterweise machst Du das per SELECT INTO TABLE. Anschließend musst Du zu diesen Aufträgen alle betroffenen Positionen lesen. Performanterweise machst Du das per SELECT FOR ALL ENTRIES IN (alternativ durch Aufbau einer passenden RANGES-Tabelle). Und dann musst Du pro VKGRP hingehen, einen LOOP über Deine Auftragstabelle WHERE VKGRP = ... machen und darin dann einen LOOP auf Deine Positionstabelle machen und Deine Positionen ranholen.

Je nachdem, von wieviel Daten wir da reden, kann das zu einer längeren Laufzeit führen, ja. Aber das ist dann die Aufgabenstellung. Die Alternative wären viele einzelne Zugriffe auf die Datenbank (etwa ein separater SELECT für jede einzelne VKGRP), was performancetechnisch viel schlechter wäre als ein einziger dicker SELECT und dann Suche durch Deine sortierten oder gehashten internen Tabellen.
DeathAndPain
Expert
 
Beiträge: 972
Registriert: 05.05.2006, 10:14
Dank erhalten: 222 mal
Ich bin: Entwickler/in

Re: Interne Tabelle selektieren

Beitragvon ralf.wenzel » 18.03.2019, 16:09

DeathAndPain hat geschrieben:
Was schreibst du denn da? Natürlich sollte man nested loops vermeiden, darum warnt das System auch davor, wenn es welche erkennt.

Ich bin schon vom System vor allem möglichen Mist gewarnt worden, aber noch nie vor einem nested loop. Noch nicht mal in ausblendbarer Form.


Ich schon.

DeathAndPain hat geschrieben:Aber wenn Du beispielsweise zu bestimmten Verkäufergruppen alle Materialien wissen willst, die von den jeweiligen VKGRP in einem bestimmten Zeitraum verkauft worden sind, dann wird Dir nichts anderes übrigbleiben, als zunächst einmal zu dieser VKGRP aus der VBAK alle relevanten Aufträge zu lesen. Performanterweise machst Du das per SELECT INTO TABLE. Anschließend musst Du zu diesen Aufträgen alle betroffenen Positionen lesen. Performanterweise machst Du das per SELECT FOR ALL ENTRIES IN (alternativ durch Aufbau einer passenden RANGES-Tabelle). Und dann musst Du pro VKGRP hingehen, einen LOOP über Deine Auftragstabelle WHERE VKGRP = ... machen und darin dann einen LOOP auf Deine Positionstabelle machen und Deine Positionen ranholen.


Auweh. Also, einen LOOP AT....WHERE.... macht man nicht über Standardtabellen, weil dabei jeder Satz angefasst wird, um zu prüfen, ob er der WHERE-Bedingung entspricht. Deutlich performanter ist das mit sortierten Tabellen (dann werden wirklich nur die Sätze angesprungen, die der WHERE-Bedingung entsprechen) oder mit einem Aufsetzpunkt. Man kann und sollte bei solchen Konstrukten immer dafür sorgen, dass jeder Satz nach Möglichkeit nur einmal durchlaufen wird (eben auch im inneren LOOP).

In der Regel lohnt es sich, in solche Konstrukte viel Hirnschmalz zu investieren.


Ralf
ralf.wenzel
Top Expert
 
Beiträge: 3374
Registriert: 18.09.2004, 13:03
Wohnort: Hamburg
Dank erhalten: 213 mal
Ich bin: Freiberufler/in

Re: Interne Tabelle selektieren

Beitragvon ewx » 18.03.2019, 17:05

ralf.wenzel hat geschrieben:
DeathAndPain hat geschrieben:
Was schreibst du denn da? Natürlich sollte man nested loops vermeiden, darum warnt das System auch davor, wenn es welche erkennt.

Ich bin schon vom System vor allem möglichen Mist gewarnt worden, aber noch nie vor einem nested loop. Noch nicht mal in ausblendbarer Form.


Ich schon.

Das ist die Code-Inspector-Prüfung "Geschachtelte Schleifen" aus der Gruppe "Performance-Prüfungen".

Code: Alles auswählen
Was wird geprüft?

    Geschachtelte Schleifen

    Sucht nach Schleifen, die selbst wiederum in Schleifen enthalten sind.
    Dies sind:

    o   LOOP ... ENDLOOP.

    o   DO ... ENDDO.

    o   WHILE ... ENDWHILE.

    o   PROVIDE ... ENDPROVIDE.

    Gemeldet wird, wenn zwei der obigen Schleifentypen ineinander
    geschachtelt sind bzw. in einer SELECT ... ENDSELECT-Schleife vorkommen.
    Die Verwendung in Modularisierungseinheiten, die innerhalb einer
    Schleife aufgerufen werden, kann nicht festgestellt werden.

    SELECT-Statements innerhalb einer Schleife werden in einer anderen
    Prüfung untersucht.
ewx
Top Expert
 
Beiträge: 3885
Registriert: 04.08.2003, 19:55
Wohnort: Schleswig-Holstein
Dank erhalten: 343 mal

Re: Interne Tabelle selektieren

Beitragvon ralf.wenzel » 18.03.2019, 17:10

ewx hat geschrieben:Das ist die Code-Inspector-Prüfung "Geschachtelte Schleifen" aus der Gruppe "Performance-Prüfungen".


Richtig.


Ralf
ralf.wenzel
Top Expert
 
Beiträge: 3374
Registriert: 18.09.2004, 13:03
Wohnort: Hamburg
Dank erhalten: 213 mal
Ich bin: Freiberufler/in

Re: Interne Tabelle selektieren

Beitragvon black_adept » 18.03.2019, 17:56

ralf.wenzel hat geschrieben:
ewx hat geschrieben:Das ist die Code-Inspector-Prüfung "Geschachtelte Schleifen" aus der Gruppe "Performance-Prüfungen".

Richtig.
Und wenn einen die Prüfung stört einfach die innere Schleife in eine eigene Modularisierungseinheit refactoren...
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Für diese Nachricht hat black_adept einen Dank bekommen :
DeathAndPain
black_adept
Top Expert
 
Beiträge: 3198
Registriert: 08.01.2003, 13:33
Wohnort: Lehrte ( bei Hannover )
Dank erhalten: 560 mal
Ich bin: Freiberufler/in

Re: Interne Tabelle selektieren

Beitragvon ralf.wenzel » 18.03.2019, 19:26

Das ist in der Tat ein Problem: Sowas erkennt die Prüfung leider nicht.


Ralf
ralf.wenzel
Top Expert
 
Beiträge: 3374
Registriert: 18.09.2004, 13:03
Wohnort: Hamburg
Dank erhalten: 213 mal
Ich bin: Freiberufler/in

Re: Interne Tabelle selektieren

Beitragvon SaskuAc » 19.03.2019, 08:23

ralf.wenzel hat geschrieben:Das ist in der Tat ein Problem: Sowas erkennt die Prüfung leider nicht.


Wir haben dafür eine kleine Modifikation eingebaut. Es wird bis zu einer Tiefe von X ( kann man einstellen ) nach den nested loops gesucht. Hatte anfangs bedenken ob das so klappen kann wie wir uns das erhofft haben, aber es funktioniert tatsächlich wie wir es brauchen ( heißt es werden die sourcen, welche innerhalb des loops aufgerufen werden ( also Methoden, Fubas und Forms ), durchsucht. ).

würde aber empfehlen die Tiefe nicht allzu groß zu setzen... das kann sonst unter umständen extrem lange dauern...
SaskuAc
Specialist
 
Beiträge: 240
Registriert: 01.06.2015, 10:16
Dank erhalten: 24 mal
Ich bin: Entwickler/in

Re: Interne Tabelle selektieren

Beitragvon ralf.wenzel » 19.03.2019, 08:32

Die Laufzeit wird auch der Grund sein, warum die SAP das nicht eingebaut hat. Ist aber ein interessanter Ansatz. Aber warum als Modifikation und nicht als eigene Prüfung?


Ralf
ralf.wenzel
Top Expert
 
Beiträge: 3374
Registriert: 18.09.2004, 13:03
Wohnort: Hamburg
Dank erhalten: 213 mal
Ich bin: Freiberufler/in

Re: Interne Tabelle selektieren

Beitragvon SaskuAc » 19.03.2019, 10:26

ralf.wenzel hat geschrieben:Die Laufzeit wird auch der Grund sein, warum die SAP das nicht eingebaut hat. Ist aber ein interessanter Ansatz. Aber warum als Modifikation und nicht als eigene Prüfung?


Vermutlich. Man muss halt bedenken, dass einige Sourcen unter umständen mehrmals durchsucht werden könnten.. daher die Tiefe nicht allzu "Hoch" setzen..

Warum genau eine Modifikation weiß ich leider nicht, bin selber erst später zu dem "Projekt" dazu gekommen, da war die Klasse schon modifiziert. glaube, dass man nicht 2 mehr oder wenige gleiche Prüfungen haben wollte und deswegen die Klasse modifiziert hat.
SaskuAc
Specialist
 
Beiträge: 240
Registriert: 01.06.2015, 10:16
Dank erhalten: 24 mal
Ich bin: Entwickler/in

Re: Interne Tabelle selektieren

Beitragvon DeathAndPain » 19.03.2019, 11:47

Ralf hat geschrieben:Auweh. Also, einen LOOP AT....WHERE.... macht man nicht über Standardtabellen

An welcher Stelle habe ich geschrieben, dass die verwendeten internen Tabellen Standardtabellen sein sollen?!?

Selbstverständlich sollte man dafür sortierte Tabellen verwenden. In diesem Rahmen ist das von mir geschilderte Beispiel definitiv gültig.

ewx hat geschrieben:Das ist die Code-Inspector-Prüfung "Geschachtelte Schleifen" aus der Gruppe "Performance-Prüfungen".

Ja, ok, wenn man explizit den Code Inspector startet, dann mag der einem in dieser Richtung Vorschläge machen. Die reguläre Programmprüfungen, die teils mit Pragmas ausblendbar sind, haben sowas nicht dabei. Noch nicht mal mit Pragma.

black_adept hat geschrieben:Und wenn einen die Prüfung stört einfach die innere Schleife in eine eigene Modularisierungseinheit refactoren...
Ralf hat geschrieben:Das ist in der Tat ein Problem: Sowas erkennt die Prüfung leider nicht.

Sowas wird sich doch von ganz alleine immer wieder ergeben. Wenn ich mir ein durchschnittliches Programm anschaue, wieviel Ebenen die Aufruftiefe da umfasst, da kann mir keiner erzählen, dass es nicht häufig vorkommt, dass in irgendeinem in der Aufrufhierarchie weiter unten liegenden Codestück auch mal ein kleiner LOOP drin ist. Darum darf man sich als Aufrufer ja noch nicht einmal kümmern, weil ja das Paradigma der Kapselung und Geheimhaltung gilt.

Das ist aber auch alles ganz normal. Es ist ja auch immer die Frage, was für LOOPS das sind. Wenn ich mir da weiter unten aus einer sortierten oder gehashten Tabelle 5 Einträge erloope oder die interne Tabelle insgesamt nur 4 Einträge enthält, dann ist das überhaupt kein Problem.

Und es ist nicht nur kein Problem, sondern, wie gesagt, je nach Aufgabenstellung sogar notwendig.
DeathAndPain
Expert
 
Beiträge: 972
Registriert: 05.05.2006, 10:14
Dank erhalten: 222 mal
Ich bin: Entwickler/in


Zurück zu ABAP® für Anfänger

  Aktuelle Beiträge   
Steuerliches Abgangsland in Verkaufsbeleg ändern
vor 20 Stunden von Julia611 1 Antw.
XML hochladen, Abschnitte suchen, Abschnitte als XML zurück
Gestern von deejey 1 Antw.
(LKW)Bedarfsvorschau je Debitor
vor 3 Tagen von wreichelt 5 Antw.
Lieferplan, Einteilungen, Feinabrufe
vor 4 Tagen von bapimueller 0 Antw.
gelöst Smartforms Struktur rechtsbündig
vor 4 Tagen von qyurryus 3 Antw.

  Ähnliche Beiträge beta
Einträge aus DB-Tabelle paketweise selektieren
29.08.2008, 08:37 von euro2008 2 Antw.
Programm RLLNACH1 nach Z-Tabelle selektieren lassen
13.02.2007, 14:58 von max1 0 Antw.
alv grid interne tabelle mit transparenter tabelle abgleiche
07.05.2008, 07:30 von hadde85 10 Antw.
Daten aus DB-Tabelle in interne Tabelle kopieren
07.02.2008, 12:38 von TWP 1 Antw.
Vergleich interne Tabelle mit Datenbank Tabelle
27.01.2014, 14:14 von a-dead-trousers 2 Antw.

 

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder