Knobelaufgabe ( August 2021 )

Alles Rund um SAP®.
7 Beiträge • Seite 1 von 1
7 Beiträge Seite 1 von 1

Knobelaufgabe ( August 2021 )

Beitrag von black_adept (Top Expert / 3701 / 78 / 771 ) »
Moin allerseits,

im englischen gibt es ein Konzept namens "Creative limitation", welches grob behauptet, dass sich die Kreativität erhöht, wenn man sich selbst Beschränkungen unterwirft.
Damit kommen wir auch schon zu unserer Situation im August:
Ihr seit als Entwickler beschäftigt, aber der Entwicklungsleiter ist mehr als nur leicht paranoid veranlagt und hat entschieden, dass der Befehl "MOVE-CORRESPONDING" und der Ausdruck "CORRESPONDING" zu gefährlich für euch Entwickler ist, und dass die Verwendung davon politische und religiöse Nachteile verursacht. Deshalb hat er eine Codeinspektorprüfung gebaut, die jede Eigenentwicklung ablehnt, die doch eine Verwendung findet.
In eurem Programm benötigt ihr aber ein solches Konstrukt. Eure Aufgabe ist es nun die Methode "korresponding" mit Leben zu füllen, so dass die Ausgabe "grün" wird.

Hier ist eure Kreativität gefragt und es führen einige sehr unterschiedliche Wege nach Rom. Ein paar davon werden hoffentlich recht ausgetreten sein, aber eventuell gibt es ja ein paar Schleichwege, die auch die Leser dieses Forums überraschen und euch helfen, solltet ihr euch auch einmal in dieser vielleicht nicht ganz so wahrscheinlichen Situation befinden.

Jeder erdenklicher Ansatz ist erlaubt, auch wenn er sehr speziell nur für dieses Beispiel funktionieren sollte. Und wenn ihr mehrere ( im wesentlichen unterschiedliche ) Ansätze parat habt, würde ich gerne alle davon erfahren.

Hier das Coding, in welchem NUR DIE METHODE KORRESPONDING überarbeitet werden soll.

Code: Alles auswählen.

REPORT knobelei_august_2021.

CLASS lcl DEFINITION FINAL.
  PUBLIC SECTION.
    METHODS:
      main,
      korresponding IMPORTING is_structure_1 TYPE any
                    CHANGING  cs_structure_2 TYPE any.
ENDCLASS.

END-OF-SELECTION.
  NEW lcl( )->main( ).

CLASS lcl IMPLEMENTATION.

  METHOD korresponding.
**********************************************************************
*--------------------------------------------------------------------*

* Hier bitte euer Coding

*--------------------------------------------------------------------*
**********************************************************************
  ENDMETHOD.


  METHOD main.
    DATA: struc1         TYPE bapiaddr3,
          struc2         TYPE addr2_data,
          correct_result LIKE struc2.

*--------------------------------------------------------------------*
* Testdaten erstellen
*--------------------------------------------------------------------*
    CLEAR struc1 WITH 'X'.
*--------------------------------------------------------------------*
* Umgehen des SCI
*--------------------------------------------------------------------*
    korresponding( EXPORTING is_structure_1 = struc1
                   CHANGING  cs_structure_2 = struc2 ).
*--------------------------------------------------------------------*
* Prüfen ob das Ergebnis korrekt ist durch Verwendung des "bösen" Befehls
*--------------------------------------------------------------------*
    MOVE-CORRESPONDING struc1 TO correct_result.
    IF struc2 = correct_result.
      WRITE:/ 'Grün' COLOR 5.
    ELSE.
      WRITE:/ 'Hat nicht funktioniert' COLOR 6.
    ENDIF.
  ENDMETHOD.

ENDCLASS.

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

live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de


Re: Knobelaufgabe ( August 2021 )

Beitrag von ewx (Top Expert / 4472 / 236 / 505 ) »
Endlich mal wieder was ohne denken... :D
Danke und schönes Wochenende!

Re: Knobelaufgabe ( August 2021 )

Beitrag von black_adept (Top Expert / 3701 / 78 / 771 ) »
Moin allerseits,

hier ein kurzer Zwischenstand und eine Ergänzung:
Ergänzung: Da es hier eigentlich um ein "eigenes" Programm geht, dürft ihr davon ausgehen, dass ihr wisst, welche Strukturen in is_structure_1 und cs_structure_2 übergeben werden. Die Schnittstelle per se soll nicht erweitert werden und es gibt Lösungen, welche auch mit den anonym typisierten Inputparametern klarkommen. Aber durch diese Erweiterung werden mehr Lösungsansätze möglich - u.a. auch derjenige, welchen ich als "Schreibarbeit" bezeichnen möchte und der letztlich der Fallback für dieses spezielle Problem sein kann.

Zwischenstand
Bisher haben mich 2 Einsendungen mit jeweils einem Lösungsansatz erreicht. Ist als Entwickler eigentlich auch genau die richtige Vorgehensweise - sobald ich einen Ansatz gefunden habe programmiere ich den auch aus.
Aber diese Knobelei soll euch anregen "out of the box" zu denken und auch mehrere ( im Wesentlichen aber verschiedene ) Ansätze anzubieten, einfach um das ABAP-Gehirn zu trainieren.
Und es gibt mehr als diese 2 Ansätze.

Einsendeschluss ist wie üblich Donnerstag Abend, so dass ich für Freitag dann ein Fazit vorbereiten kann.
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Knobelaufgabe ( August 2021 )

Beitrag von black_adept (Top Expert / 3701 / 78 / 771 ) »
Aktueller Zwischenstand:
Die Anzahl der verschiedenen Lösungsansätze liegt immer noch bei 2, welche beide das allgemeine Problem lösen und keiner, welcher nur bei Wissen über die übergebenen Eingabestrukturen funktioniert.
Ich hoffe immer noch, dass noch weitere Ansätze gefunden werden. Diese müssten nicht "gut" sein - sie sollen einfach nur zeigen wie man anders an ein Problem rangehen könnte. Und es gibt noch mindestens 2-3 weitere Ansätze für den allgemeinen Fall + mindestens 2 für den Spezialfall, von denen einer einfach Schreibarbeit ist.
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Knobelaufgabe ( August 2021 )

Beitrag von black_adept (Top Expert / 3701 / 78 / 771 ) »
Moin allerseits,

wie üblich zum Wochenende die Vorstellung der möglichen (mir bekannten ) Lösungsansätze:
Zunächst sollte man unterscheiden, ob man - wie in einem Programm was man selber erstellt - evtl. Informationen über die übergebenen Strukturen hat. Wenn man das annimmt ergeben sich die beiden folgenden Ansätze:

Lösungen mit Informationen über die übergebenen Strukturen
1. Schreibarbeit: Man macht einfach manuell das, was auch das Move-Corresponding macht. Man suche sich alle gleichnamigen Felder heraus und weise diese dann 1:1 zu. Glücklicherweise habe ich keine Einsendung mit dieser Lösung erhalten. Kein Programmierer der was auf sich hält würde wohl diesen Ansatz wählen, wenn man bessere Alternativen hat. Aber es ist halt ein Ansatz, der das Problem lösen kann.

Code: Alles auswählen.

  METHOD korresponding.
    FIELD-SYMBOLS: <ls_source> TYPE bapiaddr3,
                   <ls_target> TYPE addr2_data.
    ASSIGN is_structure_1 TO <ls_source>.
    ASSIGN cs_structure_2 TO <ls_target>.
    <ls_target> = VALUE #( home_city        = <ls_source>-home_city
                           chckstatus       = <ls_source>-chckstatus
                           regiogroup       = <ls_source>-regiogroup
                           pcode1_ext       = <ls_source>-pcode1_ext
                           pcode2_ext       = <ls_source>-pcode2_ext
                           pcode3_ext       = <ls_source>-pcode3_ext
                           po_box           = <ls_source>-po_box
                           dont_use_p       = <ls_source>-dont_use_p
                           po_box_reg       = <ls_source>-po_box_reg
                           transpzone       = <ls_source>-transpzone
                           street           = <ls_source>-street
                           dont_use_s       = <ls_source>-dont_use_s
                           str_suppl1       = <ls_source>-str_suppl1
                           str_suppl2       = <ls_source>-str_suppl2
                           str_suppl3       = <ls_source>-str_suppl3
                           location         = <ls_source>-location
                           building         = <ls_source>-building
                           floor            = <ls_source>-floor
                           country          = <ls_source>-country
                           langu            = <ls_source>-langu
                           region           = <ls_source>-region
                           sort1            = <ls_source>-sort1
                           sort2            = <ls_source>-sort2
                           time_zone        = <ls_source>-time_zone
                           taxjurcode       = <ls_source>-taxjurcode
                           po_box_lobby     = <ls_source>-po_box_lobby
                           deli_serv_type   = <ls_source>-deli_serv_type
                           deli_serv_number = <ls_source>-deli_serv_number
                           county_code      = <ls_source>-county_code
                           county           = <ls_source>-county
                           township_code    = <ls_source>-township_code
                           township         = <ls_source>-township
                           title_p          = <ls_source>-title_p
                           title_aca1       = <ls_source>-title_aca1
                           title_aca2       = <ls_source>-title_aca2
                           prefix1          = <ls_source>-prefix1
                           prefix2          = <ls_source>-prefix2
                           title_sppl       = <ls_source>-title_sppl
                           nickname         = <ls_source>-nickname
                           initials         = <ls_source>-initials
                           nameformat       = <ls_source>-nameformat
                           namcountry       = <ls_source>-namcountry
                           langu_p          = <ls_source>-langu_p
                           sort1_p          = <ls_source>-sort1_p
                           sort2_p          = <ls_source>-sort2_p
                           langu_cr_p       = <ls_source>-langu_cr_p
                         ).
  ENDMETHOD.
2. SELECT:Wenn man sich die ABAPDOKU nach "CORRESPONDING" durchsucht findet man irgendwann dies auch beim SELECT-Befehl. Da lt. Vorgabe nur der Ausdruck CORRESPONDING und der Befehl MOVE-CORRESPONDING vom Code-Inspektor abgelehnt werden, kann man sich diesen Zusatz zu nutze machen. Voraussetzung ist hier aber eben auch, dass man zumindest weiß, wie die Eingabestruktur typisiert ist. Hier ein Ansatz ( ab Release 7.52 ), der eine Lösung mit diesem Ansatz umsetzt.

Code: Alles auswählen.

  METHOD korresponding.
    DATA: lt_data TYPE STANDARD TABLE OF bapiaddr3.
    APPEND is_structure_1 TO lt_data.
    SELECT SINGLE *
      FROM @lt_data AS itab
      INTO CORRESPONDING FIELDS OF @cs_structure_2.
  ENDMETHOD.
Allgemeine Lösungen, die mit den anonymen Strukturen umgehen können
Diese Lösungen sind eigentlich diejenigen, die man auch in Klassen kapseln könnte und die einem dann in vielen Aufrufen zugänglich sind.
3. RTTI:Dies ist der Lösungsansatz, der am häufigsten vorgeschlagen wurde. Es werden über RTTI ( RunTime Type Information ) die Feldnamen der Eingabestruktur gesucht und der Feldinhalt der zugehörigen Felder werden dann - wenn möglich - in die Zielstruktur überführt. Meines Erachtens ist dies der sauberste Ansatz, einfach weil am einfachsten wart- und lesbar.

Code: Alles auswählen.

  METHOD korresponding.
    DATA(lo_descr) = CAST cl_abap_structdescr( cl_abap_structdescr=>describe_by_data( is_structure_1 ) ).
    LOOP AT lo_descr->components ASSIGNING FIELD-SYMBOL(<ls_component>).
      ASSIGN COMPONENT <ls_component>-name OF STRUCTURE cs_structure_2 TO FIELD-SYMBOL(<ls_target>).
      IF sy-subrc = 0.
        ASSIGN COMPONENT <ls_component>-name OF STRUCTURE is_structure_1 TO FIELD-SYMBOL(<ls_source>).
        <ls_target> = <ls_source>.
      ENDIF.
    ENDLOOP.
  ENDMETHOD.
4. Generate Subroutinepool: Dies ist wohl der allgemeinste Ansatz, der auch angewendet werden kann, wenn der Entwicklungsleiters weitere paranoide Schübe macht oder auch wenn Zitat: Es eine schlecht geschriebene CI-Prüfung ist, welche nach dem Wort "CORRESPONDING" sucht

Code: Alles auswählen.

  METHOD korresponding.
    DATA(code) = VALUE string_table(
     ( |REPORT.| )
     ( |FORM MOVC USING IN TYPE ANY CHANGING OUT TYPE ANY.| )
     ( |  MOVE-CO{ sy-abcde+17(1) WIDTH = 2 PAD = 'R' }ESPONDING IN TO OUT.| )
     ( |ENDFORM.| )  ).

    DATA(repname) = CONV syrepid( |Z%{ sy-uname }_{ sy-uzeit }| ).
    INSERT REPORT repname FROM code PROGRAM TYPE 'S'.
    IF sy-subrc = 0.
      PERFORM movc IN PROGRAM (repname) USING is_structure_1 CHANGING cs_structure_2 IF FOUND.
    ENDIF.

  ENDMETHOD.
5a. Call Function SAP stellt für diversen Quatsch, den man eigentlich mit ABAP-Bordmitteln erledigen kann, Funktionsbausteine zur Verfügung. Auch für den Befehl MOVE-Corresponding. Eine kleine Suche in der SE37 hat mich auf den FuBa "COPY_STRUCTURE_CORRESPONDING" gebracht, der - nicht sonderlich überraschend - tatsächlich dem MOVE-Corresponding entspricht. Wenn man sich die Kommentare am Anfang des Codings dieses FuBa anschaut erkennt man, dass dies dem Ausdruck CORRESPONDING # auch für tiefe Strukturen entspricht. Dementsprechend gibt sich damit dann folgender Ansatz:

Code: Alles auswählen.

  METHOD korresponding.

    CALL FUNCTION 'COPY_STRUCTURE_CORRESPONDING'
      EXPORTING
        im_structure = is_structure_1
      IMPORTING
        ex_structure = cs_structure_2.

  ENDMETHOD.
5a. Call Method Dies ist sehr verwandt mit dem Aufruf eines FuBa - aber ich möchte es trotzdem erwähnen, da hier eine Besonderheit vorherrscht. Es gibt die Klasse CL_ABAP_CORRESPONDING mit der man auch ein move-corresponding ausführen kann, welche aber über eine Kernelmethode läuft. Da wir hier kein Mapping verwenden kann man den einfachsten Aufruf dieser Klasse=>Methode verwenden um das gewünschte Ergebnis zu erzielen. Wenn man sich nun fragt, ob evtl. die beim Erstellen einer Instanz dieser Klasse übergebenen Informationen den Kernel befähigen hier Informationen über die zu bewegendne Felder zu puffern und damit eine besonders schnelle Ausführung zu erleben wird leider enttäuscht. Der Standardbefehl "MOVE-Corresponding" ist deutlich schneller als die Kernelmethode.
Trotzdem hier ein Ansatz mit dieser Klasse:

Code: Alles auswählen.

  METHOD korresponding.
    cl_abap_corresponding=>create( source      = is_structure_1
                                   destination = cs_structure_2
                                   mapping     = VALUE #( ) )->execute( EXPORTING source      = is_structure_1
                                                                        CHANGING  destination = cs_structure_2 ).
  ENDMETHOD.
6. Call Transformation Der Befehl CALL TRANSFORMATION erlaubt es Daten(strukturen) zu serialisieren und zu deserialisieren. Da dabei Informationen über die Feldnamen verwendet werden und dieser Befehl sehr robust gegenüber Strukturänderungen ist, eignet er sich auch für die Lösung dieser Aufgabe, indem man die Eingabestruktur serialisiert und dann zurück in die Ausgabestruktr deserialsiert.

Code: Alles auswählen.

  METHOD korresponding.
    DATA: lv_xml TYPE string.
    CALL TRANSFORMATION id
       SOURCE data = is_structure_1
       RESULT XML lv_xml.
    CALL TRANSFORMATION id
       OPTIONS value_handling = 'accept_data_loss'
       SOURCE XML lv_xml
       RESULT data = cs_structure_2.
  ENDMETHOD.

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

live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Knobelaufgabe ( August 2021 )

Beitrag von IHe (ForumUser / 95 / 26 / 29 ) »
Danke für die Aufstellung der unterschiedlichen Lösungsansätze! Ich überlege gerade, ob der Ansatz mit CALL TRANSFORMATION auch geeignet ist, um ein MOVE-CORRESPONDING für Objekt-Instanzen zu realisieren, d.h. dass von einem Objekt alle gleichartigen Attribute in ein anderes Objekt übernommen werden... eventuell nur mit dem Interace IF_SERIALIZABLE_OBJECT.
Ingo Hoffmann

ECC|S/4HANA|BTP
dbh SAP Solutions

Re: Knobelaufgabe ( August 2021 )

Beitrag von black_adept (Top Expert / 3701 / 78 / 771 ) »
Moin Ingo,

das geht - aber man muss schummeln, da die ID-Transformation auch den Klassennamen ablegt.
Dafür wird man mit einem Attributmoving belohnt, welches sich nicht mal an Sichtbarkeitsdefinitionen aufhält.
Beispielprogramm bei dem das private Attribut mv2 aus der Source- in die Targetklasse übetragen wird, wo das Attribut mv2 public definiert ist:

Code: Alles auswählen.

REPORT.


CLASS lcl_get DEFINITION.
  PUBLIC SECTION.
    INTERFACES if_serializable_object.
    METHODS constructor.
  PRIVATE SECTION.
    DATA: mv1 TYPE i,
          mv2 TYPE i,
          mv3 TYPE i.
ENDCLASS.

CLASS lcl_get IMPLEMENTATION.
  METHOD constructor.
    mv1 = 1.
    mv2 = 2.
    mv3 = 3.
  ENDMETHOD.
ENDCLASS.

CLASS lcl_put DEFINITION.
  PUBLIC SECTION.
    INTERFACES if_serializable_object.
    DATA: mv2 TYPE i.
ENDCLASS.

END-OF-SELECTION.
  DATA: lv_xml TYPE string.
  DATA(lo_get) = NEW lcl_get( ).
  CALL TRANSFORMATION id
    SOURCE oref  = lo_get
    RESULT XML lv_xml.

**********************************************************************
*** Schummeln ***
**********************************************************************
  REPLACE ALL OCCURRENCES OF 'LCL_GET' IN lv_xml WITH 'LCL_PUT'.
**********************************************************************

  DATA(lo_put) = NEW lcl_put( ).
  WRITE:/ 'Vorher :',lo_put->mv2.

  CALL TRANSFORMATION id
    SOURCE XML lv_xml
    RESULT oref = lo_put.

  WRITE:/ 'Nachher:',lo_put->mv2.

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

live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Seite 1 von 1

Über diesen Beitrag



ABAP & SAP eBook Flatrate von Espresso Tutorials Sponsorlink
Unterstütze die Community und teile den Beitrag für mehr Leser und Austausch

Aktuelle Forenbeiträge

Texte im Rechnungskopf
Gestern von JHM 7 / 65
CO01 BADI
Gestern von L0w-RiDer 13 / 150
Dynpro Eingabe von Zahl mit Komma
Gestern von ewx 17 / 181
Probleme mit CORRESPONDING itab
vor 2 Tagen von ewx gelöst 7 / 87

Vergleichbare Themen

Knobelaufgabe - Advent 2021
von black_adept » 29.11.2021 12:58
Knobelaufgabe ( Oktober 2021 )
von black_adept » 19.10.2021 12:19
Knobelaufgabe zum Wochenbeginn ( Mai 2021 )
von black_adept » 11.05.2021 16:21
Knobelaufgabe zum Wochenbeginn ( Juni 2021 )
von black_adept » 21.06.2021 16:29