
ABAP Cloud - System Fields (SYST)
There are currently several alternatives for accessing SYST fields in ABAP Cloud. In this article, we'll look at the alternative and obsolete variants.
Table of contents
In this article, we compare the various relevant fields of the SY and SYST structures and present alternatives in the ABAP Cloud world. We examine various aspects of their use.
Introduction
In the classic world, the SY system variable contains approximately 170 different fields with different information that are always kept up-to-date at runtime. This includes information such as the current date in the system, the current user, or the last message. Given the number of fields, much of the information is no longer relevant or has been deprecated by SAP. In addition, many fields refer to reports and list outputs that are no longer supported in ABAP Cloud.
Technical Fields
In this chapter, we look at technical fields that you repeatedly use in processing and logic for which there are currently no alternatives.
Processing
- INDEX - Current index in a DO.
- TABIX - Current table index in a LOOP.
- DBCNT - Number of records that were changed during the last database operation.
- SUBRC - Status of the last action, for example, when checking authorizations, whether a LOOP contained records, or whether the SELECT of the data was successful. 0 (zero) is the successful case.
- ABCDE - Static variable that contains the Latin alphabet in UPPER.
Information
- MANDT - Current client of the system, consists of three digits, whereby certain clients are reserved for SAP (e.g., 000).
- DBSYS - Current database system of the system. In modern systems, HDB should be displayed here.
- SYSID - ID of the system, this is an abbreviation consisting of three letters or numbers.
- OPSYS - Operating system on which the system was installed, for example, Linux.
- SAPRL - Information about the current ABAP release. For example, an S/4HANA On-Prem 2023 system has release 758, while the current ABAP environment is 917.
Content Fields
In this chapter, we will look at the fields in detail and compare them to the SY field, the context class, and the XCO library.
User
Being able to access the current user ID is particularly necessary in the logging and reconciliation environment. In the modern cloud environment, the business partner is usually located in this field.
DATA(syst) = sy-uname.
DATA(context) = cl_abap_context_info=>get_user_technical_name( ).
DATA(xco) = xco_cp=>sy->user( )->name.
User Alias
If you're in a modern environment and not on-premises, you might also want to derive the real user ID for the currently logged-in user. Currently, only the Context class is available for this.
DATA(syst) = '-'.
DATA(context) = cl_abap_context_info=>get_user_alias( ).
DATA(xco) = '-'.
System Date/Time
The current system date is usually stored in UTC. For the XCO library, we map it to a date, since the value is returned as a string.
DATA(syst) = sy-datum.
DATA(context) = cl_abap_context_info=>get_system_date( ).
DATA(xco) = CONV d( xco_cp=>sy->date( xco_cp_time=>time_zone->utc )->as( xco_cp_time=>format->abap )->value ).
If you want to have the current time for the system, you can find the information this way.
DATA(syst) = sy-uzeit.
DATA(context) = cl_abap_context_info=>get_system_time( ).
DATA(xco) = CONV t( xco_cp=>sy->time( xco_cp_time=>time_zone->utc )->as( xco_cp_time=>format->abap )->value ).
Local Date/Time
The local time describes the current time of the logged-in user. This setting is different for each user, depending on their settings. The Context class doesn't offer an alternative here, but in principle it could be calculated using the time zone and system data.
DATA(syst) = sy-datlo.
DATA(context) = '-'.
DATA(xco) = CONV d( xco_cp=>sy->date( xco_cp_time=>time_zone->user )->as( xco_cp_time=>format->abap )->value ).
The time is derived similarly to the local date; there is no alternative in the context object.
DATA(syst) = sy-timlo.
DATA(context) = '-'.
DATA(xco) = CONV t( xco_cp=>sy->time( xco_cp_time=>time_zone->user )->as( xco_cp_time=>format->abap )->value ).
A third important property in this context is the user's time zone. This allows you to derive further calculations and details.
DATA(syst) = sy-zonlo.
DATA(context) = cl_abap_context_info=>get_user_time_zone( ).
DATA(xco) = xco_cp_time=>time_zone->user->value.
Language
The current language of the registration is important when it comes to texts and translations in the system. However, the SAP format is single-digit, so capitalization is important for deriving the language and is no longer so easy to understand. This has historical reasons.
DATA(syst) = sy-langu.
DATA(context) = cl_abap_context_info=>get_user_language_abap_format( ).
DATA(xco) = xco_cp=>sy->language( )->value.
If you want the general ISO code for the language, there is already an alternative in the new frameworks.
SELECT SINGLE FROM I_Language
FIELDS LanguageISOCode
WHERE Language = @sy-langu
INTO @DATA(syst).
DATA(context) = cl_abap_context_info=>get_user_language_iso_format( ).
DATA(xco) = xco_cp=>sy->language( )->as( xco_cp_language=>format->iso_639 ).
Messages
If a message is generated in the system, the corresponding variables in the SYST are filled. However, since there are seven variables involved, handling can be somewhat cumbersome in some cases.
DATA(syst) = VALUE symsg( msgid = sy-msgid
msgno = sy-msgno
msgty = sy-msgty
msgv1 = sy-msgv1
msgv2 = sy-msgv2
msgv3 = sy-msgv3
msgv4 = sy-msgv4 ).
DATA(context) = '-'.
DATA(xco) = xco_cp=>sy->message( )->value.
Usage
Why do we actually want to move away from system fields? The reason is relatively simple: many of the fields no longer comply with the current SAP standard with their German names. Therefore, the fields were set to obsolete in ABAP Cloud. At the beginning of the ABAP environment, the fields were even completely prohibited, but due to the effort involved in the migration, they were allowed again, albeit with a warning.
Fundamentally, the fields cannot be cleanly decoupled when it comes to unit tests. We access the information directly, which is essentially equivalent to a DOC (Dependend-On Component).
Complete Example
You can find the complete example from today's article as an executable class in this section. If you want to recreate the examples, you can copy the class to your system.
CLASS zcl_bs_demo_system_compare DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
PRIVATE SECTION.
METHODS compare_user
IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.
METHODS compare_system_date
IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.
METHODS compare_system_time
IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.
METHODS compare_local_date
IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.
METHODS compare_local_time
IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.
METHODS compare_time_zone
IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.
METHODS compare_client
IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.
METHODS compare_language
IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.
METHODS compare_language_iso
IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.
METHODS compare_system_id
IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.
METHODS compare_user_alias
IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.
METHODS compare_message
IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.
ENDCLASS.
CLASS zcl_bs_demo_system_compare IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
compare_user( out ).
compare_user_alias( out ).
compare_system_date( out ).
compare_system_time( out ).
compare_local_date( out ).
compare_local_time( out ).
compare_time_zone( out ).
compare_language( out ).
compare_language_iso( out ).
compare_client( out ).
compare_system_id( out ).
compare_message( out ).
ENDMETHOD.
METHOD compare_user.
DATA(syst) = sy-uname.
DATA(context) = cl_abap_context_info=>get_user_technical_name( ).
DATA(xco) = xco_cp=>sy->user( )->name.
out->write( syst ).
out->write( context ).
out->write( xco ).
ENDMETHOD.
METHOD compare_user_alias.
DATA(syst) = '-'.
DATA(context) = cl_abap_context_info=>get_user_alias( ).
DATA(xco) = '-'.
out->write( syst ).
out->write( context ).
out->write( xco ).
ENDMETHOD.
METHOD compare_system_date.
DATA(syst) = sy-datum.
DATA(context) = cl_abap_context_info=>get_system_date( ).
DATA(xco) = CONV d( xco_cp=>sy->date( xco_cp_time=>time_zone->utc )->as( xco_cp_time=>format->abap )->value ).
out->write( syst ).
out->write( context ).
out->write( xco ).
ENDMETHOD.
METHOD compare_system_time.
DATA(syst) = sy-uzeit.
DATA(context) = cl_abap_context_info=>get_system_time( ).
DATA(xco) = CONV t( xco_cp=>sy->time( xco_cp_time=>time_zone->utc )->as( xco_cp_time=>format->abap )->value ).
out->write( syst ).
out->write( context ).
out->write( xco ).
ENDMETHOD.
METHOD compare_local_date.
DATA(syst) = sy-datlo.
DATA(context) = '-'.
DATA(xco) = CONV d( xco_cp=>sy->date( xco_cp_time=>time_zone->user )->as( xco_cp_time=>format->abap )->value ).
out->write( syst ).
out->write( context ).
out->write( xco ).
ENDMETHOD.
METHOD compare_local_time.
DATA(syst) = sy-timlo.
DATA(context) = '-'.
DATA(xco) = CONV t( xco_cp=>sy->time( xco_cp_time=>time_zone->user )->as( xco_cp_time=>format->abap )->value ).
out->write( syst ).
out->write( context ).
out->write( xco ).
ENDMETHOD.
METHOD compare_time_zone.
DATA(syst) = sy-zonlo.
DATA(context) = cl_abap_context_info=>get_user_time_zone( ).
DATA(xco) = xco_cp_time=>time_zone->user->value.
out->write( syst ).
out->write( context ).
out->write( xco ).
ENDMETHOD.
METHOD compare_language.
DATA(syst) = sy-langu.
DATA(context) = cl_abap_context_info=>get_user_language_abap_format( ).
DATA(xco) = xco_cp=>sy->language( )->value.
out->write( syst ).
out->write( context ).
out->write( xco ).
ENDMETHOD.
METHOD compare_language_iso.
SELECT SINGLE FROM I_Language
FIELDS LanguageISOCode
WHERE Language = @sy-langu
INTO @DATA(syst).
DATA(context) = cl_abap_context_info=>get_user_language_iso_format( ).
DATA(xco) = xco_cp=>sy->language( )->as( xco_cp_language=>format->iso_639 ).
out->write( syst ).
out->write( context ).
out->write( xco ).
ENDMETHOD.
METHOD compare_client.
DATA(syst) = sy-mandt.
DATA(context) = '-'.
DATA(xco) = '-'.
out->write( syst ).
out->write( context ).
out->write( xco ).
ENDMETHOD.
METHOD compare_system_id.
DATA(syst) = sy-sysid.
DATA(context) = '-'.
DATA(xco) = '-'.
out->write( syst ).
out->write( context ).
out->write( xco ).
ENDMETHOD.
METHOD compare_message.
DATA(syst) = VALUE symsg( msgid = sy-msgid
msgno = sy-msgno
msgty = sy-msgty
msgv1 = sy-msgv1
msgv2 = sy-msgv2
msgv3 = sy-msgv3
msgv4 = sy-msgv4 ).
DATA(context) = '-'.
DATA(xco) = xco_cp=>sy->message( )->value.
out->write( syst ).
out->write( context ).
out->write( xco ).
ENDMETHOD.
ENDCLASS.
If you run the class, you should get a similar result, with three lines always forming a method. Therefore, you shouldn't worry about the formatting.
Conclusion
Currently, there is no single alternative if you want to access all system fields. However, you should now have a rough overview of which fields are still relevant and what you can use them for.
Further information:
SAP Help - ABAP System Fields
SAP Help - Obsolete Fields