Clear FUBA

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

Getting started ... Alles für einen gelungenen Start.
24 Beiträge • Seite 1 von 2 (current) Nächste
24 Beiträge Seite 1 von 2 (current) Nächste

Clear FUBA

Beitrag von Abapsocke (ForumUser / 49 / 6 / 0 ) »
Ist es möglich einen Funktionsbaustein während des Programmablaufes zu clearen? Also Programm holt wert aus Funktionsbaustein, Funtionsbaustein clearen, Programm holt anderen wert aus selben FUBA usw...

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


Re: Clear FUBA

Beitrag von ewx (Top Expert / 4784 / 294 / 628 ) »
Jein.
Das ist auch eines der großen Probleme von Funktionsbausteinen bzw. Funktionsgruppen.
Einmal geladen und sie sind da. Im Gegensatz zu Objektinstanzen.

Du kannst einen Funktionsbaustein mit dem Zusatz STARTING NEW TASK ausführen. Er wird dann in einem eigenen Speicherbereich ausgeführt, der nach Beendigung des Fubas gelöscht wird.

Wenn es dein eigener FB ist, dann solltest du möglichst sicherstellen, dass du möglichst wenig bis gar keine globalen Variablen nutzt.
Und wenn, dann kannst aus dem angefragten Grund, einen CLEAR-Baustein schreiben, der die Daten zurücksetzt.

Trotzdem auch hier die Gegenfrage: Warum?

Re: Clear FUBA

Beitrag von Abapsocke (ForumUser / 49 / 6 / 0 ) »
Gute Frage:

Ich habe einen kleinen Fuba für Zufallszahlen. Diesen möchte ich im Programm mehrmals aufrufen um verschiedene Zufallszahlen zu haben. Ich könnte natürlich auch am Anfang einfach dutzende Zufallszahlen erzeugen und diese dann nach und nach verwenden, aber das halte ich für ineffizient, da ich am Anfang nicht weiß, wie viele ich brauchen werde.

Daher wird der FUBA mehrmals im Programm aufgerufen um Situativ Zufallszahlen zu erzeugen. Momentan erzeugt er natürlich dann immer ein und die selbe Zahl, da ein Programmablauf = 1 Zufallszahl. Das ist nicht nützlich.

Prinzipiell der Programmablauf:

Code: Alles auswählen.

IF (eine Zahl zwischen 5-10) tue dies.
 IF (eine andere zahl zwischen 1-10) tue auch noch das. Programmablauf mit vielen Details....
  IF (eine weitere random zahl zwischen 1-10) tue auch noch jenes.
  ENDIF
 ENDIF
ELSE Progammablauf ohne weitere zwischenfälle
ENDIF
Da brauche ich natürlich mehrmals unterschiedliche Zahlen in einem Programmablauf...

Re: Clear FUBA

Beitrag von ewx (Top Expert / 4784 / 294 / 628 ) »
äh...
Weil du das hier nicht zum Laufen bekommst?

Und Zufallszahlen sollten ja immer eine andere Zahl erzeugen.
Du rufst ja nicht einen Zufallszahlbaustein auf, "berechnest" eine Zahl und verwendest die dann immer wieder.
Sondern die "Funktion" - egal ob Fuba oder Methode - berechnet immer eine Zufallszahl.
Wenn diese immer gleich ist, funktioniert was nicht mit der Berechnung.

Verwende die Klasse CL_ABAP_RANDOM_INT
Du erstellst einmal eine Objektinstanz (Create Object oder NEW) und kannst dann mit GET_NEXT immer eine neue Zufallszahl erzeugen.
Das inet ist voll von Beispielen für die Verwendung.

Re: Clear FUBA

Beitrag von Abapsocke (ForumUser / 49 / 6 / 0 ) »
Die Sache ist das der Funktionsbaustein in der Laufzeit immer 1 Zahl erstellt und diese speichert. Wird der Fuba neu gestartet ist es eine andere Zahl. Ich schau mir die Klasse mal an, obwohl das genau die ist, die ich im Fuba verwende, aber bislang noch ohne get next.

Bislang siehts gut aus. Ich teste nochmal durch und bedanke mich dann wenns klappt :)

Re: Clear FUBA

Beitrag von Abapsocke (ForumUser / 49 / 6 / 0 ) »
Irgendwie klappt es nicht. Habe nun folgenden Code. Aber auch hier bekomme ich beim erneuten Aufruf in der gleichen Laufzeit immer nur die selbe Zahl.

Das Problem liegt wahrscheinlich daran, dass ich das mit einem FUBa nicht gedeckelt bekomme. Ich muss das Objekt also (eben weil es von globalen variablen abhängig ist) ins normale Programm schreiben und dort gegebenenfalls immer wieder aufrufen.

Code: Alles auswählen.

report  zz_random_int.
data:
   lo_ran type ref to cl_abap_random_int,
   lv_i   type i,
   lv_seed type i.


 lv_seed = sy-timlo.
lo_ran = cl_abap_random_int=>create( min = 5 max = 25 seed = lv_seed ).
  lv_i = lo_ran->get_next( ).
  write / lv_i.



Zuletzt geändert von Abapsocke am 25.05.2018 13:05, insgesamt 1-mal geändert.

Re: Clear FUBA

Beitrag von DeathAndPain (Top Expert / 1797 / 214 / 396 ) »
Also irgendwie verstehe ich nicht, was Du willst. Ich habe das Gefühl, dass Du Dich darüber beschwerst, dass der Fuba das macht, was Du willst, dass er macht. Wenn Du Zufallszahlen willst, dann ist es doch gut, wenn er nicht "gecleart" wird, sondern sich seinen Seed merkt, eben damit er beim nächsten Aufruf nicht wieder dieselbe Zufallszahl ausgibt, sondern eine neue berechnet?! Damit sollte es doch in Deinem Interesse sein, dass er gerade nicht gecleart wird. Dann kann er bei seinem nächsten Aufruf da weitermachen, wo er beim letzten aufgehört hat.

Im übrigen:
  • Da es offenbar Deine eigene Funktionsgruppe ist, steht es Dir frei, wie von ewx angeregt einen dezidierten Clear-Baustein zu schreiben, der nichts anderes macht, als die globalen Variablen leerzuräumen.
  • Wenn Du die Eigenschaft der globalen Variablen, global zu sein, gar nicht haben willst (was ja auch vom Programmierstil her zu begrüßen wäre), dann sollte Dein Fuba aus nicht mehr bestehen als dem Aufruf einer Form. In dieser kannst Du dann echte lokale Variablen deklarieren. Diese sind beim nächsten Fuba-Aufruf automatisch wieder weg.

Re: Clear FUBA

Beitrag von DeathAndPain (Top Expert / 1797 / 214 / 396 ) »
Abapsocke hat geschrieben:Irgendwie klappt es nicht. Habe nun folgenden Code. Aber auch hier bekomme ich beim erneuten Aufruf in der gleichen Laufzeit immer nur die selbe Zahl.
Weil sich sy-timlo nicht laufend ändert, sondern nur "auf Anfrage": Du solltest vorher den Befehl GET TIME einbauen. Der aktualisiert die ganzen Zeitfelder, darunter SY-TIMLO. Ansonsten rufst Du die Methode immer mit dem selben Seed auf und bekommst logischerweise auch immer dieselbe Zufallszahl.

Re: Clear FUBA

Beitrag von Abapsocke (ForumUser / 49 / 6 / 0 ) »
da liegt doch der Hund begraben. Als ich hier die Anfrage geschrieben habe, wusste ich nichts von der Möglichkeit eines SEEDS. Demzufolge war mir nicht ganz klar, wie dieser genau funktionieren würde. Daher war es zu dem Zeitpunkt für mich sinnvoll zu fragen ob ich einen FUBA clearen kann, da ich ohne SEED sonst immer die selbe Zahl bekomme.

Als ich dann im Internet das Beispiel mit dem SEED gefunden habe, war mir nicht ganz klar wie dieser die Random-Funktion beeinflusst. Ich habe gelesen das er notwendig sei, warum genau weiß ich aber noch nicht. BZW, nun wegen deiner Erklärung ist mir das deutlich geworden.

Mit dem SEED ist es ja genau anders herum, wie du bereits sagst: Nun wäre es sinnlos den FUBA zu clearen, da er eigentlich macht was er soll. Jedenfalls hoffentlich mit GET TIME.

Re: Clear FUBA

Beitrag von Abapsocke (ForumUser / 49 / 6 / 0 ) »
Auch mit GET TIME bekomme ich die selbe Zahl. Ich liste den Code mal hier auf und kommentiere zur Übersicht aus:

Code: Alles auswählen.

DATA: ls_starfighters TYPE ZLK_STARFIGHTERS,
      l_num TYPE i,
      t_num TYPE i.

t_num = 1.
*t_num ist nur für Testzwecke


WRITE: 'Dies ist ein Dummytext. Bei einem 1w10 Wurf passiert etwas bei 5-10, ansonsten ist die Begegnung harmlos.'.


call function 'Z_RAUMSCHIFF_RANDOM'
 EXPORTING
   MINATTACK       = 1
   MAXATTACK       = 10
 IMPORTING
   W_NUM           = l_num.
*l_num sollte sich bei jedem Aufruf ändern.


WRITE: l_num.


IF l_num GE 5.
  WRITE: 'Deine lange Reise durch den Weltraum wird je unterbrochen:...'.

*Zweiter Funktionsbaustein call, wieder brauche ich eine neue Nummer. Derzeit ist das GET TIME im FUBA. Ich habe es aber auch hier versucht
* GET TIME.
  call function 'Z_RAUMSCHIFF_RANDOM'
 EXPORTING
   MINATTACK       = 1
   MAXATTACK       = 10
 IMPORTING
   W_NUM           = l_num.

  WRITE: / l_num, 'zweite Zufallszahl'.

und der FUBA

Code: Alles auswählen.

FUNCTION z_raumschiff_random.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*"  IMPORTING
*"     REFERENCE(MINATTACK) TYPE  ZLK_STARFIGHTERS-ANGRIFF DEFAULT 1
*"     REFERENCE(MAXATTACK) TYPE  ZLK_STARFIGHTERS-ANGRIFF DEFAULT 10
*"  EXPORTING
*"     REFERENCE(W_NUM) TYPE  I
*"----------------------------------------------------------------------

  DATA:
     lo_ran TYPE REF TO cl_abap_random_int,
     lv_seed TYPE i,
     lv_minwert TYPE i,
     lv_maxwert TYPE i.


     lv_minwert = minattack.
     lv_maxwert = maxattack.

  GET TIME.


  lv_seed = sy-timlo.
  lo_ran = cl_abap_random_int=>create( min = lv_minwert max = lv_maxwert seed = lv_seed ).
  w_num = lo_ran->get_next( ).

   WRITE / w_num.

Re: Clear FUBA

Beitrag von ewx (Top Expert / 4784 / 294 / 628 ) »
Der SEED wird für die Berechnung der Zufallszahlen verwendet.
Er stellt sicher, dass in Verbindung mit MIN und MAX zu einem SEED immer die gleiche Abfolge von Zufallszahlen erzeugt wird.

Es eignet sich daher super zum Testen...

Das wäre jetzt ein gutes Beispiel für den Einsatz von globalen Daten.
LO_RAN könntest du global definieren (Entweder im Fuba als globale Variable im TOP-Include oder als globales Attribut einer Klasse) und einmal beim ersten Aufruf erzeugen.
LO_RAN sollte dann GO_RAN heißen.

In der Funktion brauchst du dann nur noch GO_RAN->GET_NEXT aufrufen und erhältst immer eine andere Zufallszahl.

Hier haben die Klassen auch wieder einen Vorteil, denn du kannst einen (Klassen-) Konstruktor erzeugen, in dem du einmal GO_RAN erzeugst.
Dann brauchst du in der Methode nicht abzufragen IF GO_RAN IS INITIAL.

Ansonsten kannst du die Zufallszahl auch mit einem Aufruf erzeugen:

Code: Alles auswählen.

lv_i = cl_abap_random_int=>create( min = 1 max = 20 seed = conv #( sy-timlo ) )->get_next( ).
Das ist allerdings schlecht, wenn du mehrere Zufallszahlen direkt hintereinander erzeugen willst, denn so schnell ändert sich TIMLO nicht...

Folgende Benutzer bedankten sich beim Autor ewx für den Beitrag:
Abapsocke


Re: Clear FUBA

Beitrag von sapnup (ForumUser / 42 / 14 / 12 ) »
Wäre es nicht besser eine große Zahl zu rollen und ihre Bruchteile dann für verschiedene Eventualitäten zu nutzen?

Oh und einen Fuba kannst du clearen indem am Beginn des Fuba-Codes alle Fuba-internen Variablen initialiserst. Wenn du die Initialisierung bedingt machst, kannst du bei jedem Durchlauf des aufrufenden Programms entscheiden ob du neue Werte willst oder die alten.

Re: Clear FUBA

Beitrag von Abapsocke (ForumUser / 49 / 6 / 0 ) »
ewx hat geschrieben:
Das wäre jetzt ein gutes Beispiel für den Einsatz von globalen Daten.
LO_RAN könntest du global definieren (Entweder im Fuba als globale Variable im TOP-Include oder als globales Attribut einer Klasse) und einmal beim ersten Aufruf erzeugen.
LO_RAN sollte dann GO_RAN heißen.

In der Funktion brauchst du dann nur noch GO_RAN->GET_NEXT aufrufen und erhältst immer eine andere Zufallszahl.
Was ist denn der Unterschied wenn ich diese Variablen global definiere? Das brauche ich doch sonst nur, wenn ich Programmübergreifend darauf zugreifen möchte. Also im Falle eines TopIncludes beispielsweise mit anderen Fubas. Das hat zwar durchaus einen Sinn wenn ich noch mehrere FUBAS erstelle, aber darüber hinaus?

Wie kann ich denn erreichen das ich jedes mal eine andere RAndomzahl erhalte? Es scheint ja dann daran zu liegen das der TIMLO sich nicht so schnell ändert, oder?

Re: Clear FUBA

Beitrag von ewx (Top Expert / 4784 / 294 / 628 ) »
Abapsocke hat geschrieben: Was ist denn der Unterschied wenn ich diese Variablen global definiere? Das brauche ich doch sonst nur, wenn ich Programmübergreifend darauf zugreifen möchte. Also im Falle eines TopIncludes beispielsweise mit anderen Fubas. Das hat zwar durchaus einen Sinn wenn ich noch mehrere FUBAS erstelle, aber darüber hinaus?
Darüberhinaus hast du beim nächsten Fuba-Aufruf bereits das instantiierte Objekt GO_RAN und kannst einfach mit GET_NEXT die neue Zufallszahl abholen.

Re: Clear FUBA

Beitrag von DeathAndPain (Top Expert / 1797 / 214 / 396 ) »
Was ist denn der Unterschied wenn ich diese Variablen global definiere?
Keiner. ewx hat nicht aufgepasst und nicht bedacht, dass DATA-Befehle, die wie bei Dir zwischen FUNCTION und ENDFUNCTION stehen, immer globale Variablen deklarieren. Solche Variablen sind genauso global, als wenn sie im TOP-Include der Funktionsgruppe deklariert worden wären (nur dass sie vor dem DATA-Befehl naturgemäß noch nicht genutzt werden können).

Mit anderen Worten: Deine Variablen sind jetzt schon global, und mit Deinen lo_ bzw. lv_-Vorsätzen erzeugst Du nur die falsche Illusion, dass es sich um lokale Variablen handeln würde. Deswegen hatte ich Dir ja in einer vorhergehenden Antwort die Empfehlung gegeben, zwischen FUNCTION und ENDFUNCTION nur einen PERFORM zu machen. In der dazugehörigen FORM kannst Du dann echte lokale Variablen verwenden, die ihren Wert nach dem Ende der Form verlieren.
Das brauche ich doch sonst nur, wenn ich Programmübergreifend darauf zugreifen möchte.
Nicht nur. Die globalen Variablen eines Funktionsbausteins bzw. seiner Funktionsgruppe bleiben zwischen mehreren Aufrufen erhalten, auch wenn diese aus demselben Programm kommen. Beispielsweise kann Dein Fuba zwecks Performanceoptimierung eine Puffertabelle nutzen, die er bei seinem ersten Aufruf füllt und dann bei allen weiteren Aufrufen schon parat hat. Das sieht dann in etwa so aus:

Code: Alles auswählen.

IF PUFFERTABELLE{}IS INITIAL. " müssen eckige Klammern sein (wenn die Tabelle keine Kopfzeile hat, dann kann man sie auch weglassen)
  SELECT * FROM datenbanktabelle INTO PUFFERTABELLE.
ENDIF.
* Rest der Fuba-Logik
Wie kann ich denn erreichen das ich jedes mal eine andere RAndomzahl erhalte? Es scheint ja dann daran zu liegen das der TIMLO sich nicht so schnell ändert, oder?
Der ist halt nur sekundengenau, bleibt also für eine ganze Sekunde konstant.

Was Du aber machen kannst, ist ganz zu Programmbeginn (etwa zum Zeitpunkt INITIALIZATION) einen GET RUN TIME FIELD x zu machen. Später machst Du nochmal einen, um Dir in x einen passenden Seed zu erzeugen. Dazwischen muss mindestens eine Benutzeraktion liegen, und wenn es nur das Selektionsbild Deines Reports ist. Dann hast Du in x die gemessene Laufzeit zwischen beiden Aufrufen, und zwar in Mikrosekunden. Das sollte fein genug sein.

Alternativ kannst Du auch zu Programmbeginn Deinen SY-TIMLO nehmen und vor jeder neuen Zufallszahlerzeugung eins dazuaddieren. Hauptsache, der Seed ist nicht derselbe wie beim vorherigen Aufruf (und nicht derselbe wie beim vorherigen Programmstart; Du willst ja nicht bei jedem Spiel dieselben Zufallswerte bekommen).

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


Vergleichbare Themen

1
Antw.
1002
Views
CLEAR
von ABAPNEULING1 » 08.12.2004 10:42 • Verfasst in ABAP® für Anfänger
6
Antw.
1757
Views
falsch gesetztes CLEAR !?
von BabsiCSC » 30.06.2008 12:09 • Verfasst in ABAP® Core
3
Antw.
253
Views
Wann macht der Clear-Befehl Sinn?
von Bright4.5 » 03.01.2024 12:01 • Verfasst in ABAP® für Anfänger
5
Antw.
742
Views
FUBA mit FUBA RSPO_OUTPUT_DEVICEDATA eine Liste ausgeben
von Thomas E » 06.05.2021 12:49 • Verfasst in ABAP® Core
4
Antw.
657
Views
FuBa für Pop-up wie bei der Dokumentation
von il.ost » 28.06.2019 10:53 • 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.