[ABAP] Verwendung von Buttons, Links, Comboboxen, Editfeldern in cl_dd_document (Dynamische Dokumente), Eventhandling

DATA: o_doc TYPE REF TO cl_dd_document.
DATA: o_form_area TYPE REF TO cl_dd_form_area.
DATA: o_input TYPE REF TO cl_dd_input_element.
DATA: o_combo TYPE REF TO cl_dd_select_element.
DATA: o_btn TYPE REF TO cl_dd_button_element.
DATA: o_link TYPE REF TO cl_dd_link_element.

DATA: it_options TYPE sdydo_option_tab.

CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      on_button_clicked FOR EVENT clicked OF cl_dd_button_element
        IMPORTING
            sender.
    CLASS-METHODS:
      on_selected FOR EVENT selected OF cl_dd_select_element
        IMPORTING
            sender.
    CLASS-METHODS:
      on_enter FOR EVENT entered OF cl_dd_input_element
        IMPORTING
            sender.
    CLASS-METHODS:
      on_f1 FOR EVENT help_f1 OF cl_dd_input_element
        IMPORTING
            sender.
    CLASS-METHODS:
      on_link_clicked FOR EVENT clicked OF cl_dd_link_element
        IMPORTING
            sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
  METHOD on_button_clicked.
    MESSAGE |{ sender->name }: { o_input->value } und { o_combo->value }| TYPE 'I'.
  ENDMETHOD.

  METHOD on_selected.
    MESSAGE sender->value TYPE 'I'.
  ENDMETHOD.

  METHOD on_enter.
    MESSAGE |{ sender->name }: { sender->value }| TYPE 'I'.
  ENDMETHOD.

  METHOD on_f1.
    MESSAGE |{ sender->name }: { sender->value }| TYPE 'I'.
  ENDMETHOD.

  METHOD on_link_clicked.
    MESSAGE |{ sender->name }| TYPE 'I'.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
* Dokument
  o_doc = NEW cl_dd_document( ).
  o_doc->add_text( text      = 'Eingabefelder'
                   sap_style = cl_dd_area=>heading ).
* Formular
  o_doc->add_form( IMPORTING formarea = o_form_area ).

* Editfeld
  o_form_area->add_input_element( EXPORTING
                                    value         = 'Wert'
                                    name          = 'EDINPUT'
                                    size          = '40'
                                    maxlength     = '40'
                                    tooltip       = 'Bitte einen Wert eingeben'
                                  IMPORTING
                                    input_element = o_input ).

  SET HANDLER lcl_events=>on_enter FOR o_input.
  SET HANDLER lcl_events=>on_f1 FOR o_input.

* Combobox
  it_options = VALUE #( ( value = 'P1' text = 'Punkt1' )
                        ( value = 'P2' text = 'Punkt2' )
                        ( value = 'P3' text = 'Punkt3' ) ).

  o_form_area->add_select_element( EXPORTING
                                     name           = 'CBTEST'
                                     value          = 'P2'
                                     options        = it_options
                                   IMPORTING
                                     select_element = o_combo ).

  SET HANDLER lcl_events=>on_selected FOR o_combo.

* Button
  o_form_area->add_button( EXPORTING
                             sap_icon = 'ICON_LED_GREEN'
                             label    = 'Klick'
                             name     = 'BTN_TEST'
                           IMPORTING
                             button   = o_btn ).

  SET HANDLER lcl_events=>on_button_clicked FOR o_btn.

* Link
  o_form_area->add_link( EXPORTING
                           text    = 'Linktext'
                           name    = 'LINK1'
                           tooltip = 'Klick me'
                         IMPORTING
                           link    = o_link ).

  SET HANDLER lcl_events=>on_link_clicked FOR o_link.

* Dokumentelemente zusammenführen
  o_doc->merge_document( ).

* Dokument anzeigen
  o_doc->display_document( parent = cl_gui_container=>default_screen ).

* erzwingen von cl_gui_container=>default_screen
  WRITE space.

[ABAP] Verwendung von Tabellen in cl_dd_document (Dynamische Dokumente)

TRY.
* DD-Dokumentobjekt anlegen und Hintergrundfarbe festlegen
    DATA(o_doc) = NEW cl_dd_document( background_color = cl_dd_area=>col_textarea ).

* max. 255 Zeichen
    o_doc->add_text( text          = 'Fluginformationen'
                     sap_style     = cl_dd_document=>heading ).

* Trennlinie
    o_doc->underline( ).

* Text
    o_doc->add_text( text          = 'Tabelle:'
                     sap_emphasis  = cl_dd_document=>strong
                     sap_fontstyle = cl_dd_area=>serif ).

* Leerzeile
    o_doc->new_line( ).

    DATA: o_table TYPE REF TO cl_dd_table_element.
    DATA: o_table_area TYPE REF TO cl_dd_table_area.

* Tabelle mit 2 Spalten anlegen
    o_doc->add_table( EXPORTING
                        no_of_columns               = 2
                        cell_background_transparent = abap_false
                      IMPORTING
                        table                       = o_table
                        tablearea                   = o_table_area ).

* Spalte 1, Stil hellblau
    o_table->set_column_style( col_no    = 1
                               sap_style = cl_dd_area=>key ).

* Tabelle hat 2 Spalten, daher 2 Texte hinzufügen
    o_table_area->add_text( text = 'Fluggesellschaft' sap_emphasis = cl_dd_area=>strong ).
    o_table_area->add_text( text = 'LH' ).

* Zeile voll - weiter zur nächsten Zeile
    o_table_area->new_row( ).

    o_table_area->add_text( text = 'Flugnummer' sap_emphasis = cl_dd_area=>strong ).
    o_table_area->add_text( text = '400' ).

* Zweite Zeile voll
    o_table_area->new_row( ).

* Zeile 3
    o_table_area->add_text( text = 'Von' sap_emphasis = cl_dd_area=>strong ).
    o_table_area->add_text( text = 'Frankfurt' ).

* Dritte Zeile voll
    o_table_area->new_row( ).

* Zeile 4
    o_table_area->add_text( text = 'Nach' sap_emphasis = cl_dd_area=>strong ).
    o_table_area->add_text( text = 'New York' ).

* Vierte Zeile voll
    o_table_area->new_row( ).

* Dokumentelemente zusammenführen
    o_doc->merge_document( ).
* Dokument im Standardcontainer anzeigen
    o_doc->display_document( parent = cl_gui_container=>default_screen ).

* erzwingen von cl_gui_container=>default_screen
    WRITE space.

  CATCH cx_root INTO DATA(e_txt).
    WRITE: / e_txt->get_text( ).
ENDTRY.

[ABAP] GUI-Elemente ohne Dynprodefinition anzeigen

Variante 1 (Listausgabe mit WRITE erzwingen)

START-OF-SELECTION.

  DATA: it_sflight TYPE STANDARD TABLE OF sflight.

  SELECT * FROM sflight INTO TABLE @it_sflight.

* ALV-Grid in Standarddynpro cl_gui_container=>default_screen einbetten
  DATA(o_alv) = NEW cl_gui_alv_grid( i_parent = cl_gui_container=>default_screen ).

  o_alv->set_table_for_first_display( EXPORTING
                                        i_structure_name = 'SFLIGHT'
                                      CHANGING
                                        it_outtab        = it_sflight ).

* Ausgabe von cl_gui_container=>default_screen erzwingen
  WRITE space.

Variante 2 (Aufruf leeres Dynpro 100)

SELECTION-SCREEN BEGIN OF SCREEN 100.
SELECTION-SCREEN END OF SCREEN 100.

START-OF-SELECTION.

  DATA: it_sflight TYPE STANDARD TABLE OF sflight.

  SELECT * FROM sflight INTO TABLE @it_sflight.

* ALV-Grid in Standarddynpro cl_gui_container=>default_screen einbetten
  DATA(o_alv) = NEW cl_gui_alv_grid( i_parent = cl_gui_container=>default_screen ).

  o_alv->set_table_for_first_display( EXPORTING
                                        i_structure_name = 'SFLIGHT'
                                      CHANGING
                                        it_outtab        = it_sflight ).

* leeres Dynpro anzeigen und Ausgabe von cl_gui_container=>default_screen erzwingen
  CALL SCREEN 100.

[ABAP] Eigene GUI-Toolbar in einem Split-Container anzeigen, Eventhandling

TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.

CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      on_function_selected FOR EVENT function_selected OF cl_gui_toolbar
        IMPORTING
            fcode
            sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
* Toolbar Button geklickt
  METHOD on_function_selected.

    CASE fcode.
      WHEN 'BTN_CLOSE'.
        LEAVE PROGRAM.
      WHEN 'BTN_TEST'.
        MESSAGE 'TEST' TYPE 'I' DISPLAY LIKE 'S'.
    ENDCASE.

  ENDMETHOD.

ENDCLASS.

INITIALIZATION.

* Splitter erzeugen
  DATA(o_splitter) = NEW cl_gui_splitter_container( parent = cl_gui_container=>default_screen
                                                    no_autodef_progid_dynnr = abap_true
                                                    rows = 2
                                                    columns = 1 ).

* Absoluter Modus für Zeilenhöhe
  o_splitter->set_row_mode( mode = cl_gui_splitter_container=>mode_absolute ).

* Höhe absolut 24 Pixel für Splitter oben
  o_splitter->set_row_height( id = 1 height = 24 ).

* Splitter für oberen Container fest und verborgen
  o_splitter->set_row_sash( id = 1
                            type = cl_gui_splitter_container=>type_movable
                            value = cl_gui_splitter_container=>false ).

  o_splitter->set_row_sash( id = 1
                            type = cl_gui_splitter_container=>type_sashvisible
                            value = cl_gui_splitter_container=>false ).

  DATA(o_container_top) = o_splitter->get_container( row = 1 column = 1 ).
  DATA(o_container_bottom) = o_splitter->get_container( row = 2 column = 1 ).

* Toolbar hoizontal
  DATA(o_tool) = NEW cl_gui_toolbar( parent = o_container_top
                                     display_mode = cl_gui_toolbar=>m_mode_horizontal ).

* Eventtypten müssen gesondert registriert werden
  DATA(it_events) = VALUE ty_it_events( ( eventid = cl_gui_toolbar=>m_id_function_selected
                                          appl_event = abap_true ) ).

  o_tool->set_registered_events( events = it_events ).

* Toolbar-Buttons hinzufügen
* Buttontypen sind in Typgruppe CNTB definiert
  o_tool->add_button( fcode       = 'BTN_TEST'
                      icon        = icon_activate
                      butn_type   = cntb_btype_button
                      text        = 'Test'
                      quickinfo   = 'Test'
                      is_checked  = abap_false
                      is_disabled = abap_false ).

  o_tool->add_button( fcode       = ''
                      icon        = ''
                      butn_type   = cntb_btype_sep
                      text        = ''
                      quickinfo   = ''
                      is_checked  = abap_false
                      is_disabled = abap_false ).

  o_tool->add_button( fcode       = 'BTN_CLOSE'
                      icon        = icon_close
                      butn_type   = cntb_btype_button
                      text        = 'Schließen'
                      quickinfo   = 'Schließen'
                      is_checked  = abap_false
                      is_disabled = abap_false ).

* Eventhandler registrieren
  SET HANDLER lcl_events=>on_function_selected FOR o_tool.

* im unteren Splitter Beispieldaten anzeigen
  DATA: it_sflight TYPE STANDARD TABLE OF sflight.

  SELECT * FROM sflight INTO TABLE @it_sflight.

  DATA: o_salv TYPE REF TO cl_salv_table.

  cl_salv_table=>factory( EXPORTING
                            r_container    = o_container_bottom
                          IMPORTING
                            r_salv_table   = o_salv
                          CHANGING
                            t_table        = it_sflight ).

  o_salv->get_functions( )->set_all( ).
  o_salv->display( ).

* leere Standard-Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

* Ausgabe von cl_gui_container=>default_screen erzwingen
  WRITE: space.

[ABAP] Splitter (cl_gui_splitter_container) fixieren und dessen absolute Höhe festlegen

INITIALIZATION.

* Splitter erzeugen
  DATA(o_splitter) = NEW cl_gui_splitter_container( parent = cl_gui_container=>default_screen
                                                    no_autodef_progid_dynnr = abap_true
                                                    rows = 2
                                                    columns = 1 ).

* Absoluter Modus für Zeilenhöhe
  o_splitter->set_row_mode( mode = cl_gui_splitter_container=>mode_absolute ).

* Höhe absolut 40 Pixel für Splitter oben
  o_splitter->set_row_height( id = 1 height = 40 ).

* Splitter für oberen Container fest und verborgen
  o_splitter->set_row_sash( id = 1
                            type = cl_gui_splitter_container=>type_movable
                            value = cl_gui_splitter_container=>false ).

  o_splitter->set_row_sash( id = 1
                            type = cl_gui_splitter_container=>type_sashvisible
                            value = cl_gui_splitter_container=>false ).

  DATA(o_container_top) = o_splitter->get_container( row = 1 column = 1 ).
  DATA(o_container_bottom) = o_splitter->get_container( row = 2 column = 1 ).
  
  ...

* Ausgabe von cl_gui_container=>default_screen erzwingen
  WRITE: space.

[ABAP] GUI Containertypen

cl_gui_container

* cl_gui_container=>default_screen
* cl_gui_container=>screen0 ... cl_gui_container=>screen9
  • Fullscreen-Container der Listenausgabe
  • Erzeugung erfolgt z.B. bei WRITE (Bsp.: WRITE space.)
  • können als Basis für weitere Container genommen werden

Beispiel für cl_gui_container: Link

cl_gui_splitter_container

  • Splitter mit Subcontainern
  • benötigt Parent (z.B. cl_gui_container=>screen0, cl_gui_docking_container, cl_gui_custom_container)

Beispiel für cl_gui_splitter_container: Link

cl_gui_docking_container

  • Dock-Seite kann angegeben werden
  • Breite / Höhe kann absolut (extension) oder relativ (ratio) angegeben werden

Beispiel für cl_gui_docking_container: Link

cl_gui_dialogbox_container

  • erzeugt ein neues eigenständiges Fenster
  • Event “on_close” sollte behandelt werden, damit auf das Schließen-Kreuz reagiert werden kann

Beispiel für cl_gui_dialogbox_container: Link

cl_gui_custom_container

  • Containerobjekt zur Verwendung auf Dynpros
  • ein Name muss vergeben werden

Beispiel für cl_gui_custom_container: Link

cl_gui_gos_container

  • Containerobjekt für Anzeige von Generic Object Services (GOS) in der Titlebar
  • beliebige Untercontainer können eingebettet werden

Beispiel für cl_gui_gos_container: Link

cl_gui_container_bar

  • vertikales Tabstrip mit Auswahl-Buttons

Beispiel für cl_gui_container_bar: Link

cl_gui_container_bar_2

  • vertikales Tabstrip mit Auswahl-Buttons und Schließen-Kreuz
  • drei Anzeigemodi (fix (Feste Anordnung), tile (Menü), outlook (Anordnung klappt))

Beispiel für cl_gui_container_bar_2: Link

cl_gui_container_bar_xt

  • vertikales Tabstrip mit Auswahl-Buttons und Schließen-Kreuz
  • zwei Anzeigemodi (fix (Feste Anordnung), outlook (Anordnung klappt))

Beispiel für cl_gui_container_bar_xt: Link

[ABAP] Nutzung der Google-Chart-API zur Anzeige von Charts

* Beispiel adaptiert von:
* http://www.tricktresor.de/blog/sap-und-bunte-bilder-cl_gui_html_viewer/

DATA: lv_s032 TYPE s032.
SELECT-OPTIONS: so_werks FOR lv_s032-werks.

START-OF-SELECTION.

* Alle Bestände je Werk aus der S032 summieren
  SELECT werks,                    " Werk
         SUM( wbwbest ) AS wbwbest " Summe Wert Bewerteter Bestand
    INTO TABLE @DATA(it_data)
    FROM s032
      WHERE werks IN @so_werks
        AND vrsio = '000'
      GROUP BY werks.

* HTML-Code erzeugen
  DATA(it_html) = VALUE html_table(
                                    ( |<html>| )
                                    ( |  <head>| )
                                    ( |    <script type="text/javascript" src="https://www.google.com/jsapi"></script>| )
                                    ( |    <script type="text/javascript">| )
                                    ( |      google.load("visualization", "1", \{packages:["corechart"]\});| )
                                    ( |      google.setOnLoadCallback(drawChart);| )
                                    ( |      function drawChart() \{| )
                                    ( |        var data = google.visualization.arrayToDataTable([ ['Werk', 'Bestand'],| )
                                  ).

* Daten aus der iTab in den Code einfügen
  DATA(lv_html) = ||.

  LOOP AT it_data ASSIGNING FIELD-SYMBOL(<d>).
    IF lv_html IS INITIAL.
      lv_html = |        ['{ <d>-werks }', { <d>-wbwbest }]|.
    ELSE.
      lv_html = |        ,['{ <d>-werks }', { <d>-wbwbest }]|.
    ENDIF.

    APPEND lv_html TO it_html.
  ENDLOOP.

* Code abschließen
  it_html = VALUE html_table( BASE it_html
                              ( |        ]);| )
                              ( |        var options = \{title: 'Summe bewertete Bestände pro Werk'\};| )
                              ( |        var chart = new google.visualization.PieChart(document.getElementById('piechart'));| )
                              ( |        chart.draw(data, options);| )
                              ( |      \};| )
                              ( |    </script>| )
                              ( |  </head>| )
                              ( |  <body>| )
                              ( |    <div id="piechart" style="width: 900px; height: 500px;"></div>| )
                              ( |  </body>| )
                              ( |</html>| )
                            ).

* HTML-Viewer
  DATA(o_html) = NEW cl_gui_html_viewer( parent = cl_gui_container=>default_screen ).

* URL zu HTML holen
  DATA: lv_url TYPE swk_url.

  o_html->load_data( IMPORTING
                       assigned_url = lv_url
                     CHANGING
                       data_table   = it_html ).

* HTML anzeigen
  o_html->show_url( url = lv_url ).

* leere Standard-Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

* Ausgabe von cl_gui_container=>default_screen erzwingen
  WRITE: space.

[ABAP] SALV-Table: Funktionsbuttons hinzufügen

Variante 1 (nur wenn in eigenem Dynpro + Container)

SELECT * FROM sflights INTO TABLE @DATA(it_data).

DATA: o_salv TYPE REF TO cl_salv_table.

cl_salv_table=>factory( EXPORTING
                          r_container  = cl_gui_container=>default_screen " Standard-Container der Listausgabe nutzen
                        IMPORTING
                          r_salv_table = o_salv
                        CHANGING
                          t_table      = it_data ).

o_salv->get_functions( )->set_all( ).

* Für diesen Button muss zus. noch ein Event-Handler ausgeprägt werden
o_salv->get_functions( )->add_function( name     = 'MYFUNC'
                                        icon     = |{ icon_complete }|
                                        text     = 'Funktionstext'
                                        tooltip  = 'ToolTipText'
                                        position = if_salv_c_function_position=>right_of_salv_functions ).

o_salv->display( ).

* Erzwingen von cl_gui_container=>default_screen (Listausgabe)
WRITE space.

Variante 2 (PF_STATUS)

* ohne Angabe eines Containers in der factory-Methode:
SELECT * FROM sflights INTO TABLE @DATA(it_data).

DATA: o_salv TYPE REF TO cl_salv_table.

cl_salv_table=>factory( IMPORTING
                          r_salv_table = o_salv
                        CHANGING
                          t_table      = it_data ).

* PF-Status aus Programm SAPLSLVC_FULLSCREEN benutzen
o_salv->set_screen_status( pfstatus      = 'STANDARD_FULLSCREEN'
                           report        = 'SAPLSLVC_FULLSCREEN'
                           set_functions = cl_salv_model_base=>c_functions_all ).

o_salv->display( ).

oder

SELECT * FROM sflights INTO TABLE @DATA(it_data).

DATA: o_salv TYPE REF TO cl_salv_table.

cl_salv_table=>factory( IMPORTING
                          r_salv_table = o_salv
                        CHANGING
                          t_table      = it_data ).

* PF-Status manuelle aus Funktionsgruppe SALV_METADATA_STATUS kopieren
* im lokalen Programm (sy-repid) aufrufen
o_salv->set_screen_status( pfstatus      = 'SALV_TABLE_STANDARD'
                           report        = sy-repid
                           set_functions = cl_salv_model_base=>c_functions_all ).

o_salv->display( ).