Code: Alles auswählen.
DATA: alv TYPE REF TO CL_SALV_TABLE,
itab TYPE "dein itab-Typ
cl_salv_table=>factory(
IMPORTING
r_salv_table = alv
CHANGING
t_table = itab ).
alv->display( ).
Code: Alles auswählen.
DATA: ALV_FIELDCAT TYPE SLIS_T_FIELDCAT_ALV WITH HEADER LINE,
ALV_LAYOUT TYPE SLIS_LAYOUT_ALV,
ALV_VARIANT LIKE DISVARIANT.
PERFORM ALV_LAYOUT_ERZEUGEN.
PERFORM ALV_AUSGEBEN. " interne Tabelle mit ALV-Daten heißt in diesem Beispiel M
*&---------------------------------------------------------------------*
*& Form ALV_LAYOUT_ERZEUGEN
*&---------------------------------------------------------------------*
FORM ALV_LAYOUT_ERZEUGEN.
CONSTANTS X VALUE 'X'.
REFRESH ALV_FIELDCAT.
ALV_LAYOUT-COLWIDTH_OPTIMIZE = SPACE.
* ALV_LAYOUT-INFO_FIELDNAME = 'LINECOLOR'. " Feld für Zeilenfarbe
ALV_LAYOUT-ZEBRA = X.
ALV_LAYOUT-CELL_MERGE = X.
ALV_VARIANT-REPORT = SY-REPID.
ALV_VARIANT-HANDLE = 'HAUPT'.
PERFORM NONDDIC_FIELDCATENTRY USING 8 'N' 'PERNR' 'Persnr' 'Personalnr' 'Personalnummer' SPACE SPACE.
PERFORM NONDDIC_FIELDCATENTRY USING ... all die anderen Spalten mit Komponentenbezeichnung, Kurztext, mittellangem Text und Langtext sowie Flag für Groß/Kleinschreibung und NO_OUT
ENDFORM. " ALV_LAYOUT_ERZEUGEN
*&---------------------------------------------------------------------*
*& Form NONDDIC_FIELDCATENTRY
*&---------------------------------------------------------------------*
FORM NONDDIC_FIELDCATENTRY USING OUTPUTLEN INTTYPE FIELDNAME SELTEXT_S SELTEXT_M SELTEXT_L LOWERCASE NO_OUT.
ALV_FIELDCAT-OUTPUTLEN = OUTPUTLEN.
ALV_FIELDCAT-INTTYPE = INTTYPE.
ALV_FIELDCAT-FIELDNAME = FIELDNAME.
ALV_FIELDCAT-SELTEXT_S = SELTEXT_S.
ALV_FIELDCAT-SELTEXT_M = SELTEXT_M.
ALV_FIELDCAT-SELTEXT_L = SELTEXT_L.
ALV_FIELDCAT-LOWERCASE = LOWERCASE.
ALV_FIELDCAT-NO_OUT = NO_OUT.
APPEND ALV_FIELDCAT.
ENDFORM. " NONDDIC_FIELDCATENTRY
*&---------------------------------------------------------------------*
*& Form ALV_AUSGEBEN
*&---------------------------------------------------------------------*
FORM ALV_AUSGEBEN.
DATA REPID LIKE SY-REPID.
MOVE SY-REPID TO REPID.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
I_CALLBACK_PROGRAM = REPID
I_CALLBACK_PF_STATUS_SET = 'SET_PF_STATUS'
I_CALLBACK_USER_COMMAND = 'USER_COMMAND'
IS_LAYOUT = ALV_LAYOUT
IT_FIELDCAT = ALV_FIELDCAT{} " sind eckige Klammern, aber die mutieren optisch im Forum
I_SAVE = 'U'
IS_VARIANT = ALV_VARIANT
TABLES
T_OUTTAB = M.
ENDFORM. " ALV_AUSGEBEN
*&---------------------------------------------------------------------*
*& Form SET_PF_STATUS
*&---------------------------------------------------------------------*
FORM SET_PF_STATUS USING RT_EXTAB TYPE SLIS_T_EXTAB.
SET PF-STATUS 'ALV'.
ENDFORM. " SET_PF_STATUS
*&---------------------------------------------------------------------*
*& Form USER_COMMAND
*&---------------------------------------------------------------------*
FORM USER_COMMAND USING I_UCOMM I_SELFIELD TYPE SLIS_SELFIELD.
DATA: DOKUOBJEKT TYPE DOKHL-OBJECT.
CASE I_UCOMM.
WHEN 'USE'. " Programmdokumentation anzeigen
DOKUOBJEKT = SY-REPID.
CALL FUNCTION 'DOCU_CALL'
EXPORTING
DISPL = 'X'
DISPL_MODE = '2'
ID = 'RE'
LANGU = 'D'
OBJECT = DOKUOBJEKT.
WHEN '&IC1'. " Doppelklick auf ALV-Zeile
CLEAR M.
READ TABLE M INDEX I_SELFIELD-TABINDEX.
CHECK NOT M-PERNR IS INITIAL.
" Bei Doppelklick in die PA20 abspringen, sofern entsprechende Berechtigung vorliegt
AUTHORITY-CHECK OBJECT 'S_TCODE' ID 'TCD' FIELD 'PA20'.
CHECK SY-SUBRC = 0.
CALL FUNCTION 'HR_CHECK_AUTHORITY_PERNR'
EXPORTING PERNR = M-PERNR
EXCEPTIONS NO_AUTHORIZATION_FOR_PERNR = 1.
IF SY-SUBRC <> 0.
MESSAGE TEXT-NOA TYPE 'S' DISPLAY LIKE 'E'.
EXIT.
ENDIF.
SET PARAMETER ID 'PER' FIELD M-PERNR.
CALL TRANSACTION 'PA20' AND SKIP FIRST SCREEN.
ENDCASE.
ENDFORM. " USER_COMMAND
Folgende Benutzer bedankten sich beim Autor DeathAndPain für den Beitrag:
fr-g
Code: Alles auswählen.
Feldkatalog lt_fcat erstellen lassen ( z.B. mit LVC_FIELDCATALOG_MERGE oder andere Themen hier im Forum
loop at lt_fcat assigning ...
case columname.
when 'FELDXYZ'. Besondere Eigenschaften hier setzen
when 'WEITERES_FELD'. Andere Eigenschaften setzen
endcase.
endloop.
Folgende Benutzer bedankten sich beim Autor black_adept für den Beitrag:
fr-g
Code: Alles auswählen.
DATA:
t_table TYPE TABLE OF lips,
r_salv_colsl TYPE REF TO cl_salv_columns_list,
r_salv_sorts TYPE REF TO cl_salv_sorts.
CALL METHOD cl_salv_table=>factory
IMPORTING
r_salv_table = DATA(r_salv)
CHANGING
t_table = t_table.
r_salv->get_columns( )->set_optimize( abap_true ).
* Icon oder Text in der Mitte der Zelle
r_salv_colsl->get_column( 'STATUS_ACC' )->set_alignment( if_salv_c_alignment=>centered ).
* Sort
r_salv_sorts = r_salv->get_sorts( ).
r_salv_sorts->add_sort( columnname = 'AWREF'
position = 1 ).
r_salv_sorts->add_sort( columnname = 'GLX_DOCNR'
position = 2 ).
PERFORM salv_rename_col USING r_salv_colsl:
'MESSAGE' text-mes,
'VBELN' text-bel.
r_salv_colsl->set_color_column( 'T_COLOR' ).
r_salv_colsl->set_cell_type_column( 'T_STYLE' ).
r_salv->display( ).
FORM salv_rename_col
USING iref_alv_cols TYPE REF TO cl_salv_columns_list
iv_fieldname TYPE fieldname
iv_text TYPE itex132.
DATA:
lref_alv_col TYPE REF TO cl_salv_column_table,
lref_error TYPE REF TO cx_root,
lv_text_s TYPE scrtext_s,
lv_text_m TYPE scrtext_m,
lv_text_l TYPE scrtext_l.
lv_text_l =
lv_text_m =
lv_text_s = iv_text.
TRY.
lref_alv_col ?= iref_alv_cols->get_column( iv_fieldname ).
CATCH cx_salv_not_found INTO lref_error.
ENDTRY.
IF NOT lref_error IS BOUND.
TRY.
lref_alv_col->set_long_text( lv_text_l ).
lref_alv_col->set_medium_text( lv_text_m ).
lref_alv_col->set_short_text( lv_text_s ). " --> wenn text( '' ) gesetzt wird und nur langtext mit Spaltenoptimierung
" dann wird nur der Langtext spaltenoptimiert angezeigt
CATCH cx_salv_not_found.
ENDTRY.
ENDIF.
ENDFORM.
In meinen Augen geht GMV (gesunder Menschenverstand) vor starren Regeln. In echter Logik benutze ich keine globalen Variablen. Ein ALV ist jedoch vergleichbar etwa einem Dynpro (in dem ja von der SAP vorgegebenermaßen auch alles global ist). Von daher sehe ich es entspannt, wenn meine ALV-Ausgabetabelle und deren Layout global ist.Globale Variablen sollten nicht verwendet werden
Bekanntlich bin ich ein großer Fan von Kopfzeilen und halte die Empfehlung, sie nicht mehr zu nutzen, für eine willkürliche Modeerscheinung. IMHO ist für jeden, der ABAP kann, aus dem Kontext auf einen Blick ersichtlich, ob er eine Kopfzeile oder den Tabellenrumpf vor sich hat, bzw. bei Tabellenrümpfen gebe ich immer explizit [] an (und nutze REFRESH statt CLEAR). Die Anforderungen an das geistige Abstraktionsvermögen, die durch Feldsymbole, funktionale Methoden und Variablenreferenzen, am besten noch in einem Ausdruck geschachtelt, an den Programmierer gestellt werden, sind um Größenordnungen größer als die Arbeit mit Kopfzeilen.Kopfzeilen schon mal gar nicht
Ich kann mich erinnern, den auch schon ein paarmal benutzt zu haben, weil er Sachen kann, die der REUSE nicht beherrscht. Das waren aber exotische Sachen, die man nur bei ganz wenigen ALVs braucht, und ich meine mich zu erinnern, dass beim LVC irgendwas umständlicher war. Das kann ich aber nicht belegen, und vielleicht täusche ich mich da auch. Ich bin halt beim REUSE geblieben, weil er perfekt ausreicht und ich halt ein neues ALV schnell per Copy&Paste aus einem Altprogramm hinbekomme (im Prinzip der Code, den ich oben gepostet habe).Heutzutage nehme ich statt des REUSE_ALV_GRID_DISPLAY lieber den REUSE_ALV_GRID_DISPLAY_LVC.
Das sind sie; deswegen dokumentiert ja auch niemand. Das ist für mich aber kein Maßstab.Manuelles Aufbauen eines Feldkatalogs? Ich dachte Programmierer sind faul.
Bei einer Firma, in der es komplett international SAPGui-User gibt, die sich in ihrer jeweiligen Landessprache anmelden, hast Du recht. Meine Firma ist auch international tätig, aber da ist die (nicht von mir stammende) Ansage, dass alles, was nicht deutsch ist, mit englisch arbeitet. Ich muss also den Feldkatalog neben deutsch per CASE SY-LANGU auch noch auf englisch bereitstellen, wenn es ein Programm ist, von dem ich nicht genau weiß, dass es nur in Deutschland genutzt werden wird, und dann ist das gut.Davon abgesehen muss man in dem Fall auch noch die ganzen Übersetzungen mitliefern ( es sei denn man programmiert für eine rein deutsche Firma - soll es ja auch noch geben ).
Habe ich mir auch schon überlegt, bin dann aber darüber gestolpert, dass ich von 20 Feldern doch 17 umdefinieren musste, und dann lohnt der Fax nicht. Das hängt auch damit zusammen, dass die Bedeutung vieler Felder kontextabhängig ist. Wenn ich beispielsweise eine Liste von Planstellen ausgebe, dann habe ich darin zwei Felder vom Typ PERNR. Die DDIC-Beschreibung "Personalnummer" nützt mir da aber nichts, schon gar nicht doppelt in derselben Liste, sondern die eine Spalte soll mit "Planstelleninhaber" und die andere mit "Führungskraft" überschrieben werden. Bei Feldern, deren Wert ich erst im Programm zusammenbaue (etwa Berechnungsergebnisse), lässt das DDIC mich sowieso im Stich.Vorteilhafter erscheint mir das Erstellen eines Feldkatalogs (kann gekapselt und wiederverwendet werden ) und dann manuelle Anpassungen für diejenigen Spalten, die nicht so bleiben sollen wie das System das vorschlägt.
Schön, dass sogar die SAP mal gemerkt hat, dass Objektorientierung nur um der Objektorientierung willen auch keine Punkte bringt.Meines Wissen war die von SAP im Laufe der Jahre empfohlene ALV-Listdarstellung folgende:
ganz alt: Die REUSE-Bausteine
die Klasse cl_gui_alv_grid ( Objektorientiert )
die SALV-Klasse, weil die noch viel mehr auf Objektorientierung setzt
aktuell wieder: Die Klasse cl_gui_alv_grid
Dieser Ausschnitt ist ein schönes Beispiel, weshalb ich den Kram nicht mag. Beim Aufbau des Feldkatalogs habe ich eine Struktur, der ich halt die benötigten Werte zuweise und fertig. Hier muss man für jeden einzelnen Wert extra eine Methode aufrufen und das ganze noch über einen TRY-ENDTRY-CATCH-Block absichern, damit einem der Mist nicht dumpen kann. Das finde ich nicht modern, sondern krank.Romaniac hat geschrieben:Code: Alles auswählen.
TRY. lref_alv_col->set_long_text( lv_text_l ). lref_alv_col->set_medium_text( lv_text_m ). lref_alv_col->set_short_text( lv_text_s ). " --> wenn text( '' ) gesetzt wird und nur langtext mit Spaltenoptimierung " dann wird nur der Langtext spaltenoptimiert angezeigt CATCH cx_salv_not_found. ENDTRY.
CASE SY-LANGU und nicht Textsymbole? SLIN wird nie dein Freund werden....DeathAndPain hat geschrieben:[...] Ich muss also den Feldkatalog neben deutsch per CASE SY-LANGU auch noch auf englisch bereitstellen,
Das habe ich noch nie gehört. Ich kann mir ja vorstellen, dass eine Spalte mal Planstelleninhaber und mal Führungskraft heißen soll. Und wenn das nur in einem einzigen Report vorkommt kann man ja auch so vorgehen wie du. Aber ich kanngar nicht glauben, dass es nicht noch zig andere Reports gibt, die diese Bezeichnungen auch noch brauchen könnten. Wenn du schon den ganzen Aufwand treibst - warum dann nicht im DDIC Datenelemente anlegen mit den richtigen Bezeichnungen und damit mit Wiederverwendungsmöglichkeit?DeathAndPain hat geschrieben:Habe ich mir auch schon überlegt, bin dann aber darüber gestolpert, dass ich von 20 Feldern doch 17 umdefinieren musste, und dann lohnt der Fax nicht. Das hängt auch damit zusammen, dass die Bedeutung vieler Felder kontextabhängig ist. Wenn ich beispielsweise eine Liste von Planstellen ausgebe, dann habe ich darin zwei Felder vom Typ PERNR. Die DDIC-Beschreibung "Personalnummer" nützt mir da aber nichts, schon gar nicht doppelt in derselben Liste, sondern die eine Spalte soll mit "Planstelleninhaber" und die andere mit "Führungskraft" überschrieben werden. Bei Feldern, deren Wert ich erst im Programm zusammenbaue (etwa Berechnungsergebnisse), lässt das DDIC mich sowieso im Stich.Vorteilhafter erscheint mir das Erstellen eines Feldkatalogs (kann gekapselt und wiederverwendet werden ) und dann manuelle Anpassungen für diejenigen Spalten, die nicht so bleiben sollen wie das System das vorschlägt.
Insofern habe ich das mit der DDIC-Unterstützung vor Jahren mal versucht und bin schnell davon abgekommen. Ja, der Aufbau des Feldkatalogs ist eine Fleißarbeit und ja, ich hasse sie, aber wenn ich mit dem Ergebnis zufrieden sein will, gibt es keinen anderen Weg.
Folgende Benutzer bedankten sich beim Autor black_adept für den Beitrag:
ralf.wenzel
Diesen Block kann man ja auch in eine weitere Methode auslagern, so geht das denke ich viel schneller wie das befüllen eines kompletten Feldkatalogs und hat eben den Vorteil der bereits Übersetzten Texte.Romaniac hat geschrieben:
CODE: ALLES AUSWÄHLEN
TRY.
lref_alv_col->set_long_text( lv_text_l ).
lref_alv_col->set_medium_text( lv_text_m ).
lref_alv_col->set_short_text( lv_text_s ). " --> wenn text( '' ) gesetzt wird und nur langtext mit Spaltenoptimierung
" dann wird nur der Langtext spaltenoptimiert angezeigt
CATCH cx_salv_not_found.
ENDTRY.
Das ist aber kein Alleinstellungsmerkmal des SALV, sondern den automatisierten Aufbau der Feldliste gibt es auch für alle anderen ALV-Versionen. Evtl. muss man einen Fuba/Methode dazu aufrufen, aber häufig genug kann man auf das DDIC referenzieren und alles klappt auch hier automatisch.abuma hat geschrieben: also ich persönlich finde salv schon sehr praktisch, gerade auch mit der Feldliste die man nicht selber mühsam aufbauen muss.
Nein. Ein Dynpro funktioniert nach einem ganz anderes Prinzip als ein ALV, was man schon daran erkennt, dass ein ALV ein Dynpro braucht.DeathAndPain hat geschrieben:In meinen Augen geht GMV (gesunder Menschenverstand) vor starren Regeln. In echter Logik benutze ich keine globalen Variablen. Ein ALV ist jedoch vergleichbar etwa einem Dynpro.Globale Variablen sollten nicht verwendet werden
Bei dir vielleicht Ich verwende Klassenattribute (und ja, das ist etwas ganz anderes).DeathAndPain hat geschrieben:Ansonsten sind bei mir auch Puffertabellen global.
Es ist eher eine willkürliche ABAP-Erscheinung, dass man einen Variablennamen für unterschiedliche Variablen verwendet und man nur deshalb REFRESH erfindet, obwohl ein CLEAR reicht. Eine Tabelle ist für mich eine Variable und die lösche ich mit CLEAR.DeathAndPain hat geschrieben:Bekanntlich bin ich ein großer Fan von Kopfzeilen und halte die Empfehlung, sie nicht mehr zu nutzen, für eine willkürliche Modeerscheinung.Kopfzeilen schon mal gar nicht
Lösung: LOOP AT variable INTO DATA(variable). Ich aber bevorzuge Feldsymbole, weil das schön knallt, wenn es nicht zugewiesen ist, statt einfach nur "leer" zu sein (bei einem LOOP nicht relevant, bei einem READ schon).DeathAndPain hat geschrieben:LOOP AT variable ASSIGNING FIELD-SYMBOL(<variable>) en passant eine passende Workarea mit sprechendem Namen beschaffen kann, dann ist das wunderbar, und ich bin nur etwas unglücklich darüber, dass die Winkelklammern um den Variablennamen sich so blöd tippen.
Das und implizite Kopfzeilen sind Dinge, deren Verständnis denen sehr schwer fällt, die aus anderen Programmiersprachen kommen. Das spricht sicher für sich.DeathAndPain hat geschrieben:Der einst von der SAP bei TABLES gewählte Ansatz, eine zweite Workarea per Stern vor dem Tabellennamen bereitzustellen, erscheint mir bedeutend programmiererfreundlicher und zugleich hervorragend lesbar.
Ich nutze im Allgemeinen die SALV-Klasse. Das ist am einfachsten zu skalieren, vom Einfachstaufruf (der wirklich sehr einfach ist) bis hin zu sehr komplexem Gedöns.Heutzutage nehme ich statt des REUSE_ALV_GRID_DISPLAY lieber den REUSE_ALV_GRID_DISPLAY_LVC.
Nein. Man kann einen großen drumrum bauen nach dem Motto "ich weise jetzt alle Feldeigenschaften zu, wenn (irgend)was dabei schiefgeht, ist das ein Fehler". Man kann mit Ausnahmeklassen irre Sachen machen, wenn man ein bisschen kreativ ist. Früher hab ich die Dinger gehasst wie die Pest, aber seit ich z. B. weiß, wie ich komplette Protokolle durch Verschachteln von Ausnahmen zusammenbauen kann, die ich dann einmal "auspacke" und ins Anwenderlog schreibe (mit einer generischen Klasse, die ich einmal geschrieben habe für das ganze System), bin ich ein echter Fan davon, weil ich dazu nix mehr selbst machen muss.DeathAndPain hat geschrieben:Dieser Ausschnitt ist ein schönes Beispiel, weshalb ich den Kram nicht mag. Beim Aufbau des Feldkatalogs habe ich eine Struktur, der ich halt die benötigten Werte zuweise und fertig. Hier muss man für jeden einzelnen Wert extra eine Methode aufrufen und das ganze noch über einen TRY-ENDTRY-CATCH-Block absichern, damit einem der Mist nicht dumpen kann.Romaniac hat geschrieben:Code: Alles auswählen.
TRY. lref_alv_col->set_long_text( lv_text_l ). lref_alv_col->set_medium_text( lv_text_m ). lref_alv_col->set_short_text( lv_text_s ). " --> wenn text( '' ) gesetzt wird und nur langtext mit Spaltenoptimierung " dann wird nur der Langtext spaltenoptimiert angezeigt CATCH cx_salv_not_found. ENDTRY.