[ABAP] Datensätze einer internen Tabelle mit FOR … WHERE kopieren

TYPES: ty_spfli TYPE STANDARD TABLE OF spfli WITH DEFAULT KEY.

DATA: it_spfli TYPE ty_spfli.

SELECT * FROM spfli INTO TABLE @it_spfli.

* Daten mit carrid = LH in neue iTab kopieren
* es werden nur die Daten in carrid, connid, cityfrom, cityto übertragen
DATA(it_for) = VALUE ty_spfli( FOR l IN it_spfli WHERE ( carrid = 'LH' )
                               ( carrid = l-carrid
                                 connid = l-connid
                                 cityfrom = l-cityfrom
                                 cityto = l-cityto ) ).

[ABAP] UTC-Zeit (TIMESTAMP) in Datum (d) und Uhrzeit (t) splitten

DATA: lv_date TYPE d.
DATA: lv_time TYPE t.
DATA: lv_utc TYPE timestamp.

GET TIME STAMP FIELD lv_utc.

* Zeitzohne bleibt UTC, Timestamp wird also ohne Umrechnung der Zone gesplittet
CONVERT TIME STAMP lv_utc TIME ZONE 'UTC' INTO DATE lv_date TIME lv_time.

WRITE: / |UTC: { lv_utc TIMESTAMP = USER }|.
WRITE: / |UTC-Datum: { lv_date DATE = USER }|.
WRITE: / |UTC-Zeit: { lv_time TIME = USER }|.

[ABAP] Prüfen, ob ein Verzeichnis auf dem Applikationsserver existiert / schreibbar ist

DATA: lv_dir TYPE char128 VALUE '/usr/sap'.
  
CALL FUNCTION 'PFL_CHECK_DIRECTORY'
  EXPORTING
    write_check                 = abap_true
    directory_long              = lv_dir    " darf kein TYPE string sein, sonst Exception
  EXCEPTIONS
    pfl_dir_not_exist           = 1
    pfl_permission_denied       = 2
    pfl_cant_build_dataset_name = 3
    pfl_file_not_exist          = 4
    pfl_authorization_missing   = 5
    OTHERS                      = 6.

IF sy-subrc = 0.

ENDIF.

[ABAP] XML-Dokument aufbauen / erstellen und rendern

TRY.
* Interface
    DATA(o_ixml) = cl_ixml=>create( ).

* Document
    DATA(o_doc) = o_ixml->create_document( ).

* Root definieren
    DATA(o_root) = o_doc->create_simple_element_ns( prefix = 'asx'
                                                    name = 'list'
                                                    parent = o_doc ).

* zwei Root-Element-Attribute hinzufügen
    o_root->set_attribute_ns( name =  'asx'
                              prefix = 'xmlns'
                              value = 'http://www.google.com/xml' ).

    o_root->set_attribute_ns( name =  'version'
                              value = '1.0' ).

* Node1 unterhalb Root definieren
    DATA(o_node1) = o_doc->create_simple_element_ns( prefix = 'asx'
                                                     name = 'names'
                                                     parent = o_root ).

* Node2 zur Node1 hinzufügen
    DATA(o_node2) = o_doc->create_simple_element_ns( name = 'name'
                                                     value = 'ABC'
                                                     parent = o_node1  ).

* XML-String generieren
    DATA: xml TYPE string.

    DATA(o_stream) = o_ixml->create_stream_factory( )->create_ostream_cstring( xml ).
    o_ixml->create_renderer( document = o_doc
                             ostream = o_stream )->render( ).

* Anzeige im Browser
    cl_abap_browser=>show_xml( xml_string = xml
                               title      = 'Test XML'
                               size       = cl_abap_browser=>large ).

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

[ABAP] Numerische Funktionen

DATA: x TYPE decfloat16 VALUE '-10.67'.

* Absolutwert: 10.67
WRITE: / |  abs: { abs( x ) }|.
* Vorzeichen: -1
WRITE: / | sign: { sign( x ) }|.
* nächstgrößerer ganzzahliger Wert: -10
WRITE: / | ceil: { ceil( x ) }|.
* nächstkleinerer ganzzahliger Wert: -11
WRITE: / |floor: { floor( x ) }|.
* Vorkommateil: -10
WRITE: / |trunc: { trunc( x ) }|.
* Nachkommateil: -0.67
WRITE :/ | frac: { frac( x ) }|.
* Ganzzahlige Potenzfunktion: x^n, wobei n >= 0: 113.8489
WRITE :/ | ipow: { ipow( base = x exp = 2 ) }|.
* Rundungsfunktion: -10.7
WRITE :/ |round: { round( val = x dec = 1 ) }|.
* Arcuscosinus [-1,1]
WRITE :/ | acos: { acos( '0.5' ) }|.
* Arcussinus [-1,1]
WRITE :/ | asin: { asin( '0.5' ) }|.
* Arcustangens
WRITE :/ | atan: { atan( '0.5' ) }|.
* Cosinus
WRITE :/ |  cos: { cos( '0.5' ) }|.
* Sinus
WRITE :/ |  sin: { sin( '0.5' ) }|.
* Tangens
WRITE :/ |  tan: { tan( '0.5' ) }|.
* Hyperbelcosinus
WRITE :/ | cosh: { cosh( '0.5' ) }|.
* Hyperbelsinus
WRITE :/ | sinh: { sinh( '0.5' ) }|.
* Hyperbeltangens
WRITE :/ | tanh: { tanh( '0.5' ) }|.
* Exponentialfunktion zur Basis e und x->[-709, 709] für Typ f und x->[-14144, 14149] für Typ decfloat34
WRITE :/ |  exp: { exp( x ) }|.
* natürlicher Logarithmus; x > 0
WRITE :/ |  log: { log( 2 ) }|.
* Logarithmus zur Basis 10; x > 0
WRITE :/ |log10: { log10( 2 ) }|.
* Quadratwurzel X >= 0
WRITE :/ | sqrt: { sqrt( 4 ) }|.

[ABAP] Wichtige Systemvariablen mit der ABAP Systemklasse auslesen

* Alias User
WRITE: / cl_abap_syst=>get_alias_user( ).
* Mandant
WRITE: / cl_abap_syst=>get_client( ).
* Programmname
WRITE: / cl_abap_syst=>get_current_program( ).
* Applikationsserver
WRITE: / cl_abap_syst=>get_host_name( ).
* Instanz
WRITE: / cl_abap_syst=>get_instance_name( ).
* akt. Sprachenschlüssel
WRITE: / cl_abap_syst=>get_language( ).
* Anmeldesprache
WRITE: / cl_abap_syst=>get_logon_language( ).
* Session Anmeldestatus
CASE cl_abap_syst=>get_session_authentication( ).
  WHEN cl_abap_syst=>session_authenticated_user.
    WRITE: / 'Session läuft unter Benutzerkennung (nach Anmeldung).'.
  WHEN cl_abap_syst=>session_configured_identity.
    WRITE: / 'Session läuft unter (technischer) Servicebenutzer-Kennung.'.
  WHEN cl_abap_syst=>session_system_account.
    WRITE: / 'Session läuft unter Systemkennung (keine Anmeldung erfolgt).'.
  WHEN OTHERS.
    WRITE: / 'Session läuft unter unbekanntem Kontext.'.
ENDCASE.
* Transaktionscode
WRITE: / cl_abap_syst=>get_transaction_code( ).
* User
WRITE: / cl_abap_syst=>get_user_name( ).

[ABAP] Wertebereich einer Domäne auslesen

Variante 1 (get_ddic_fixed_values)

CLASS lcl_domvalues DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS: get_by_type
      IMPORTING
                iv_data               TYPE any
      RETURNING VALUE(rt_ddfixvalues) TYPE ddfixvalues.
    CLASS-METHODS: get_by_name
      IMPORTING
                iv_name               TYPE domname
      RETURNING VALUE(rt_ddfixvalues) TYPE ddfixvalues.
ENDCLASS.

CLASS lcl_domvalues IMPLEMENTATION.

  METHOD get_by_type.
    TRY.
* liefert Typebeschreibung für DDIC-Typ
        rt_ddfixvalues = CAST cl_abap_elemdescr( cl_abap_typedescr=>describe_by_data( iv_data ) )->get_ddic_fixed_values( ).
      CATCH cx_root.
    ENDTRY.
  ENDMETHOD.

  METHOD get_by_name.
    TRY.
* liefert Typebeschreibung für DDIC-Typ
        rt_ddfixvalues = CAST cl_abap_elemdescr( cl_abap_typedescr=>describe_by_name( iv_name ) )->get_ddic_fixed_values( ).
      CATCH cx_root.
    ENDTRY.
  ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.

* Domäne über Variablen-Typ
  DATA(lv_cat) = VALUE cccategory( ).
  DATA(it_by_type) = lcl_domvalues=>get_by_type( lv_cat ).

* Domäne über Name
  DATA(it_by_name) = lcl_domvalues=>get_by_name( 'CCCATEGORY' ).

  cl_demo_output=>write_data( it_by_type ).
  cl_demo_output=>write_data( it_by_name ).

  cl_demo_output=>display( ).

Variante 2 (DD_DOMVALUES_GET)

DATA(it_dd07v_tab) = VALUE dd07v_tab( ).
DATA(lv_rc) = VALUE sy-subrc( ).

CALL FUNCTION 'DD_DOMVALUES_GET'
  EXPORTING
    domname        = 'CCCATEGORY'
    text           = abap_true
*   LANGU          = ' '
*   BYPASS_BUFFER  = ' '
  IMPORTING
    rc             = lv_rc
  TABLES
    dd07v_tab      = it_dd07v_tab
  EXCEPTIONS
    wrong_textflag = 1
    OTHERS         = 2.

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

Variante 3 (SQL)

* Name der Domäne
DATA(lv_domain) = 'CCCATEGORY'.
* Anmeldesprache
DATA(lv_lang) = cl_abap_syst=>get_logon_language( ).

SELECT l~domvalue_l, t~ddtext
  INTO TABLE @DATA(it_dom)
  FROM dd07l AS l
  INNER JOIN dd07t AS t ON l~domname = t~domname AND l~valpos = t~valpos AND l~domvalue_l = t~domvalue_l
  WHERE l~domname    = @lv_domain
    AND t~ddlanguage = @lv_lang.

cl_demo_output=>display( it_dom ).

Variante 4 (cl_reca_ddic_doma)

DATA(it_rsdomaval) = VALUE re_t_rsdomaval( ).

* DDIC-Objekt: Domäne
cl_reca_ddic_doma=>get_values( EXPORTING id_name   = 'CCCATEGORY'
                               IMPORTING et_values = it_rsdomaval ).

cl_demo_output=>display( it_rsdomaval ).

Variante 5 (cl_reca_ddic_doma)

DATA(lv_dd01v) = VALUE dd01v( ).
DATA(it_rsdomaval) = VALUE re_t_rsdomaval( ).

* DDIC-Objekt: Domäne
cl_reca_ddic_doma=>get_complete( EXPORTING id_name      = 'CCCATEGORY'
                                 IMPORTING es_header    = lv_dd01v
                                           et_rsdomaval = it_rsdomaval ).

cl_demo_output=>write_data( lv_dd01v ).
cl_demo_output=>write_data( it_rsdomaval ).
cl_demo_output=>display( ).

Links

[ABAP] Rolle eines Mandanten bestimmen

* aktueller Mandant
DATA(man) = cl_abap_syst=>get_client( ).

* verfügbare Mandanten
SELECT SINGLE *
  INTO @DATA(lv_t000)
  FROM t000
  WHERE mandt = @man.

IF sy-subrc = 0.
  DATA(it_dd07v_tab) = VALUE dd07v_tab( ).
  DATA(lv_rc) = VALUE sy-subrc( ).

* DDextern: Externe Schnittstelle zum Lesen der Domänenfestwerte
  CALL FUNCTION 'DD_DOMVALUES_GET'
    EXPORTING
      domname        = 'CCCATEGORY' " Feld CCCATEGORY: Client Control: Rolle des Mandanten (Productive, Test,...)
      text           = abap_true    " Text holen
    IMPORTING
      rc             = lv_rc
    TABLES
      dd07v_tab      = it_dd07v_tab
    EXCEPTIONS
      wrong_textflag = 1
      OTHERS         = 2.
  IF sy-subrc = 0.
    IF lv_rc = 0.
      IF line_exists( it_dd07v_tab[ domvalue_l = lv_t000-cccategory ] ).
        DATA(lv_dd07v) = it_dd07v_tab[ domvalue_l = lv_t000-cccategory ].

* logisches System, Mandant und Kategorietext ausgeben
        WRITE: / lv_t000-logsys, lv_dd07v-ddtext.
      ENDIF.
    ENDIF.
  ENDIF.
ENDIF.

[ABAP] Passwort generieren

PARAMETERS: p_length TYPE i DEFAULT 20. " Passwortlänge
PARAMETERS: p_alpha TYPE string LOWER CASE DEFAULT 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_'. " Passwortzeichensatz
  
START-OF-SELECTION.
  DATA: lv_pw TYPE string.
  DATA(r_sel) = cl_abap_random_int=>create( seed = cl_abap_random=>seed( ) min = 0 max = strlen( p_alpha ) - 1 ).

  DO p_length TIMES.
    lv_pw = |{ lv_pw }{ substring( val = p_alpha off = r_sel->get_next( ) len = 1 ) }|.
  ENDDO.

  WRITE: / 'Passwort: ', lv_pw.