This is a test message to test the length of the message box.
Login
ABAP Tipp Zufallszahlen
Erstellt von Software-Heroes

ABAP Tipp - Zufallszahlen

1848

Wie erstellst du einen ordentlich funktionierenden Zufallsgenerator in ABAP? Das zeigen wir dir in unserem kleinen Artikel und auf was du achten solltest.

Werbung


Ein Zufallszahlengenerator in SAP wirkt doch recht verloren, wieso solltest du so etwas benötigen, wo doch alles auf Logik ausgelegt ist? Die Antwort ist eher aus Spaß oder für eine Testanwendung die auf zufälligen Datenbasen aufbaut. Die Implementierung ist sehr einfach, doch sollte man dabei ein paar Punkte beachten, um einen echten Zufallsgenerator zu erhalten.

 

Klasse cl_abap_random

Den Grundstein bildet die Klasse cl_abap_random die zufällige Zahlen erzeugen kann. Dazu erzeugt man eine einfache Instanz über die Factory-Methode. Mit den verschiedenen Methoden kannst du dann verschiedene Zufallszahlen erzeugen. Im Beispiel haben wir einen einfachen Würfel, der die Zahlen von 1 bis 6 erzeugt.


" Instanziierung über Factory-Methode
DATA(lo_rand) = cl_abap_random=>create( ).

" zufällige Zahl von 1-6 (Integer)
DATA(ld_num) = lo_rand->intinrange( low = 1 high = 6 ).

 

Wenig Zufall

Problem bei der Erzeugung der Zufallszahlen ist dann der Zufall an sich. Denn die generierten Zahlen sind in der Reihenfolge nicht wirklich sehr zufällig. Dafür haben wir den folgenden Versuchsaufbau:


DO 15 TIMES.
  DATA(lo_rand) = cl_abap_random=>create( ).
  DO 30 TIMES.
    WRITE: CONV char1( lo_rand->intinrange( low = 1 high = 6 ) ).
  ENDDO.
  NEW-LINE.
ENDDO.

 

Pro erzeugter Ausgabezeile wird noch einmal der Zufallsgenerator instanziiert. Das Ergebnis ist aber, dass jede Reihe gleich aussieht, die erzeugten Zufallszahlen wiederholen sich exakt in ihrer Reihenfolge. Dies entspricht aber keinem Zufall, da mit jedem Testfall das gleiche Ergebnis erzeugt werden würde.

 

Lösung

Dazu brauchen wir eine kleine Hilfe, um wirklich zufällige Zahlenreihen zu erzeugen und das bei jedem Durchlauf. Die Factory-Methode der Klasse nimmt noch einen weiteren Paramter auf, den Seed. Dieser Seed legt den Startwert des Zufallsgenerator fest.Das Arbeiten mit einem festen Startwert/Seed erzeugt ebenfalls das selbe Ergebnis und ist nicht zu empfehlen.

Von daher benötigen wir zu Anfang einen "Seed Generator" der uns zufällige Seeds für den Zufallsgenerator zur Verfügung stellt. Dieser sollte dann ebenfalls auf einer relativ zufälligen Zahl erzeugt worden sein. In unserem Beispiel verwenden wir Monat/Tag, sowie die aktuelle Uhrzeit, um den Startwert zu erhalten. Mit diesem Startwert erzeugen wir dann einen Seed-Generator.


" Seed erzeugen
TRY.
    " Seed mit Datum bis Sekunde
    DATA(ld_seed) = CONV i( |{ sy-datum(4) }{ sy-uzeit }| ).
  CATCH cx_sy_conversion_overflow.
    " FallBack Seed
    ld_seed = 1337.
ENDTRY.

" Seed Generator
mo_seed = cl_abap_random=>create( ld_seed ).

 

Die Instanz dieses Generators sollte statisch oder global gehalten werden, damit er nicht jedes Mal neu erzeugt werden muss.

Mit Hilfe unseres Seed-Generators können wir nun jedes Mal eine Klasse von cl_abap_random erstellen und dieser einen zufälligen Seed bereitstellen, um wirklich auch zufällige Zahlen zu erhalten.


" Zufallsgenerator instanziieren
DATA(lo_rand) = cl_abap_random=>create( mo_seed->intinrange( low = 1 high = 999999 ) ).

 

Dazu noch einmal das komplette Beispiel zur Erzeugung des neuen Würfelergebnisses. Es werden wieder 15 Zahlenreihen erstellt und jedes Mal eine neue Instanz des Zufallsgenerator erzeugt, dieses mal nur mit Hilfe unseres Seed-Generators.


" Seed erzeugen
TRY.
    DATA(ld_seed) = CONV i( |{ sy-datum(4) }{ sy-uzeit }| ).
  CATCH cx_sy_conversion_overflow.
    ld_seed = 1337.
ENDTRY.
DATA(lo_seed) = cl_abap_random=>create( ld_seed ).

" Schleife durchlaufen
DO 15 TIMES.
  DATA(lo_rand) = cl_abap_random=>create( lo_seed->intinrange( low = 1 high = 999999 ) ).
  DO 30 TIMES.
    WRITE: CONV char1( lo_rand->intinrange( low = 1 high = 6 ) ).
  ENDDO.
  NEW-LINE.
ENDDO.

 

Das aktuelle Ergebnis kann sich damit sehen lassen und sieht mehr nach Zufall aus, als bisher. Folgend findest du 3 Beispiele was das Programm an Zahlenreihen erzeugt hat und du wirst feststellen, dass es sich nun um einigermaßen gute Zahlen handelt.

 

Vollständiges Beispiel

Hier findest du die vollständige Klasse zum Erstellen von Zufallszahlen. Entsprechend der Logik von oben, ist die Erzeugung des Seeds im Klassen-Konstruktor und im Konstruktur das Initialisieren des Zufallsgenerators.

CLASS zcl_bs_demo_random DEFINITION
  PUBLIC FINAL
  CREATE PUBLIC.

  PUBLIC SECTION.
    CLASS-METHODS class_constructor.

    METHODS constructor
      IMPORTING id_min TYPE i DEFAULT 1
                id_max TYPE i DEFAULT 6.

    METHODS rand
      RETURNING VALUE(rd_rand) TYPE i.

  PRIVATE SECTION.
    CLASS-DATA mo_seed TYPE REF TO cl_abap_random.

    DATA mo_rand TYPE REF TO cl_abap_random.
    DATA md_from TYPE i.
    DATA md_to   TYPE i.
ENDCLASS.


CLASS zcl_bs_demo_random IMPLEMENTATION.
  METHOD class_constructor.
    TRY.
        DATA(ld_date) = cl_abap_context_info=>get_system_date( ).
        DATA(ld_time) = cl_abap_context_info=>get_system_time( ).

        DATA(ld_seed) = CONV i( |{ ld_date+4 }{ ld_time }| ).
      CATCH cx_sy_conversion_overflow.
        ld_seed = 1337.
    ENDTRY.

    mo_seed = cl_abap_random=>create( ld_seed ).
  ENDMETHOD.


  METHOD constructor.
    md_from = id_min.
    md_to = id_max.

    mo_rand = cl_abap_random=>create( mo_seed->intinrange( low  = 1
                                                           high = 10000 ) ).
  ENDMETHOD.


  METHOD rand.
    rd_rand = mo_rand->intinrange( low  = md_from
                                   high = md_to ).
  ENDMETHOD.
ENDCLASS.

 

Fazit

Die Implementierung eines Zufallsgenerators sollte nun für dich kein Problem sein, wenn du die Feinheiten beachtest bei der Implementierung. Mit Hilfe unseres Beispiels sollte es für dich nun kein Problem mehr sein eine effiziente Lösung zu implementieren. 


Enthaltene Themen:
TippRandom
Kommentare (0)



Und weiter ...

Bist du zufrieden mit dem Inhalt des Artikels? Wir posten jeden Dienstag und Freitag neuen Content im Bereich ABAP und unregelmäßig in allen anderen Bereichen. Schaue bei unseren Tools und Apps vorbei, diese stellen wir kostenlos zur Verfügung.


ABAP in Praxis - Fiori Daten fehlerhaft

Kategorie - ABAP

In diesem kleinen Praxisbeispiel schauen wir uns einen Fehlerfall in Fiori an. Hier werden die Daten im UI falsch angezeigt, obwohl alles sonst richtig zu sein scheint. Die Spur führt uns durch den RAP Stack in eine andere Richtung.

10.10.2025

ABAP Tipp - Handling von Funktionsbausteinen

Kategorie - ABAP

Wie gehst du eigentlich mit Funktionsbausteinen und der Fehlerbehandlung innerhalb von ABAP um? In diesem kleinen Tipp schauen wir uns die Behandlung auch im Rahmen von RFC an.

26.08.2025

ABAP Tipp - Generische Datentypen

Kategorie - ABAP

Was unterscheidet eigentlich CLIKE von CSEQUENCE? Generische Typen können manchmal etwas undurchsichtig sein und als ABAP Entwickler wählen wir vielleicht den Typen zu generisch.

12.08.2025

Recycling-Heroes (Erklärt)

Kategorie - ABAP

Was haben die Recycling-Heroes mit moderner ABAP Entwicklung und ABAP Cloud zu tun? In diesem Artikel geben wir Einblicke in die Idee.

15.07.2025

ABAP Tipp - Ranges und Select-Options

Kategorie - ABAP

Ranges und Select-Options in ABAP sind sehr ähnlich und doch gibt es feine Unterschiede bei der Nutzung im ABAP OO Kontext. Hier schauen wir uns die moderne Verwendung an.

09.05.2025