Interne Tabelle selektieren

Getting started ... Alles für einen gelungenen Start.
15 Beiträge Seite 1 von 1
15 Beiträge Seite 1 von 1

Interne Tabelle selektieren

Beitrag von flo1304 (ForumUser / 1 / 0 / 0 ) » 14. Mär 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


Re: Interne Tabelle selektieren

Beitrag von LostDarkness (ForumUser / 44 / 13 / 1 ) » 14. Mär 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

Re: Interne Tabelle selektieren

Beitrag von qyurryus (ForumUser / 20 / 18 / 4 ) » 14. Mär 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[ kunnr= <table1>-kunnr] ).
    " 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.

Re: Interne Tabelle selektieren

Beitrag von DeathAndPain (Top Expert / 1042 / 122 / 228 ) » 15. Mär 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.

Re: Interne Tabelle selektieren

Beitrag von ralf.wenzel (Top Expert / 3401 / 147 / 218 ) » 16. Mär 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

Re: Interne Tabelle selektieren

Beitrag von DeathAndPain (Top Expert / 1042 / 122 / 228 ) » 18. Mär 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.

Re: Interne Tabelle selektieren

Beitrag von ralf.wenzel (Top Expert / 3401 / 147 / 218 ) » 18. Mär 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

Re: Interne Tabelle selektieren

Beitrag von ewx (Top Expert / 3943 / 162 / 360 ) » 18. Mär 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.

Re: Interne Tabelle selektieren

Beitrag von ralf.wenzel (Top Expert / 3401 / 147 / 218 ) » 18. Mär 2019 17:10

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


Ralf

Re: Interne Tabelle selektieren

Beitrag von black_adept (Top Expert / 3239 / 54 / 565 ) » 18. Mär 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...

Folgende Benutzer bedankten sich beim Autor black_adept für den Beitrag:
DeathAndPain

live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Interne Tabelle selektieren

Beitrag von ralf.wenzel (Top Expert / 3401 / 147 / 218 ) » 18. Mär 2019 19:26

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


Ralf

Re: Interne Tabelle selektieren

Beitrag von SaskuAc (Specialist / 250 / 21 / 29 ) » 19. Mär 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...

Re: Interne Tabelle selektieren

Beitrag von ralf.wenzel (Top Expert / 3401 / 147 / 218 ) » 19. Mär 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

Re: Interne Tabelle selektieren

Beitrag von SaskuAc (Specialist / 250 / 21 / 29 ) » 19. Mär 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.

Re: Interne Tabelle selektieren

Beitrag von DeathAndPain (Top Expert / 1042 / 122 / 228 ) » 19. Mär 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.

Seite 1 von 1

Aktuelle Forenbeiträge

ABAP Clean Code
vor 49 Minuten von deejey 54 / 1335
Funktionsbaustein READ_TEXT
vor 17 Stunden von Tron 2 / 121
Code lesen
Gestern von GastX 5 / 1464
CL_GUI_TEXTEDIT im Subscreen
Gestern von black_adept 2 / 84

Unbeantwortete Forenbeiträge

HowTo? Reisekosten PR05: Land hinzufügen
vor 2 Tagen von Florian9999 1 / 75
eMail Versand Faktura, falscher Betreff in eMail
vor 2 Tagen von bapimueller 1 / 74
[GELÖST] Kundenhierarchien in der Preisfindung
vor 3 Tagen von SAP_ENTWICKLER 1 / 84
[GELÖST] Feld KNVV-BOIDT
vor einer Woche von SAP_ENTWICKLER 1 / 65