FOR mit CORRESPONDING

Alles rund um die Sprache ABAP®: Funktionsbausteine, Listen, ALV
12 Beiträge • Seite 1 von 1
12 Beiträge Seite 1 von 1

FOR mit CORRESPONDING

Beitrag von rob_abc (Specialist / 139 / 37 / 57 ) »
Hallo zusammen,

Ich würde gerne FOR mit CORRESPONDING kombinieren, aber zusätzlich noch für einen oder mehrere Werte eine Konvertierung durchführen. Geht das irgendwie? Wenn ich FOR verwende, müsste ich alle Felder einzeln auflisten und kann nicht auf CORRESPONDING zurückgreifen.

In einem LOOP kann ich problemlos erst ein CORRESPONDING machen und anschliessend die Felder konvertieren

Code: Alles auswählen.

REPORT.

CLASS lcl_report DEFINITION CREATE PRIVATE.

  PUBLIC SECTION.
    TYPES: BEGIN OF ty_1,
             werks TYPE string,
             desc  TYPE string,
           END OF ty_1.
    TYPES: BEGIN OF ty_2,
             werks       TYPE string,
             longer_desc TYPE string,
           END OF ty_2.
    TYPES tty_plants        TYPE SORTED TABLE OF ty_1 WITH UNIQUE KEY werks.
    TYPES tty_plants_longer TYPE SORTED TABLE OF ty_2 WITH UNIQUE KEY werks.

    CLASS-METHODS main.

    CLASS-METHODS enhance
      IMPORTING i_desc          TYPE string
      RETURNING VALUE(r_result) TYPE string.

ENDCLASS.


CLASS lcl_report IMPLEMENTATION.
  METHOD main.
    DATA(plants) = VALUE tty_plants( ( werks = '1000' desc = 'Plant 1' )
                                     ( werks = '2000' desc = 'Plant 2' ) ).

    cl_demo_output=>write( plants ).

    " Konvertierung von DESC findet nicht statt
    DATA plants_longer TYPE tty_plants_longer.
    plants_longer = VALUE #( FOR <x> IN plants
                             ( CORRESPONDING #( <x> MAPPING longer_desc = desc ) ) ).
    cl_demo_output=>write( plants_longer ).

    " TBL kann auhc direkt kopiert werden.
    plants_longer = CORRESPONDING #( plants MAPPING longer_desc = desc ).
    cl_demo_output=>write( plants_longer ).

    " Ohne CORRESPONDING müssen alle Felder aufgelistet werden, was viele sein können
    " Aber Felder können konvertiert werden
    DATA plants_longer2 TYPE tty_plants_longer.
    plants_longer2 = VALUE #( FOR <x> IN plants
                              ( werks       = <x>-werks
                                longer_desc = enhance( <x>-desc ) ) ).
    cl_demo_output=>write( plants_longer2 ).

*    " Zusätzliches Klammernpaar fügt zusätzliche Zeile ein
*    DATA plants_longer3 TYPE tty_plants_longer.
*    plants_longer3 = VALUE #( FOR <x> IN plants
*                            ( CORRESPONDING #( <x> ) )
*                            ( longer_desc = enhance( <x>-desc ) ) ).
*    cl_demo_output=>write( plants_longer3 ).

*    " Im Mapping können Werte nicht verändert werden
*    DATA plants_longer4 TYPE tty_plants_longer.
*    plants_longer4 = VALUE #( FOR <x> IN plants
*                             ( CORRESPONDING #( <x> MAPPING longer_desc = enhance( desc ) ) ) ).
*    cl_demo_output=>write( plants_longer4 ).

    " Nur im LOOP kann ich es mir ersparen, evtl. hunderte Felder aufzulisten
    DATA plants_longer5 TYPE tty_plants_longer.
    DATA new_line       TYPE ty_2.
    LOOP AT plants ASSIGNING FIELD-SYMBOL(<line>).
      new_line = CORRESPONDING #( <line> ).
      new_line-longer_desc = enhance( <line>-desc ).
      INSERT new_line INTO TABLE plants_longer5.
    ENDLOOP.
    cl_demo_output=>write( plants_longer5 ).

    cl_demo_output=>display( ).
  ENDMETHOD.

  METHOD enhance.
    r_result = |{ i_desc } in long|.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  lcl_report=>main( ).

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


Re: FOR mit CORRESPONDING

Beitrag von LeMinion (ForumUser / 21 / 1 / 7 ) »
Moin.
Wenn im (klassischen) Loop möglich ist, was Du willst/brauchst, wieso willst Du eine FOR-Schleife bauen? Ernst gemeinte und einfach nur aus Interesse gestellte Frage.
Ansonsten könntest Du sowas hier bauen:

Code: Alles auswählen.

DATA(longerPlants) = VALUE tty_plants_longer(
  FOR plant IN plants
  ( VALUE #( BASE CORRESPONDING #( plant )  desc = enhance( plant-descending ) ) )
).
Viele Grüße,
LeMinion

Folgende Benutzer bedankten sich beim Autor LeMinion für den Beitrag:
rob_abc


Re: FOR mit CORRESPONDING

Beitrag von msfox (Specialist / 391 / 59 / 76 ) »
LeMinion hat geschrieben:
02.05.2025 11:46
Loop möglich ist, was Du willst/brauchst, wieso willst Du eine FOR-Schleife bauen?
Weils Leute gibt, die das GEIL finden... Solche Experten hat bei uns auch, die bestehenden Code unbedingt von LOOP auf FOR umstellen müssen, damit alles in einer Anweisung steht. Mache ich inzwischen auch, damit es im Coding einheitlich bleibt und nicht nachträglich meine Coding immer umgeschrieben wird.

Re: FOR mit CORRESPONDING

Beitrag von rob_abc (Specialist / 139 / 37 / 57 ) »
LeMinion hat geschrieben:
02.05.2025 11:46

Code: Alles auswählen.

DATA(longerPlants) = VALUE tty_plants_longer(
  FOR plant IN plants
  ( VALUE #( BASE CORRESPONDING #( plant )  desc = enhance( plant-descending ) ) )
).
Ach, VALUE im FOR mit BASE CORRESPONDING, vielen Dank.

LeMinion hat geschrieben:
02.05.2025 11:46
Wenn im (klassischen) Loop möglich ist, was Du willst/brauchst, wieso willst Du eine FOR-Schleife bauen?
Weil ich damit viel prägnanter ausdrücken kann was passiert und damit für den Leser später leichter verständlich ist. Das mit einer Reihe Hilfsvariablen und LOOP zu bauen geht natürlich, dauert in dem Fall aber meiner Meinung nach länger in der Erfassung.
Hier das Beispiel, bei dem ich es eingebaut habe. Variablennamen sind anonymisiert.

Code: Alles auswählen.

      e_export = VALUE #( FOR <x> IN mat->get_itab( )
        ( value #( base corresponding #( <x> ) 
                   menge  = zconverter=>to_string( CONV #( <x>-menge ) ) ) ) ).

Re: FOR mit CORRESPONDING

Beitrag von black_adept (Top Expert / 4134 / 131 / 956 ) »
rob_abc hat geschrieben:
03.05.2025 08:25
Weil ich damit viel prägnanter ausdrücken kann was passiert und damit für den Leser später leichter verständlich ist. Das mit einer Reihe Hilfsvariablen und LOOP zu bauen geht natürlich, dauert in dem Fall aber meiner Meinung nach länger in der Erfassung.

Code: Alles auswählen.

      e_export = VALUE #( FOR <x> IN mat->get_itab( )
        ( value #( base corresponding #( <x> ) 
                   menge  = zconverter=>to_string( CONV #( <x>-menge ) ) ) ) ).
Also bei den Aussagen "prägnanter Ausdrückbar", "für den Leser leichter verständlich" und "dauert länger in der Erfassung" (? Erfassung = Zeit das zu Coden ? ) und "Reihe von Hilfsvariablen" hätte ich noch Erklärungsbedarf.

Das hier wäre die Alternative

Code: Alles auswählen.

      loop at me->get_itab ASSIGNING FIELD-SYMBOL(<ls_itab>).
        append value #( base corresponding #( <ls_itab> ) 
                        menge  = zconverter=>to_string( CONV #( <ls_itab>-menge ) ) ) to e_export.
      endloop.
  • - Hilfsvariablen: Eine Hilfsvariable. Und irgendwie finde ich, dass dein "<x>" auch eine Hilfsvariable ist.
  • - Erfassungszeit: Das Coding hat mich nicht mehr Zeit gekostet als es die FOR-Version gekostet hätte und da du hier einen Forumsbeitrag zu diesem Thema erstellt hast wette ich, dass dich das Ganze mit LOOP schneller zum Ziel geführt hätte. Zumindest für dieses Mal -aber zukünftig sollte das schneller gehen, wobei ich wette, dass auch du für den LOOP nicht wesentlich mehr Zeit brauchst als für ein FOR.
  • - "prägnanter Ausdrückbar": Da hast du mich leider abgehängt, was an dem FOR denn nun prägnanter ist als am LOOP. Könntest du das bitte noch mal genauer erläutern.
  • - "für den Leser leichter verständlich": Das ist einerseits sehr subjektiv - ich z.B. kann das mit dem LOOP schneller verinnerlichen als das FOR. Andererseits finde ich, dass ich in einem LOOP besser Breakpunkte verteilen kann wenn in <ls_itab> halt ein spezieller Wert drin steht der mir Probleme bereitet. Und abschließend programmieren wir doch für Leser, die ein Mindestmaß an Wissen mitbringen und nicht für Idioten. Und für erstere sollte beides gleich leicht verständlich sein.
Meine Meinung wäre also, dass die Versionen mit FOR und LOOP gleichwertig nebeneinander stehen und nicht, dass das FOR in irgendeiner Art besser oder vorziehbar ist.

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

live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: FOR mit CORRESPONDING

Beitrag von msfox (Specialist / 391 / 59 / 76 ) »
black_adept hat geschrieben:
05.05.2025 10:32
- "für den Leser leichter verständlich": Das ist einerseits sehr subjektiv - ich z.B. kann das mit dem LOOP schneller verinnerlichen als das FOR. Andererseits finde ich, dass ich in einem LOOP besser Breakpunkte verteilen kann wenn in <ls_itab> halt ein spezieller Wert drin steht der mir Probleme bereitet.
Recht hat er... Debuggen geht da einfacher, weil es ebenen mehrere Befehle sind und nicht in einem Schritt alles auf einmal stattfindet.
+ Wenn man mit LOOP arbeitet, rückt einen der Pretty Printer Einiges schön. Beim FOR muss man es selbst schieben.

Re: FOR mit CORRESPONDING

Beitrag von rob_abc (Specialist / 139 / 37 / 57 ) »
Mit Erfassungszeit meine ich nicht die Zeit zum Schreiben, sondern die Zeit wie lange ich brauche, um dich Absicht des gelesenen Codings zu verstehen. Diese ist hier bei der FOR-Schleife geringer, da sofort klar ist, dass E_EXPORT einen neuen Inhalt erhält. Es ist das erste was dem Leser ins Auge springt: E_EXPORT = ...
Wenn mich die Details dazu nicht interessieren, kann ich über den Rest drüber hinweggehen und muss mich darum gar nicht kümmern, die in diesem Fall ja nur das Kopieren einer itab + ein paar Konvertierungen sind.

Beim LOOP muss ich schauen, was genau im LOOP passiert. Ich erfahre erst ganz am Ende, nachdem ich alles Coding gelesen habe, dass eigentlich nur E_EXPORT befüllt wird.

Prinzipiell stimme ich deinen Ausführungen zum LOOP zu. Ich nutze LOOP selbst auch sehr gerne, nur in diesem Fall nicht.

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


Re: FOR mit CORRESPONDING

Beitrag von msfox (Specialist / 391 / 59 / 76 ) »
rob_abc hat geschrieben:
05.05.2025 21:48
Wenn mich die Details dazu nicht interessieren, kann ich über den Rest drüber hinweggehen
Ja genau zum Zeitpunkt der Entwicklung. Aber wehe dem, irgendwo ist ein Fehler drin und dieser soll gefunden werden. Dann muss gedanktlich das ganze FOR zerlegen, weil man es ja nicht debuggen kann.
Oder es fehlt noch was. Ich habe letzte Woche auch erst so ein FOR gebaut. Dann kam eine neue Anforderung, was im FOR so nicht ging, weil die Logik noch gegen unterschiedliche Tabelle geprüft werden soll. Ja, könnte man dann ggf. in eine Methode auslagern. Aber, dass hatte ich letztens beim Kollegen, der dann in der Methode wieder von der Datenbank gelesen hat. Auch was verschlimmerbessert und dann die bis dahin vorhandene Pufferung umgangen.

Re: FOR mit CORRESPONDING

Beitrag von black_adept (Top Expert / 4134 / 131 / 956 ) »
rob_abc hat geschrieben:
05.05.2025 21:48
Mit Erfassungszeit meine ich nicht die Zeit zum Schreiben, sondern die Zeit wie lange ich brauche, um dich Absicht des gelesenen Codings zu verstehen. Diese ist hier bei der FOR-Schleife geringer, da sofort klar ist, dass E_EXPORT einen neuen Inhalt erhält. Es ist das erste was dem Leser ins Auge springt: E_EXPORT = ...
Wenn mich die Details dazu nicht interessieren, kann ich über den Rest drüber hinweggehen und muss mich darum gar nicht kümmern, die in diesem Fall ja nur das Kopieren einer itab + ein paar Konvertierungen sind.
Ich gebe zu, dass ich für sowas noch Kommentare verwende.
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: FOR mit CORRESPONDING

Beitrag von rob_abc (Specialist / 139 / 37 / 57 ) »
Ich möchte an der Stelle ja niemanden vorschreiben, wie er zu entwickeln hat. Fremdes Coding ändere ich auch nur im Fehlerfall oder wenn vom Fachbereich Performance bemängelt wird.

Für mich habe ich einfach festgestellt, dass ich FOR-Schleifen hilfreich und sinnvoll finde, wenn es um einfaches kopieren von ITABs geht, wo CORRESPONDING mit MAPPING nicht ausreicht. Das kann z.B. ein WHERE sein, mit dem ich die Anzahl der Einträge einschränke, oder wie in dem obigen Beispiel eine Konvertierung.

Wenn in diesen einfachen FOR-Schleifen doch mal der Debugger gebraucht wird, kann dieser auch auf "Step Size: Expression" umgestellt werden. Damit lassen sich alle "neuen" Ausdrücke Schrittweise debuggen.

Ich denke wir sind auch inhaltlich gar nicht so weit auseinander. Die Verarbeitung von Daten, z.B. eine Liste von MATNRs und Aufruf von MATERIAL MAINTAIN DARK, würde ich persönlich auch nicht in eine FOR-Schleife packen. Komplizierte REDUCE-Ausdrücke gibt es doch auch nur zum ärgern von Kollegen =)

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


Re: FOR mit CORRESPONDING

Beitrag von sap_enthusiast (Specialist / 106 / 29 / 25 ) »
rob_abc hat geschrieben:
09.05.2025 08:23
Komplizierte REDUCE-Ausdrücke gibt es doch auch nur zum ärgern von Kollegen =)
Da muss ich kurz entgegen sprechen, weil mir persönlich REDUCE Ausdrücke schon mal geholfen haben, wenn man innerhalb eines Loops mehrere Werte zu einem Haupteintrag aus mehreren Tabellen aggregieren soll. Damit lässt sich halt ein größer ausgelegtes LOOP innerhalb eines LOOPs vermeiden. Nested Loop ist weiterhin ein Problem mit FOR klar aber für diesen Zweck finde ich REDUCE ziemlich gescheit, auch wenn sich Fehler, wie bereits erwähnt, nicht unbedingt so einfach ermitteln lassen.
Erstmal aber ein schönes Wochenende!

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


Re: FOR mit CORRESPONDING

Beitrag von DeathAndPain (Top Expert / 1970 / 264 / 416 ) »
black_adept hat geschrieben:
05.05.2025 10:32
Das hier wäre die Alternative

Code: Alles auswählen.

      loop at me->get_itab ASSIGNING FIELD-SYMBOL(<ls_itab>).
        append value #( base corresponding #( <ls_itab> ) 
                        menge  = zconverter=>to_string( CONV #( <ls_itab>-menge ) ) ) to e_export.
      endloop.
Deine Alternative ist nicht ganz vollwertig. Wenn e_export keine Standardtabelle ist, wird Dein APPEND spektakulär auf die Bretter gehen, während die Originallösung mit jeder Tabellenart funktioniert. Das kannst Du retten, indem Du ihn in ein INSERT INTO TABLE wandelst. Dennoch ist die Performance abseits von Standardtabellen schlechter. Besonders bedeutsam wird das bei einer Hashtabelle, weil bei jedem Einfügen einer Tabellenzeile die Hashwerte aller Tabellenzeilen neu berechnet werden müssen. Deshalb empfiehlt die SAP, Hashtabellen nur zu verwenden, wenn diese in einem Rutsch aufgebaut werden können. Die Originallösung mit dem FOR leistet genau das.
rob_abc hat geschrieben:Wenn in diesen einfachen FOR-Schleifen doch mal der Debugger gebraucht wird, kann dieser auch auf "Step Size: Expression" umgestellt werden. Damit lassen sich alle "neuen" Ausdrücke Schrittweise debuggen.
Wow, das wusste ich gar nicht. Vielen Dank dafür!
robn_abc hat geschrieben:Mit Erfassungszeit meine ich nicht die Zeit zum Schreiben, sondern die Zeit wie lange ich brauche, um dich Absicht des gelesenen Codings zu verstehen. Diese ist hier bei der FOR-Schleife geringer, da sofort klar ist, dass E_EXPORT einen neuen Inhalt erhält. Es ist das erste was dem Leser ins Auge springt: E_EXPORT = ...
Genau so sehe ich das auch. Und dieses Argument gilt durchaus auch für einen REDUCE. Die Verwendung von REDUCE zeigt dem Leser sofort, wo der Programmierer hin will. Das mit einem LOOP nachzubilden ist nicht so trivial möglich wie bei dem FOR, und da muss man dann erst mal schauen, was da überhaupt in dem LOOP passiert.
rob_abc hat geschrieben:Damit lässt sich halt ein größer ausgelegtes LOOP innerhalb eines LOOPs vermeiden.
Auch ein gutes Argument. Verschachtelte LOOPs lassen sich nicht immer vermeiden, aber da wird es schnell unübersichtlich, worauf sich welcher ENDLOOP bezieht und was da geschachtelt ist. Ein LOOP, der FOR oder REDUCE enthält, bleibt gut sichtbar strukturiert.
msfox hat geschrieben:Dann kam eine neue Anforderung, was im FOR so nicht ging, weil die Logik noch gegen unterschiedliche Tabelle geprüft werden soll.
Die Anforderung ist das Erste im Software Life Cycle. Wenn nach erfolgter Programmierung die Anforderung geändert wird, ist es ganz normal, dass die Programmierung umgebaut werden muss. Deswegen soll man ja darauf achten, vorher alle Anforderungen glatt zu ziehen, denn je später im Cycle sie sich ändern, desto teurer wird die Korrektur. Primitiver zu programmieren aus vorauseilender Angst, dass das Programm möglicherweise in Zukunft mal anders arbeiten soll als gegenwärtig gewünscht, halte ich jedenfalls dann für kontraproduktiv, wenn diese Änderung noch nicht absehbar ist.
msfox hat geschrieben:+ Wenn man mit LOOP arbeitet, rückt einen der Pretty Printer Einiges schön. Beim FOR muss man es selbst schieben.
Die schlechtere Programmiervariante wählen, weil man zu faul ist, den besseren Code selber vernünftig einzurücken? Hmm... Womit natürlich nicht gesagt ist, dass ein endlos komplexer FOR oder REDUCE stets die bessere Wahl sein muss. Ich will an dieser Stelle nur darauf hinaus, dass ich das mit dem Einrücken für kein valides Argument halte. Ich pflege da nach der Devise vorzugehen: wenn ich sofort weiß, wie ich das als FOR bzw. REDUCE bauen muss, dann ist die Struktur einfach genug, so dass sich das auch lohnt. Wenn ich erst mal einen REDUCE-Prototypcode bauen und dann daran herumfeilen müsste, um ihn Stück für Stück dahin zu bringen, wo ich hin möchte, dann ist der LOOP meist nicht nur wegen der Entwicklungszeit effizienter, sondern auch hinsichtlich der Lesbarkeit des Ergebnisses.

Ich habe im Pretty Printer das Einrücken ohnehin ausgestellt, da der vieles suboptimal macht. Wissend, dass stets das Risiko besteht, dass später einer kommt und mit dem normalen Pretty Printer über meinen Code drüberbürstet.

Seite 1 von 1

Aktuelle Forenbeiträge

RFC vs. ODATA
vor 6 Tagen von DeathAndPain 8 / 2285
FUBA 'HR_INFOTYPES_OPERATION'
vor 6 Tagen von DeathAndPain 2 / 1395
Frage zur redefinierten Methode
vor einer Woche von ralf.wenzel 12 / 2681

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.