Zweifachen Loop vermeiden

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

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

Zweifachen Loop vermeiden

Beitrag von Barney (Specialist / 104 / 20 / 9 ) »
Hallo zusammen,

ich steh mal wieder auf dem Schlauch. Ich habe eine interne Tabelle (lt_goodsmvt_item) mit allen Positionen, für die ich einen Wareneingang buchen möchte. Doch die Positionen kann unterschiedliche externe Lieferscheinnummern (lt_goodsmvt_item-deliv_numb) enthalten. Ich möchte nun die Wareneingänge je Lieferscheinnummer buchen (weil das ein Kopffeld ist und sonst die Rechnungsprüfung durcheinander kommt).

Mein Ansatz wäre jetzt, mir eine Hilfstabelle mit allen externen Lieferscheinnummern aufzubauen (lt_deliv_numb). Dann könnte ich über die Hilfstabelle loopen und in dem Loop würde ich dann über lt_goodsmvt_item loopen mit der entsprechenden WHERE-Bedingung:

Code: Alles auswählen.

Loop at lt_deliv_numb into ls_deliv_numb. 

  refresh lt_goodsmvt_final. 

  Loop at lt_goodsmvt_item into ls_goodsmvt_item where VBELN = ls_deliv_numb-vbeln. 

    append ls_goodsmvt_item to lt_goodsmvt_final. 

  endloop. 

  CALL FUNCTION 'BAPI_GOODSMVT_CREATE' ...

endloop.   "Loop at lt_deliv_numb into ls_deliv_numb. 

Ich frage mich, ob es da keinen geschickteren Ansatz gibt. Any Ideas?

Danke im Voraus.

Tot ziens

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


Re: Zweifachen Loop vermeiden

Beitrag von Thanatos82 (Expert / 699 / 32 / 123 ) »
Hi Barney,

also vorweg: REFRESH ist obsolet. es sollte nur noch clear verwendet werden.
Und sofern du deine item Tabelle nach den Lieferscheinnummern vorsortieren kannst / möchtest wäre der Befehl AT NEW vbeln wohl die gesuchte kürzere Lösung.
Gruß,
der Matze

Re: Zweifachen Loop vermeiden

Beitrag von a-dead-trousers (Top Expert / 4394 / 223 / 1182 ) »
Je nachdem wie groß die Tabellen sind kann man bei einer sortierten Tabelle mit READ TABLE BINARY SEARCH eine beachtliche Steigerung der Zugriffsgeschwindigkeit erreichen.

In etwa so:

Code: Alles auswählen.

SORT it_itab2 BY feld1.
LOOP AT it_itab1 ASSIGNING <ls_itab1>.
  READ TABLE it_itab2 TRANSPORTING NO FIELDS BINARY SEARCH
    WITH KEY feld1 = <ls_itab1>-feld1.
  IF sy-subrc EQ 0.
    LOOP AT it_itab2 ASSIGNING <ls_itab2> FROM sy-tabix.
      IF <ls_itab2>-feld1 NE <ls_itab1>-feld1.
        EXIT. 
      ENDIF.
* Verarbeitung der gefundenen Einträge
    ENDLOOP.
  ENDIF.
ENDLOOP.
Und falls es jetzt einen 'Aufschrei' der anderen Top-Experten hier im Forum gibt:
Das Beispiel ist aus der ABAP-Performance Schulung BC 490 8)

lg ADT
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: Zweifachen Loop vermeiden

Beitrag von ewx (Top Expert / 4842 / 310 / 638 ) »
Auch mit "LOOP index" ist eine Geschwindigkeitssteigerung möglich.
http://www.tricktresor.de/blog/geschach ... -tabellen/

Am Prinzip der geschachtelten Zugriffe ändert sich jedoch nichts.

Möglich wäre noch eine tiefe Struktur in der die zugehörigen Einträge je Zeile verwaltet werden:
TYPES: BEGIN OF ty_item,
matnr,
menge,
END OF ty_item.
TYPES: BEGIN OF ty_data,
delivery_number type vbeln,
items TYPE STANDARD TABLE OF ty_item WITH DEFAULT KEY,
END OF ty_data.

Setzt natürlich eine entsprechende Aufbereitung voraus.

Re: Zweifachen Loop vermeiden

Beitrag von Barney (Specialist / 104 / 20 / 9 ) »
Hallo zusammen,

Danke zunächst für das Feedback.

Da ich auch gerne was neues lerne, würde ich die Variante mit dem AT...ENDAT versuchen.

Nach dem Studium der Doku würde ich statt AT NEW besser AT END OF nehmen, weil die Buchung ja am Ende einer Tabellengruppe erfolgen soll.

Also:

Code: Alles auswählen.


SORT lt_goodsmvt_item BY deliv_numb ASCENDING.

LOOP AT lt_goodsmvt_item INTO ls_goodsmvt_final.

APPEND ls_goodsmvt_final TO lt_goodsmvt_final.

  AT END OF deliv_numb.
  CALL FUNCTION 'BAPI_GOODSMVT_CREATE'.
  CLEAR lt_goodsmvt_final.
  ENDAT.

  ENDLOOP.
Habe ich das so richtig verstanden?

Tot ziens

Re: Zweifachen Loop vermeiden

Beitrag von a-dead-trousers (Top Expert / 4394 / 223 / 1182 ) »
Etwas, das die Hilfe mitunter verschweigt, weswegen ich AT END bzw. AT NEW auch nicht einsetze:
Alle Felder die in der Struktur LINKS von dem Feld das mit AT geprüft wird, werden implizit ebenfalls geprüft. d.h. Wenn sich da was ändert, aber das eigentlich Feld nicht, wird trotzdem die AT NEW Verarbeitung aufgerufen.
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: Zweifachen Loop vermeiden

Beitrag von Barney (Specialist / 104 / 20 / 9 ) »
a-dead-trousers hat geschrieben:Etwas, das die Hilfe mitunter verschweigt, weswegen ich AT END bzw. AT NEW auch nicht einsetze:
Alle Felder die in der Struktur LINKS von dem Feld das mit AT geprüft wird, werden implizit ebenfalls geprüft. d.h. Wenn sich da was ändert, aber das eigentlich Feld nicht, wird trotzdem die AT NEW Verarbeitung aufgerufen.
Ups, ein wichtiger Hinweis. Denn DELIV_NUMB ist das 107. Feld von 126 in der Struktur BAPI2017_GM_ITEM_CREATE. D.h. - wenn ich Deinen Einwand richtig verstehe - dass sich nur eines der 106 anderen Feld links von DELIV_NUMB sich ändern muss, damit die AT-Verarbeitung einsetzt.

In diesem Fall scheint mir das nicht praktikabel... :D

Tot ziens

Re: Zweifachen Loop vermeiden

Beitrag von Murdock (Specialist / 123 / 58 / 10 ) »
a-dead-trousers hat geschrieben:Etwas, das die Hilfe mitunter verschweigt, weswegen ich AT END bzw. AT NEW auch nicht einsetze:
Alle Felder die in der Struktur LINKS von dem Feld das mit AT geprüft wird, werden implizit ebenfalls geprüft. d.h. Wenn sich da was ändert, aber das eigentlich Feld nicht, wird trotzdem die AT NEW Verarbeitung aufgerufen.
Das steht schon in der Hilfe: " Die Gruppenwechsel finden statt, wenn sich der Inhalt der Komponente compi oder einer Komponente links von compi ändert.", aber wer liest die heutzutage schon noch ;-) daher ist der Hinweis durchaus gut hier.
Ich habe deswegen mal eine komplette zweite Struktur erstellt, in der ich das entsprechende Feld ganz vorne hatte und immer schön umgeschaufelt...

Re: Zweifachen Loop vermeiden

Beitrag von JHM (Top Expert / 1197 / 1 / 197 ) »
Murdock hat geschrieben:Ich habe deswegen mal eine komplette zweite Struktur erstellt, in der ich das entsprechende Feld ganz vorne hatte und immer schön umgeschaufelt...
Man kann die AT-Verarbeitung mit Hilfsvariablen selber gestallten:

Code: Alles auswählen.

DATA: merker TYPE vbeln.
CLEAR merker.
SORT lt_goodsmvt_item BY deliv_numb ASCENDING.

LOOP AT  lt_goodsmvt_item INTO ls_goodsmvt_item.
  IF merker <> ls_goodsmvt_item-deliv_numb.
    IF merker IS NOT INITIAL.  "nicht beim erstenmal
      PERFORM bapi_call USING lt_goodsmvt_final.
      CLEAR lt_goodsmvt_final.
    ENDIF.
    merker = ls_goodsmvt_item-deliv_numb. "Lieferung merken
  ENDIF.

APPEND ls_goodsmvt_item to lt_goodsmvt_final.
ENDLOOP.

* Die letzte Lieferung wurde nicht in der Schleife angelegt, deshalb hier nach hohlen
IF sy-subrc = 0. "nur wenn es einen Schleifendurchlauf gab
  PERFORM bapi_call USING lt_goodsmvt_final.
ENDIF.

Folgende Benutzer bedankten sich beim Autor JHM für den Beitrag:
Murdock

Gruß Hendrik

Re: Zweifachen Loop vermeiden

Beitrag von Unit605 (Expert / 975 / 37 / 93 ) »
a-dead-trousers hat geschrieben:Etwas, das die Hilfe mitunter verschweigt, weswegen ich AT END bzw. AT NEW auch nicht einsetze:
Alle Felder die in der Struktur LINKS von dem Feld das mit AT geprüft wird, werden implizit ebenfalls geprüft. d.h. Wenn sich da was ändert, aber das eigentlich Feld nicht, wird trotzdem die AT NEW Verarbeitung aufgerufen.
Vielleicht hast Du ja nur die falsche SAP Hilfe?

In meiner Hilfe steht folgendes:

Gruppenstufen werden durch Anfang bzw. Ende einer Gruppe von Zeilen mit dem gleichen Inhalt in der Komponenten compi (mit i = 1, 2, ...) und in den Komponenten links von compi definiert. Die Gruppenwechsel finden statt, wenn sich der Inhalt der Komponente compi oder einer Komponente links von compi ändert.

Re: Zweifachen Loop vermeiden

Beitrag von ralf.wenzel (Top Expert / 3921 / 200 / 280 ) »
Für neuere Releases gibt es endlich etwas Zeitgemäßes:

http://scn.sap.com/community/abap/blog/ ... nal-tables
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: Zweifachen Loop vermeiden

Beitrag von Barney (Specialist / 104 / 20 / 9 ) »
Hallo Ralf,

danke für den Hinweis. Das ist in der Tat sehr interessant. Ich habe nur noch nicht die Anweisung in dem vermeintlichen zweiten Loop verstanden:

Code: Alles auswählen.

 LOOP AT GROUP <group> ASSIGNING FIELD-SYMBOL(<flight>).
    members = VALUE #( BASE members ( <flight> ) ).
  ENDLOOP.

Re: Zweifachen Loop vermeiden

Beitrag von Barney (Specialist / 104 / 20 / 9 ) »
'ne Doku zu dem VALUE-Operator habe ich auch mittlerweile gefunden...

Re: Zweifachen Loop vermeiden

Beitrag von Murdock (Specialist / 123 / 58 / 10 ) »
JHM hat geschrieben:
Murdock hat geschrieben:Ich habe deswegen mal eine komplette zweite Struktur erstellt, in der ich das entsprechende Feld ganz vorne hatte und immer schön umgeschaufelt...
Man kann die AT-Verarbeitung mit Hilfsvariablen selber gestallten:
Danke. "Standardgruppenwechselprogrammierung" ist mir aber durchaus bekannt :wink: . Ich weiß auch nicht mehr genau, warum ich das mit dem AT machen wollte / musste, aber an die zweite extra Struktur erinnere ich mich...

Re: Zweifachen Loop vermeiden

Beitrag von a-dead-trousers (Top Expert / 4394 / 223 / 1182 ) »
Unit605 hat geschrieben:Vielleicht hast Du ja nur die falsche SAP Hilfe?
In meiner Hilfe steht folgendes:
Gruppenstufen werden durch Anfang bzw. Ende einer Gruppe von Zeilen mit dem gleichen Inhalt in der Komponenten compi (mit i = 1, 2, ...) und in den Komponenten links von compi definiert. Die Gruppenwechsel finden statt, wenn sich der Inhalt der Komponente compi oder einer Komponente links von compi ändert.
Ok... Stimmt das steht bei mir auch :oops:
Ich hab das einfach überlesen (oder nicht kapiert) erst als ich hier im Forum vor ein paar Jahren davon gelesen hab, hab ich verstanden warum meine ersten Versuche mit AT immer fehlgeschlagen sind. Hab eigentlich schon von Anfang an nur mit der Lösung die JHM aufgezeigt hat gearbeitet.

@ralf: Ich auch 7.40 haben möcht!

lg ADT
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Seite 1 von 1

Vergleichbare Themen

1
Antw.
1423
Views
2
Antw.
1541
Views
Loginscreen bei RFC vermeiden
von Janosch2 » 14.12.2004 11:14 • Verfasst in ABAP® Core
6
Antw.
7533
Views
Division durch 0 vermeiden
von Gast » 18.05.2005 16:47 • Verfasst in ABAP® für Anfänger
2
Antw.
310
Views
Vor Integer Leerzeichen vermeiden
von User1234 » 09.08.2021 08:37 • Verfasst in ABAP® für Anfänger
7
Antw.
2756
Views
Anlegen doppelter Datensätze vermeiden
von SLUK » 26.02.2018 20:48 • 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

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.

Unbeantwortete Forenbeiträge

aRFC im OO-Kontext
vor 4 Wochen von ralf.wenzel 1 / 1519
Hilfe bei SWEC/SWE2
letzen Monat von retsch 1 / 8132