Minuszeichen vor dem Wert im ALV anzeigen

Heute hat ein Gruppenmitglied in unserer Telegram Chatgruppe die Frage gestellt, wie man das Minuszeichen vor dem Wert anstatt hinter dem Wert im ALV anzeigen kann. Dabei soll aber die Möglichkeit der Summen- und Zwischensummenbildung erhalten bleiben.

Anforderung an den Test:

  • Einen Weg finden das Minuszeichen vor den Wert zu bringen
  • Sicherstellen, dass die Dezimaldarstellung des Benutzers erhalten bleibt

Fragestellung und Entscheidung zur Umsetzung:

  1. Kann es unter Berücksichtigung des Standards umgesetzt werden?
    • Nein, denn weder der Feldkatalog noch das Layout des ALV bieten eine Möglichkeit.
  2. Muss hier entwickelt werden?
    • Ja, wir benötigen eine Konvertierungsroutine. Das bedeutet, dass wir eine Funktionsgruppe und zwei Funktionsbausteine anlegen müssen.

Umsetzungsschritte

Info: Ich habe alle Popup mit Warnungen und Paketzuweisungen nicht in Artikel aufgenommen. Alle Warnungen, die in diesem Beispiel auftreten habe ignoriert und die Objekte habe ich in das lokale Paket $TMP aufgenommen.

Gedanken über die Anforderung und die Probleme während der Implementierung machen.

Wenn wir eine Konvertierungsroutine für eine Zahl implementieren möchten, müssen wir auch daran denken, dass die Dezimaldarstellung des Benutzers aus seinen Einstellungen (TAC:SU01/SU3) erhalten bleibt. Das bedeutet, dass wir eine flexible EDIT MASK in die Konvertierungsroutine für die Anzeige einbauen müssen.

Konvertierungsroutine anlegen.

Eine Konvertierungs-Routine wird über einen fünfstelligen Namen identifiziert und ist als Gruppe von zwei Funktionsbausteinen abgelegt. Die Funktionsbausteine haben dabei eine festgelegte Namenskonvention. Der Konvertierungs-Routine xxxxx sind folgende Funktionsbausteine zugeordnet:

  • CONVERSION_EXIT_xxxxx_INPUT
  • CONVERSION_EXIT_xxxxx_OUTPUT

Funktionsgruppe anlegen

Um die benötigte Funktionsgruppe anzulegen, habe ich die Transaktion SE37 benutzt. Dafür sollte das Funktionsbaustein Feld leer bleiben und wir navigieren zu Menü->Springen->FGruppenverwaltung->Gruppe anlegen.
Gewünschten Name und Kurztext für die Gruppe eingeben und Sichern.

Navigiere zum Topinclude der Funktionsgruppe und füge den folgenden Code ein:

1
2
3
4
FUNCTION-POOL zstkoes_sign_conversion.      "MESSAGE-ID..
DATA:
  gv_decimal_sign   TYPE char1,
  gv_separator      TYPE char1.

Funktionsbaustein Intern -> Anzeige anlegen

Im Einstiegsbild der SE37 einen Namen für den Funktionsbaustein eingeben “CONVERSION_EXIT_XXXXX_OUTPUT” (XXXX durch den gewünschten Namen für die Routine ersetzen).
Den Funktionsbaustein der neuen Funktionsgruppe zuweisen, den Kurztext eingeben und Sichern.
Es ist erforderlich einen Importingparameter mit INPUT zubenennen.
Es ist erforderlich einen Exportingparameter mit OUTPUT zubenennen.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
" Get the Decimal Format from the user settings (SU01/SU3)
" Dezimaldarstellung aus den Benutzereinstellungen holen (SU01/SU3)
IF gv_decimal_sign IS INITIAL.
  CALL FUNCTION 'CLSE_SELECT_USR01'
    EXPORTING
      username         = sy-uname
      iv_delete_buffer = abap_true
    IMPORTING
      decimal_sign     = gv_decimal_sign
      separator        = gv_separator.
ENDIF.
DATA(lv_input) = CONV string( input ).
DATA(lv_negativ_number) = boolc( lv_input CS '-' ).
REPLACE ALL OCCURRENCES OF '-' IN lv_input WITH ''.
SPLIT lv_input AT '.' INTO DATA(lv_number) DATA(lv_decimals).
REPLACE ALL OCCURRENCES OF '.' IN lv_input WITH ''.
DO strlen( lv_number ) TIMES.
  IF sy-index EQ 1.
    DATA(lv_mask) = |_|.
    CONTINUE.
  ENDIF.
  lv_mask = |_{ COND #( WHEN sy-index MOD 3 EQ 1 THEN gv_separator ) }{ lv_mask }|.
ENDDO.
DO strlen( lv_decimals ) TIMES.
  IF sy-index EQ 1.
    lv_mask = |{ lv_mask }{ gv_decimal_sign }_|.
    CONTINUE.
  ENDIF.
  lv_mask = |{ lv_mask }_|.
ENDDO.
lv_mask = |{ COND #( WHEN lv_negativ_number EQ abap_true THEN |-| ) }{ lv_mask }|.
WRITE lv_input TO output USING EDIT MASK lv_mask.

Funktionsbaustein Anzeige -> Intern anlegen

Im Einstiegsbild der SE37 einen Namen für den Funktionsbaustein eingeben “CONVERSION_EXIT_XXXXX_OUTPUT” (XXXX durch den bereits für OUTPUT benutzen Namen für die Routine ersetzen).
Den Funktionsbaustein der neuen Funktionsgruppe zuweisen, den Kurztext eingeben und Sichern.
Es ist erforderlich einen Importingparameter mit INPUT zubenennen.
Es ist erforderlich einen Exportingparameter mit OUTPUT zubenennen.
Für die korrekte Fehlerbehandlung, falls der Benutzer eine ungültige Zahl eingibt, ist es erforderlich einen Exceptionparameter mit ERROR_MESSAGE zubenennen.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
" Get the Decimal Format from the user settings (SU01/SU3)
" Dezimaldarstellung aus den Benutzereinstellungen holen (SU01/SU3)
IF gv_decimal_sign IS INITIAL.
  CALL FUNCTION 'CLSE_SELECT_USR01'
    EXPORTING
      username         = sy-uname
      iv_delete_buffer = abap_true
    IMPORTING
      decimal_sign     = gv_decimal_sign
      separator        = gv_separator.
ENDIF.
DATA(lv_input) = CONV string( input ).
REPLACE ALL OCCURRENCES OF gv_separator IN lv_input WITH ''.
REPLACE gv_decimal_sign IN lv_input WITH '.'.
CONDENSE lv_input NO-GAPS.
TRY.
    output = lv_input.
  CATCH cx_sy_conversion_no_number.
    " Clear message fields of sy structure, so that 'Conversion error' will be raised
    " Alle Message Felder der sy Struktur löschen, damit 'Fehler bei der Konvertierung.' geworfen wird
    CLEAR: sy-msgty, sy-msgno, sy-msgv1, sy-msgv2, sy-msgv3, sy-msgv4.
    RAISE error_message.
ENDTRY.

Aktivierung der neuen Funktionsgruppe und Funktionsbausteine

Jetzt müssen die Funktionsgruppe und die Funktionsbausteine noch aktiviert werden.

Konvertierungsroutine implementieren

Konvertierungsroutine in eine Domäne implementieren

Nun legen wir eine neue Domäne an oder kopieren eine vorhandene und weisen die neu angelegte Konvertierungsroutine der Domäne zu.

Konvertierungsroutine zur Laufzeit in ein ALV implementieren

In dem Demo Report findest du, wie du die Konvertierungsroutine zur Laufzeit den Feldern des ALV zuweisen kannst.

Demo Report

Hier ist ein kleiner Demo Report mit der Implementierung.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
REPORT zstkoes_alv_sort.
TYPES:
  BEGIN OF gty_mard,
    matnr   TYPE matnr,
    werks   TYPE werks_d,
    lgort   TYPE lgort_d,
    labst   TYPE labst,
    zlabst  TYPE zlabst,
    h_level TYPE h_level,
  END OF gty_mard,
  gtty_mard TYPE gty_mard.
DATA:
  gt_mard TYPE TABLE OF gtty_mard.
gt_mard = VALUE #(
  ( matnr = CONV numc4( 1 ) werks = '0001' lgort = '0001' labst = '-9.999' zlabst = '-9.999' h_level = -99999999 )
  ( matnr = CONV numc4( 1 ) werks = '0001' lgort = '0002' labst = '-99.999' zlabst = '-99.999' h_level = -9999999 )
  ( matnr = CONV numc4( 1 ) werks = '0002' lgort = '0001' labst = '-999.999' zlabst = '-999.999' h_level = -999999 )
  ( matnr = CONV numc4( 1 ) werks = '0002' lgort = '0002' labst = '-9999.999' zlabst = '-9999.999' h_level = -99999 )
  ( matnr = CONV numc4( 2 ) werks = '0001' lgort = '0001' labst = '-99999.999' zlabst = '-99999.999' h_level = -9999 )
  ( matnr = CONV numc4( 2 ) werks = '0001' lgort = '0002' labst = '-999999.999' zlabst = '-999999.999' h_level = -999 )
  ( matnr = CONV numc4( 2 ) werks = '0002' lgort = '0001' labst = '-9999999.999' zlabst = '-9999999.999' h_level = -99 )
  ( matnr = CONV numc4( 2 ) werks = '0002' lgort = '0002' labst = '-99999999.999' zlabst = '-99999999.999' h_level = -9 ) ).
cl_salv_table=>factory(
  IMPORTING
    r_salv_table   = DATA(lo_table)    " Basisklasse einfache ALV Tabellen
  CHANGING
    t_table        = gt_mard ).
lo_table->get_functions( )->set_all( ).
DATA(it_column_ref) = lo_table->get_columns( )->get( ).
LOOP AT it_column_ref ASSIGNING FIELD-SYMBOL(<st_column_ref>).
  CASE <st_column_ref>-columnname.
    WHEN 'H_LEVEL'.
      <st_column_ref>-r_column->set_edit_mask( value = '==ZSIGN' ).
  ENDCASE.
ENDLOOP.
lo_table->display( ).

Ergebnis

So sieht das Ergebnis der Entwicklung aus.
  • Die vierte Spalte “Frei verwendbar” benutzt die neue Konvertierungsroutine nicht und zeigt das Minuszeichen somit hinter dem Wert an.
  • Die fünfte Spalte “Frei verwendbar” benutzt die neue Konvertierungsroutine und zeigt das Minuszeichen, wie erwartet, somit vor dem Wert an.
  • Die sechste Spalte “Baugruppenstufe” ist vom Typ Integer, benutzt die neue Konvertierungsroutine und zeigt das Minuszeichen, wie erwartet, somit vor dem Wert an.