[ABAP] Auswahl eines Transportauftrags (mit Anlegen)

* Tabellen:
*  E070 (Transportsystem: Header von Aufträgen/Aufgaben)
*  E07T (Transportsystem: Kurzbeschreibungen von Aufträgen/Aufgaben)
*  E070C (Transportsystem: Quell-/Zielmandant von Aufträgen/Aufgaben)
*  E071 (Transportsystem: Objekt-Einträge von Aufträgen/Aufgaben)
*  TADIR (Katalog der Repository-Objekte)
*  TPLOG (Logging der tp Aufrufe)

* https://www.berater-wiki.de/Transportauftrag
* https://www.berater-wiki.de/Access_Tabellenbeziehung_Transportauftrag/-Aufgabe
* http://sapyourself.com/2014/06/11/transporte-transporteur-ermitteln-und-analysieren-tabelle-tplog/

* TRFUNCTION
*  K  Workbench-Auftrag
*  W  Customizing-Auftrag
*  C  Umzug von Objekten ohne Paketwechsel
*  O  Umzug von Objekten mit Paketwechsel
*  E  Umzug eines kompletten Pakets
*  T  Transport von Kopien
*  S  Entwicklung/Korrektur
*  R  Reparatur
*  X  Unklassifizierte Aufgabe
*  Q  Customizing-Aufgabe
*  G  Stückliste für CTS-Projekt
*  M  Auftrag für Mandantentransport
*  P  Stückliste für Upgrade
*  D  Stückliste für Patch
*  F  Stückliste
*  L  Löschtransport
* TRSTATUS
*  D  Änderbar
*  L  Änderbar, geschützt
*  O  Freigabe gestartet
*  R  Freigegeben
*  N  Freigegeben (Importschutz für reparierte Objekte aktiv)
* KORRDEV
*  CUST  mandantenabhängiges Customizing
*  SYST  Repository, mandantenunabbhängige Objekte
* LOCKFLAG
*     nicht gesperrt
*  X  gesperrt
*  0  nicht importiert
*  1  importiert mit Fehler
*  2  erfolgreich importiert
*  3  erfolgreich aktiviert /After-Import-Methode ausgeführt
*  6  erfolgreich in Schattentabellen importiert
*  7  erfolgreich in neue Schattentabellen importiert
*  8  inaktiver Anteil erfolgreich importiert

* Auftragstyp
SELECTION-SCREEN BEGIN OF LINE.
  SELECTION-SCREEN COMMENT (14) lbl1 FOR FIELD p_tfunc.
  PARAMETERS: p_tfunc TYPE trfunction.
SELECTION-SCREEN END OF LINE.

INITIALIZATION.
  lbl1 = 'Auftragstyp:'.

START-OF-SELECTION.

  DATA: lv_req TYPE trwbo_request_header.

* Auswahl eines Transportauftrags (mit Anlegen)
  CALL FUNCTION 'TR_REQUEST_CHOICE'
    EXPORTING
      iv_request_types     = p_tfunc
    IMPORTING
      es_request           = lv_req
    EXCEPTIONS
      invalid_request      = 1
      invalid_request_type = 2
      user_not_owner       = 3
      no_objects_appended  = 4
      enqueue_error        = 5
      cancelled_by_user    = 6
      recursive_call       = 7
      OTHERS               = 8.

  IF sy-subrc = 0.
    cl_demo_output=>write_data( lv_req ).
    cl_demo_output=>display( ).
  ENDIF.

[ABAP] Verschieben von Nodes per Drag & Drop innerhalb einer Baumansicht (CL_COLUMN_TREE_MODEL)

* globale Objektreferenz für Tree-Objekt
DATA: o_tree TYPE REF TO cl_column_tree_model.

* Übergabeobjekt für Drag-Drop-Events
CLASS lcl_dd_object DEFINITION.
  PUBLIC SECTION.
    METHODS: constructor
      IMPORTING
        i_drag_node_text TYPE tm_nodekey.

    METHODS: get_value
      RETURNING VALUE(rv_ret) TYPE tm_nodekey.

  PRIVATE SECTION.
    DATA: gv_drag_node_text TYPE tm_nodekey.
ENDCLASS.

CLASS lcl_dd_object IMPLEMENTATION.
  METHOD constructor.
    gv_drag_node_text = i_drag_node_text.
  ENDMETHOD.

  METHOD get_value.
    rv_ret = gv_drag_node_text.
  ENDMETHOD.
ENDCLASS.

* Demoprogramm: SAPSIMPLE_TREE_DRAG_DROP_DEMO
* http://saphelp.ucc.ovgu.de/NW750/EN/4d/88f020981740abe10000000a15822b/frameset.htm
* Eventhandler-Klasse
CLASS lcl_events DEFINITION.
  PUBLIC SECTION.

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

    CLASS-METHODS: on_drag FOR EVENT drag OF cl_column_tree_model
      IMPORTING
        node_key
        item_name
        drag_drop_object
        sender.

    CLASS-METHODS: on_drop FOR EVENT drop OF cl_column_tree_model
      IMPORTING
        node_key
        drag_drop_object
        sender.

    CLASS-METHODS: on_drop_complete FOR EVENT drop_complete OF cl_column_tree_model
      IMPORTING
        node_key
        item_name
        drag_drop_object
        sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
* Quell-Node
  METHOD on_drag.

* Übergabe Name der Quell-Node
    drag_drop_object->object = NEW lcl_dd_object( node_key ).

  ENDMETHOD.

* Ziel-Node
  METHOD on_drop.
    TRY.
* Holen Name der Quell-Node
        DATA(o_dd_obj) = CAST lcl_dd_object( drag_drop_object->object ).

        IF o_tree IS BOUND.
* Quell-Node an Ziel-Node umhängen
          o_tree->move_node(
                              node_key          = o_dd_obj->get_value( )
                              relative_node_key = node_key
                              relationship      = cl_tree_model=>relat_last_child
                           ).
        ENDIF.
      CATCH cx_root.
* Abbruch bei Cast-Fehler
        drag_drop_object->abort( ).
    ENDTRY.
  ENDMETHOD.

  METHOD on_drop_complete.

  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
* Tree-Control erzeugen
* item_selection = abap_true wegen der CheckBoxen
  o_tree = NEW cl_column_tree_model( node_selection_mode   = cl_column_tree_model=>node_sel_mode_single
                                     hierarchy_column_name = 'FOLDER'
                                     hierarchy_header      = VALUE #( t_image = icon_folder
                                                                      heading = 'Beispiel'
                                                                      tooltip = 'Tooltip'
                                                                      width   = 30
                                                                    )
                                     item_selection        = abap_true
                                   ).
* Spalten hinzufügen
  o_tree->add_column( EXPORTING
                        name                = 'COL1'
                        width               = 30
                        header_text         = 'Column1' ).

  o_tree->add_column( EXPORTING
                        name                = 'COL2'
                        width               = 30
                        header_text         = 'Column2' ).

* in default_screen einbetten
  o_tree->create_tree_control( parent = cl_gui_container=>default_screen ).

* Drag-Drop-Verhalten definieren
  DATA(o_behaviour) = NEW cl_dragdrop( ).

  o_behaviour->add( EXPORTING
                      flavor = 'Filestest'
                      dragsrc = abap_true
                      droptarget = abap_true
                      effect = CONV i( cl_dragdrop=>move + cl_dragdrop=>copy )
                  ).

  DATA: lv_handle_dd TYPE i.

  o_behaviour->get_handle( IMPORTING handle = lv_handle_dd ).

* Beispielhaft Nodes und Subnodes erzeugen
  o_tree->add_node( EXPORTING
                      isfolder          = abap_true
                      node_key          = 'NODE1'
                      relative_node_key = ''
                      relationship      = cl_tree_model=>relat_last_child
                      expanded_image    = CONV tv_image( icon_folder )
                      image             = CONV tv_image( icon_folder )
                      item_table        = VALUE #( ( class     = cl_column_tree_model=>item_class_checkbox
                                                     item_name = 'FOLDER'
                                                     text      = 'Obj1'
                                                     editable  = abap_true
                                                   )
                                                 )

                      drag_drop_id      = lv_handle_dd
                  ).

  o_tree->add_node( EXPORTING
                      isfolder          = abap_true
                      node_key          = 'NODE1_1'
                      relative_node_key = 'NODE1'
                      relationship      = cl_tree_model=>relat_last_child
                      expanded_image    = CONV tv_image( icon_oo_object )
                      image             = CONV tv_image( icon_oo_object )
                      item_table        = VALUE #( ( class     = cl_column_tree_model=>item_class_link
                                                     item_name = 'FOLDER'
                                                     text      = 'Obj4'
                                                   )
                                                   ( class     = cl_column_tree_model=>item_class_text
                                                     item_name = 'COL1'
                                                     text      = 'Wert1'
                                                     style     = cl_column_tree_model=>style_intensified
                                                     font      = cl_column_tree_model=>item_font_prop
                                                   )
                                                   ( class     = cl_column_tree_model=>item_class_text
                                                     item_name = 'COL2'
                                                     text      = 'Wert2'
                                                   )
                                                 )

                      drag_drop_id      = lv_handle_dd
                  ).

  o_tree->add_node( EXPORTING
                      isfolder          = abap_true
                      node_key          = 'NODE2'
                      relative_node_key = ''
                      relationship      = cl_tree_model=>relat_last_child
                      expanded_image    = CONV tv_image( icon_folder )
                      image             = CONV tv_image( icon_folder )
                      item_table        = VALUE #( ( class     = cl_column_tree_model=>item_class_checkbox
                                                     item_name = 'FOLDER'
                                                     text      = 'Obj2'
                                                     editable  = abap_true
                                                   )
                                                 )

                      drag_drop_id      = lv_handle_dd
                  ).

  o_tree->add_node( EXPORTING
                      isfolder          = abap_true
                      node_key          = 'NODE2_1'
                      relative_node_key = 'NODE2'
                      relationship      = cl_tree_model=>relat_last_child
                      expanded_image    = CONV tv_image( icon_oo_object )
                      image             = CONV tv_image( icon_oo_object )
                      item_table        = VALUE #( ( class     = cl_column_tree_model=>item_class_button
                                                     item_name = 'FOLDER'
                                                     text      = 'Obj3'
                                                   )
                                                   ( class     = cl_column_tree_model=>item_class_text
                                                     item_name = 'COL1'
                                                     text      = 'Wert1'
                                                     style     = cl_column_tree_model=>style_inactive
                                                     font      = cl_column_tree_model=>item_font_prop
                                                   )
                                                   ( class     = cl_column_tree_model=>item_class_text
                                                     item_name = 'COL2'
                                                     text      = 'Wert2'
                                                   )
                                                 )

                      drag_drop_id      = lv_handle_dd
                  ).

* Nodes expandieren
  o_tree->expand_root_nodes( expand_subtree = abap_true
                             level_count = 10 ).

* Events registrieren
* ITEM_DOUBLE_CLICK            Doppelklick auf Item
* BUTTON_CLICK                 Drucktaste wurde gedrückt
* LINK_CLICK                   Link geklickt
* CHECKBOX_CHANGE              Zustandsänderung einer Checkbox
* ITEM_KEYPRESS                Taste wurde gedrückt, Item war selektiert
* HEADER_CLICK                 Header geklickt
* ITEM_CONTEXT_MENU_REQUEST    Anforderung eines Kontext-Menüs für ein Item
* ITEM_CONTEXT_MENU_SELECT     Kontext-Menü Eintrag wurde ausgewählt
* HEADER_CONTEXT_MENU_REQUEST  Anforderung eines Kontext-Menüs für einen Header
* HEADER_CONTEXT_MENU_SELECT   Kontext-Menü Eintrag wurde ausgewählt
* DRAG                         Ereignis zum Füllen des Drag Drop Daten - Objekts
* DRAG_MULTIPLE                Ereignis zum Füllen des Drag Drop Daten - Objekts
* DROP_COMPLETE                Ereignis nach erfolgreichem Drop
* DROP_COMPLETE_MULTIPLE       Ereignis nach erfolgreichem Drop
  SET HANDLER lcl_events=>on_drag FOR o_tree.
  SET HANDLER lcl_events=>on_drop FOR o_tree.
  SET HANDLER lcl_events=>on_drop_complete FOR o_tree.

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

[ABAP] Versand von Emails auf Basis von CDS-Views

https://weberpatrick.de/e-mail-templates/
https://weberpatrick.de/e-mail-templates-einfaches-beispiel/

https://blogs.sap.com/2019/10/12/e-mail-templates-in-s4-hana/
https://blogs.sap.com/2020/05/07/e-mail-templates-in-s-4-hana-translations/
https://blogs.sap.com/2022/08/17/e-mail-templates-in-s-4-hana-display-table-in-the-email-template/

[ABAP] ABAP-Listausgabe in interne ASCII-Tabelle ausgeben

DATA(i) = 0.

WHILE i < 10.

  WRITE: / i.
  i = i + 1.

ENDWHILE.

DATA: it_abaplist TYPE STANDARD TABLE OF abaplist WITH DEFAULT KEY.

* Sichern einer Liste
CALL FUNCTION 'SAVE_LIST'
  TABLES
    listobject         = it_abaplist
  EXCEPTIONS
    list_index_invalid = 1
    OTHERS             = 2.

IF sy-subrc = 0.

  DATA: it_list_ascii TYPE list_string_table.

* Konvertieren eines (gesicherten) Listobjekts nach ASCI
  CALL FUNCTION 'LIST_TO_ASCI'
    IMPORTING
      list_string_ascii  = it_list_ascii
    TABLES
      listobject         = it_abaplist
    EXCEPTIONS
      empty_list         = 1
      list_index_invalid = 2
      OTHERS             = 3.

  IF sy-subrc = 0.
    cl_demo_output=>display( it_list_ascii ).
  ENDIF.
ENDIF.

[ABAP] ABAP-Listausgabe in HTML wandeln

**********************************************************************
* Testausgabe
**********************************************************************
* Farbe definieren
FORMAT COLOR COL_HEADING.
* Überschriftentext
WRITE: / |Testausgabe|.
* Leerzeichen am Zeilenende, damit der Farbbalken durchgezogen wird
WRITE AT sy-linsz space.
* Farbdefinition abschalten
FORMAT COLOR OFF.

WRITE: / 'Grün' COLOR COL_POSITIVE.
WRITE: / 'Rot' COLOR COL_NEGATIVE.

ULINE.

**********************************************************************
* Aufbereitung der Listausgabe für HTML
**********************************************************************
DATA: it_list TYPE STANDARD TABLE OF abaplist WITH DEFAULT KEY.

* Listausgabe in Form einer binären internen Tabelle speichern
* Sichern einer Liste
CALL FUNCTION 'SAVE_LIST'
  TABLES
    listobject         = it_list
  EXCEPTIONS
    list_index_invalid = 1
    OTHERS             = 2.

DATA: it_html TYPE STANDARD TABLE OF w3html.

* Listausgabe -> HTML
* Converts a given listobject to html
CALL FUNCTION 'WWW_HTML_FROM_LISTOBJECT'
  TABLES
    html          = it_html
    listobject    = it_list.

* HTML-Viewer
DATA(o_hv) = NEW cl_gui_html_viewer( parent = cl_gui_container=>default_screen ).
* URL holen
DATA: lv_url TYPE swk_url.

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

* HTML-Daten anzeigen
o_hv->show_url( url      = lv_url
                in_place = abap_false ).

* cl_gui_container=>default_screen erzwingen
WRITE: space.

[ABAP] Verarbeitungsprotokoll zu Nachrichten lesen (NAST, CMFK, CMFP)

* https://www.berater-wiki.de/Access_Tabellenbeziehung_Fehlerprotokoll

DATA: lv_kappl TYPE nast-kappl.
DATA: lv_objky TYPE nast-objky.
DATA: lv_kschl TYPE nast-kschl.
DATA: lv_erdat TYPE nast-erdat.
DATA: lv_eruhr TYPE nast-eruhr.
DATA: lv_usnam TYPE nast-usnam.

SELECT-OPTIONS: so_kappl FOR lv_kappl.
SELECT-OPTIONS: so_objky FOR lv_objky.
SELECT-OPTIONS: so_kschl FOR lv_kschl.
SELECT-OPTIONS: so_erdat FOR lv_erdat.
SELECT-OPTIONS: so_eruhr FOR lv_eruhr.
SELECT-OPTIONS: so_usnam FOR lv_usnam.

INITIALIZATION.

* Applikation für Nachrichtenkonditionen ('EF' = Bestellungen)
  so_kappl[] = VALUE #( ( sign = 'I' option = 'EQ' low = 'EF' high = '' ) ).
* Nachrichtenart
  so_kschl[] = VALUE #( ( sign = 'I' option = 'EQ' low = 'NEU' high = '' ) ).

START-OF-SELECTION.

* NAST (Nachrichtenstatus)
* CMFK (Speicherstruktur für den Kopf des Fehlerprotokolls)
* CMFP (Speicherstruktur für die gesammelten Fehler)
  SELECT FROM nast AS na
         LEFT OUTER JOIN cmfk AS ck ON na~cmfpnr = ck~nr
         LEFT OUTER JOIN cmfp AS cp ON na~cmfpnr = cp~nr
         FIELDS na~kappl,
                na~objky,
                na~kschl,
                na~parnr,
                na~erdat,
                na~eruhr,
                na~nacha,
                na~vsztp,
                na~usnam,
                na~tcode,
                na~ldest,
                na~tdreceiver,
                na~tdcovtitle,
                na~tdarmod,
                na~objtype,
                na~cmfpnr,
                ck~aplid,
                ck~nr,
                ck~datum,
                ck~uzeit,
                ck~uname,
                ck~objid,
                cp~msgcnt,
                cp~arbgb,
                cp~msgty,
                cp~msgnr,
                cp~msgv1,
                cp~msgv2,
                cp~msgv3,
                cp~msgv4,
                cp~logsys
         WHERE na~kappl IN @so_kappl
           AND na~objky IN @so_objky
           AND na~kschl IN @so_kschl
           AND na~erdat IN @so_erdat
           AND na~eruhr IN @so_eruhr
           AND na~usnam IN @so_usnam
         INTO TABLE @DATA(it_nast).

  IF sy-subrc = 0.
    cl_demo_output=>write_data( it_nast ).
* HTML-Code vom Demo-Output holen
    DATA(lv_html) = cl_demo_output=>get( ).
* Daten im Inline-Browser im SAP-Fenster anzeigen
    cl_abap_browser=>show_html( EXPORTING
                                  title        = 'Verarbeitungsprotokoll Nachrichten'
                                  html_string  = lv_html
                                  container    = cl_gui_container=>default_screen ).

* cl_gui_container=>default_screen erzwingen
    WRITE: space.
  ENDIF.

[ABAP] Leistungstammsatz anlegen

DATA: lv_service  TYPE bapisrv_asmd.
DATA: lv_servicex TYPE bapisrv_asmdx.
DATA: it_bapiret2 TYPE STANDARD TABLE OF bapiret2 WITH DEFAULT KEY.

lv_service-service           = '1234567890'. " Leistungsnummer
lv_service-matl_group        = '10000000'.   " Warengruppe
lv_service-base_uom          = 'ST'.         " Basismengeneinheit
lv_service-serv_cat          = 'SERV'.       " Leistungstyp
lv_service-val_class         = '1000'.       " Bewertungsklasse
lv_service-master_langu      = sy-langu.     " Sprache
lv_service-master_langu_iso  = cl_i18n_languages=>sap1_to_sap2( im_lang_sap1 = lv_service-master_langu ).

lv_servicex-service          = lv_service-service.
lv_servicex-matl_group       = abap_true.
lv_servicex-base_uom         = abap_true.
lv_servicex-serv_cat         = abap_true.
lv_servicex-val_class        = abap_true.
lv_servicex-master_langu     = abap_true.
lv_servicex-master_langu_iso = abap_true.

DATA it_shorttext TYPE STANDARD TABLE OF bapisrv_asmdt WITH DEFAULT KEY.

it_shorttext = VALUE #( ( language     = lv_service-master_langu
                          language_iso = lv_service-master_langu_iso
                          short_text   = 'Kurztext'
                          change_id    = 'I' ) ).

DATA(it_longtext) = VALUE srv_sm_text_tty( ( language     = sy-langu
                                             language_iso = cl_i18n_languages=>sap1_to_sap2( im_lang_sap1 = sy-langu )
                                             format       = '/'
                                             line         = 'Langtext'
                                             change_id    = 'I' ) ).

CALL FUNCTION 'BAPI_SERVICE_CREATE'
  EXPORTING
    im_service_data     = lv_service
    im_service_datax    = lv_servicex
    testrun             = ''
  TABLES
    return              = it_bapiret2
    service_description = it_shorttext
    service_long_texts  = it_longtext.

TRY.
    IF lines( it_bapiret2 ) > 0.
      IF it_bapiret2[ 1 ]-type CA 'EAX'.
        CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
      ELSE.
        CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'.
      ENDIF.
    ENDIF.
  CATCH cx_sy_itab_line_not_found.
    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
ENDTRY.

cl_demo_output=>write_data( lv_service ).
cl_demo_output=>write_data( lv_servicex ).
cl_demo_output=>write_data( it_shorttext ).
cl_demo_output=>write_data( it_longtext ).
cl_demo_output=>write_data( it_bapiret2 ).

* HTML-Code vom Demo-Output holen
DATA(lv_html) = cl_demo_output=>get( ).

* Daten im Inline-Browser im SAP-Fenster anzeigen
cl_abap_browser=>show_html( EXPORTING
                              title        = 'Leistungsstammsatz'
                              html_string  = lv_html
                              container    = cl_gui_container=>default_screen ).

* cl_gui_container=>default_screen erzwingen
WRITE: space.

[ABAP] Leistungstammsatz lesen

PARAMETERS: p_srv_nr TYPE asmd-asnum. "bapisrvpar-service.

START-OF-SELECTION.
  DATA: lv_service_info TYPE bapisrv.
  DATA: it_servicetextlines TYPE STANDARD TABLE OF bapisrvtxt WITH DEFAULT KEY.
  DATA: it_bapiret2 TYPE STANDARD TABLE OF bapiret2 WITH DEFAULT KEY.

  CALL FUNCTION 'BAPI_SERVICE_GET_DETAIL'
    EXPORTING
      servicenumber      = p_srv_nr
    IMPORTING
      servicegeneraldata = lv_service_info
    TABLES
      servicetextlines   = it_servicetextlines
      return             = it_bapiret2.

  cl_demo_output=>write_data( p_srv_nr ).
  cl_demo_output=>write_data( lv_service_info ).
  cl_demo_output=>write_data( it_servicetextlines ).
  cl_demo_output=>write_data( it_bapiret2 ).

* HTML-Code vom Demo-Output holen
  DATA(lv_html) = cl_demo_output=>get( ).

* Daten im Inline-Browser im SAP-Fenster anzeigen
  cl_abap_browser=>show_html( EXPORTING
                                title        = 'Leistungsstammsatz'
                                html_string  = lv_html
                                container    = cl_gui_container=>default_screen ).

* cl_gui_container=>default_screen erzwingen
  WRITE: space.