Code: Alles auswählen.
REPORT.
TYPES: BEGIN OF ts_data,
name TYPE text40,
vorname TYPE text40,
birthday TYPE sydatum,
END OF ts_data,
tt_data type STANDARD TABLE OF ts_data with NON-UNIQUE DEFAULT KEY.
DATA: gt_data TYPE tt_data.
PARAMETERS: anzahl TYPE i OBLIGATORy.
END-OF-SELECTION.
PERFORM build_testdata.
PERFORM drittmeiste_geburtstage CHANGING gt_data . " <<-- Diese Routine soll optimiert werden
SORT gt_data.
LOOP AT gt_data ASSIGNING FIELD-SYMBOL(<ls_data>).
WRITE:/(40) <ls_data>-name,
(40) <ls_data>-vorname,
<ls_data>-birthday.
ENDLOOP.
*&---------------------------------------------------------------------*
*& Form drittmeiste_geburtstage " <<-- Das Coding dieser Routine soll optimiert werden
*&---------------------------------------------------------------------*
FORM drittmeiste_geburtstage CHANGING ct_data type tt_data.
DATA: ls_data LIKE LINE OF ct_data,
ls_data2 LIKE LINE OF ct_data,
lv_last_bday TYPE sydatum,
lv_count TYPE i,
lv_count1 TYPE i,
lv_count2 TYPE i,
lv_count3 TYPE i,
t_ergebnis like ct_data.
* Zunächst für den drittmeisten vorkommenden Tag bestimmen
SORT ct_data BY birthday.
LOOP AT ct_data INTO ls_data.
* Jeden Geburtstag nur 1x probieren
IF lv_last_bday <> ls_data-birthday.
CLEAR lv_count.
LOOP AT ct_data INTO ls_data2 WHERE birthday = ls_data-birthday.
lv_count = lv_count + 1.
ENDLOOP.
* Falls zu den ersten drei gehörend hier einsortieren
IF lv_count > lv_count3.
lv_count3 = lv_count.
ENDIF.
IF lv_count3 > lv_count2. " Ringtausch
lv_count = lv_count2.
lv_count2 = lv_count3.
lv_count3 = lv_count.
ENDIF.
IF lv_count2 > lv_count1. " Ringtausch
lv_count = lv_count1.
lv_count1 = lv_count2.
lv_count2 = lv_count.
ENDIF.
ENDIF.
lv_last_bday = ls_data-birthday.
ENDLOOP.
* in lv_count3 steht jetzt die Anzahl der 3meisten vorkommenden Geburtstage
WRITE:/ 'Drittmeist:', lv_count3.
* jetzt alle Daten in Ausgabetabelle stellen die genau diese Anzahl haben
clear lv_last_bday.
LOOP AT ct_data INTO ls_data.
* Jeden Geburtstag nur 1x probieren
IF lv_last_bday <> ls_data-birthday.
CLEAR lv_count.
LOOP AT ct_data INTO ls_data2 WHERE birthday = ls_data-birthday.
lv_count = lv_count + 1.
ENDLOOP.
* Aha - hat die richtige Anzahl --> in Ergebnistabelle sammeln
if lv_count = lv_count3.
loop at ct_data into ls_data2 where birthday = ls_data-birthday.
append ls_data2 to t_ergebnis.
endloop.
endif.
ENDIF.
lv_last_bday = ls_data-birthday.
ENDLOOP.
* Und Ergebnistabelle zurückgeben
ct_data = t_ergebnis.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form build_testdata
*&---------------------------------------------------------------------*
FORM build_testdata .
DATA: ls_data LIKE LINE OF gt_data,
lo_random TYPE REF TO cl_abap_random.
lo_random = cl_abap_random=>create( seed = anzahl ).
DO anzahl TIMES.
ls_data-name = |Name_{ sy-index }|.
ls_data-vorname = |Vorname_{ lo_random->intinrange( low = 1 high = 100 ) }|.
ls_data-birthday = lo_random->intinrange( low = 730121 high = 730486 ).
APPEND ls_data TO gt_data.
ENDDO.
ENDFORM.
Folgende Benutzer bedankten sich beim Autor black_adept für den Beitrag (Insgesamt 2):
qyurryus • masterhash
Bin ich absolut bei dir - allerdings regt es manche Leute an zu sehen was geht. Und wenn eine Lösung mit 5 Befehlen statt den eigenen 100 daherkommt gibt das ja auch manchmal einen Hinweis, dass es wohl auch alternative Vorgehensweisen gibt. Und so lange man eben nicht weiß wie das Andere hinbekommen haben forscht man halt selber und entdeckt dabei evtl. weitere Alternativen, die man selber oder auch andere bisher nicht gesehen haben.DeathAndPain hat geschrieben: ↑04.09.2020 14:12[...]Von daher bin ich der Meinung, dass wir uns die Lösungen inhaltlich anschauen müssen, anstatt sowas zu bewerten.
Der dritthäufigste Wert ist doch 40?!black_adept hat geschrieben: ↑04.09.2020 11:23Der dritthäufigste Wert ist die 43 ( 2 Tage mit 44 haben mehr Geburtstage ) - aber es gibt mehrere Tage die diese Anzahl aufweisen. Somit sollte die Ausgabe alle 86 Einträge enthalten, die am 13.1. oder am 20.9. Geburtstag haben.
Genau genommen hast du recht. Aber ich hatte versucht das anders zu formulieren ohne gleich einen Lösungsvorschlag zu machen und das war dann immer so kompliziert, dass ich lieber bei dieser Version geblieben bin und versucht habe mit dem Beispiel klarzumachen was ich meine. Und die PMs die ich erhalten habe scheinen darauf hinzuweisen, dass Ottonormalprogrammier verstanden hat was ich will auch wenn es nicht korrekt ausgedrückt ist.
Oder wie wir aus der Objektorientierung gerne scherzhaft sagen: