Code: Alles auswählen.
REPORT.
Data: so_plant type werks_d.
SELECT-OPTIONS s_plant For so_plant.
class lcl_report definition.
public section.
types t_plant type range of werks_d.
class-methods main IMPORTING i_plants type t_plant.
endclass.
class lcl_report implementation.
method main.
cl_demo_output=>display( i_plants ).
endmethod.
endclass.
start-of-selection.
lcl_report=>main( s_plant[] ).
Code: Alles auswählen.
DATA(l_rng) = value rsdsselopt_t( ( sign = 'I' option = 'EQ' low = variable ) ).
Das muss man aber darauf achten, dass RSDSSELOP_ nur 45 Zeichen (CHAR) hat.rob_abc hat geschrieben: ↑01.02.2024 10:07Nutze auch gerne rsdsselopt_t anstatt vollständig zu typisieren.
Code: Alles auswählen.
DATA(l_rng) = value rsdsselopt_t( ( sign = 'I' option = 'EQ' low = variable ) ).
Wozu sollte der Threadersteller das brauchen/nutzen? Er will den SELECT-OPTIONS-Befehl einsetzen, um den Parameter auf sein Selektionsbild zu bekommen. SELECT-OPTIONS erzeugt immer selber eine passende RANGES-Tabelle. Da nützt es Dir nichts, wenn Du schon eine hast.adt hat geschrieben:Alternativ kann man auch im DDIC einen Range-Tabellentyp anlegen. Dieser ist dann im ganze SAP System einsetzbar.
Vollständig mit allen Spalten typisieren musst Du hier so oder so nicht. Da reicht ein einfacherrob_abc hat geschrieben:Nutze auch gerne rsdsselopt_t anstatt vollständig zu typisieren.
Code: Alles auswählen.
DATA l_rng TYPE RANGE OF werks_d.
Per Doppelklick in der SE11 muss im Jahr 2024 hoffentlich niemand mehr nachschauen was für ein Typ ein Feld, eine Struktur oder sonst was hat, wenn es im Eclipse die ABAP Element Info View gibt.DeathAndPain hat geschrieben: ↑04.02.2024 15:27Deine Variante geht natürlich auch, aber in diesem Fall tendiere ich tatsächlich dazu, die explizite Deklaration für besser lesbar zu halten, da der Leser des Programms sonst erst per Doppelklick in die SE11 abspringen muss, um sich anzuschauen, wie Dein rsdsselopt_t (das er wahrscheinlich nicht auswendig kennen wird) beschaffen ist. TYPE RANGE OF werks_d hingegen erschließt sich auf den ersten Blick.
Ja, und bei Selektionsparametern (einschließlich SELECT-OPTIONS) finde ich es auch legitim, dass diese global sind und vom Programmierer auch global verwendet werden, denn bei diesen Feldern ist zu jedem Zeitpunkt im Programmablauf glasklar, wo ihre Werte herkommen, und ab START-OF-SELECTION ändern sich diese auch nicht mehr. Man kann sie also aus Programmsicht wie Konstanten betrachten.ST22 hat geschrieben: ↑05.02.2024 09:53Du musst aber die Parameter einer Methode typisieren, dazu benötigst du einen Tabellentyp vom Typ Range, an den übergibt man dann den Tabellenkörper der Select Option SO_WERK[].
Andererseits in einer programmlokalen Klasse hat mit die Select Options natürlich so im Zugriff, ohne dass man die in die Klasse reinreichen muss.
Ich bin mit den modischen Begriffen für die Eclipse-Funktionalitäten nicht so vertraut, aber wenn Du das meinst, was man zu sehen bekommt, wenn man in Eclipse den Cursor auf ein Feld stellt und F2 drückt, dann hast Du sicherlich recht. Auf die Unterscheidung zwischen SE38 und Eclipse kommt es mir hier aber auch gar nicht an; meiner Meinung nach muss man in beiden einen leichten Zugang zu derlei Informationen haben. Witzigerweise ist das auch in der SE38 mit der Taste F2 der Fall, auch wenn die dann (bei global definierten Datentypen) in die SE11 abspringt.rob_abc hat geschrieben:Per Doppelklick in der SE11 muss im Jahr 2024 hoffentlich niemand mehr nachschauen was für ein Typ ein Feld, eine Struktur oder sonst was hat, wenn es im Eclipse die ABAP Element Info View gibt.
Ich habe vor dem Problem auch schon gestanden, und die Lösung, die mir am besten gefällt, sieht so aus, dass ich zu Programmbeginn einen programmglobalen Datentyp mit sprechendem Namen deklariere. Den kann ich dann sowohl in meiner lokalen Klasse als auch im aufrufenden Programmcode verwenden, und seine Bedeutung erschließt sich dem Leser (mich selber eingeschlossen, wenn ich nach einem halben Jahr mal wieder auf den Code schaue) auf den ersten Blick.rob_abc hat geschrieben:Aber natürlich bin ich auch ein Fan davon genau zu typisieren, deshalb nutze ich rsdsselopt_t auch nur als Hilfsvariable, wenn die Methode eine RNG-Tabelle verlangt, ich aber zum Zeitpunkt des Methodenaufrufes nur eine normale Variable oder Tabelle als Ausgangsbasis habe.
Code: Alles auswählen.
TYPES range_of_werks_d TYPE RANGE OF werks_d.
...
CLASS whatever DEFINITION.
METHODS methode IMPORTING r_werksd TYPE range_of_werks_d.
ENDCLASS.
...
START-OF-SELECTION.
...
DATA(l_rng) = value range_of_werks_d( ( sign = 'I' option = 'EQ' low = variable ) ).
methode( l_rng ).
Die können sich durch den Programmfluss durchaus ändern. Mache ich zwar selten, hat aber durchaus seine Berechtigung.DeathAndPain hat geschrieben: ↑05.02.2024 13:26Ja, und bei Selektionsparametern (einschließlich SELECT-OPTIONS)
[...]
und ab START-OF-SELECTION ändern sich diese auch nicht mehr. Man kann sie also aus Programmsicht wie Konstanten betrachten.
Ich habe viele meiner Kunden überzeugen können, dass der Systemparameter, der die Anzahl der Modi steuert, in Nichtproduktivsystemen auf deutlich höhere Werte gesetzt wird. Die Obergrenze 6 ist schon seit recht langer Zeit überholt.DeathAndPain hat geschrieben: ↑05.02.2024 13:26ohne dass mir diese von den 6 maximal möglichen SAPGui-Modi abgezogen werden.
Folgende Benutzer bedankten sich beim Autor black_adept für den Beitrag:
DeathAndPain
Gerade auf das "mich selber eingeschlossen ... nach einem halben Jahr..." kann man gar nicht häufig genug hinweisen.DeathAndPain hat geschrieben: ↑05.02.2024 13:26Ich habe vor dem Problem auch schon gestanden, und die Lösung, die mir am besten gefällt, sieht so aus, dass ich zu Programmbeginn einen programmglobalen Datentyp mit sprechendem Namen deklariere. Den kann ich dann sowohl in meiner lokalen Klasse als auch im aufrufenden Programmcode verwenden, und seine Bedeutung erschließt sich dem Leser (mich selber eingeschlossen, wenn ich nach einem halben Jahr mal wieder auf den Code schaue) auf den ersten Blick.[/code]
Code: Alles auswählen.
CLASS lcl DEFINITION FINAL.
PUBLIC SECTION.
TYPES: BEGIN OF mts_selections,
t_r_werks TYPE RANGE OF marc-werks,
t_r_vtweg TYPE RANGE OF mvke-vtweg,
flag_whatever TYPE xfeld, " Oder abap_bool oder flag
END OF mts_selections.
CLASS-METHODS:
foo IMPORTING it_r_werks TYPE mts_selections-t_r_vtweg,
bar IMPORTING is_selections TYPE mts_selections.
ENDCLASS.
SELECT-OPTIONS: s_werks FOR marc-werks,
s_vtweg FOR mvke-vtweg.
PARAMETERS: cb_wtf AS CHECKBOX DEFAULT 'X'.
Aufruf:
lcl=>foo( s_vtweg[] ).
lcl=>bar( VALUE #( t_r_werks = s_werks[]
t_r_vtweg = s_vtweg[]
flag_whatever = cb_wtf
)
).
Hmm - SelOpts sind doch meistens an ein bestimmtes Programm gebunden. Da ist es völlig ausreichend diesem Programm Typen zu spendieren und es nicht im DDIC abzulegen.a-dead-trousers hat geschrieben: ↑05.02.2024 19:44Ja, klar man kann das Rad natürlich immer neu erfinden und in kleinen Projekten mag das durchaus lesbarer sein. Aber sobald man über Systemgrenzen hinweg arbeitet (Stichwort RFC) ist man mit dem DDIC (se11) einfach besser beraten. Und auch im eigenen System ist es ab einer gewissen Größe besser, wenn man die Typdefinitionen irgendwie zentral verwalten kann. Das kann jetzt in Form eines Interfaces oder von mir aus in der PUBLIC Section einer Klasse stattfinden ... oder warte mal ... hat die SAP nicht genau dafür etwas ganz spezielles geschaffen ... wie heißt das noch gleich ... DataDictionary ???.
Folgende Benutzer bedankten sich beim Autor black_adept für den Beitrag (Insgesamt 2):
a-dead-trousers • ewx