AbapGit
A source-verified project description is not available yet. Open the detail page or wait for a manual refresh.
Source facts need a manual refresh
Utility Functions for ABAP Cloud & Standard ABAP
Utility Functions for ABAP Cloud & Standard ABAP
Utility Functions for ABAP Cloud & Standard ABAP
📖 Documentation — guides and full API reference
Install via abapGit - clone this repository into your SAP system.
abap-util is designed to be consumed as a vendored copy, not as an installed dependency. abapGit has no dependency management, so a hard dependency between repositories would force users to install packages in the correct order and keep versions in sync. Instead, this repository is the master catalog containing all utility classes with all methods, and each downstream project decides which classes it needs and embeds a renamed copy of exactly those (e.g. zabaputil_cl_util_context, and where needed zabaputil_cl_util_http or zabaputil_cx_error). Only the context class is additionally trimmed at method level to the methods the project actually uses; other classes are copied as-is:
| Project | Vendored Copies | Scope |
|---|---|---|
| abap2UI5 | z2ui5_cl_a2ui5_context, z2ui5_cl_a2ui5_http, z2ui5_cx_a2ui5_error (src/00/03/) | context class trimmed to the methods used by the core framework, the other two copied as-is |
| popups | z2ui5_cl_popup_context (src/00/) | methods used by the popup apps |
Not every class next to a vendored copy has a master here: z2ui5_cl_a2ui5_json_fltr in the same abap2UI5 package is framework-owned and has no counterpart in this repository. And abap2UI5's src/99/01/ (z2ui5_cl_util, z2ui5_cl_util_http, z2ui5_cx_util_error, …) holds frozen copies from before the vendoring model — they are kept for compatibility, receive no fixes, and are never a source for the sync described below.
This gives every consumer a zero-dependency installation ("clone and go") and full namespace isolation (several projects — even on different versions — can coexist in one system with their own copy), while this repository remains the place where all methods converge, are unit-tested, and are kept compatible with all ABAP releases.
How the cycle works:
DATA(lv_upper) = zabaputil_cl_util_context=>c_trim_upper( ` Hello World ` ). " => 'HELLO WORLD'
DATA(lv_lower) = zabaputil_cl_util_context=>c_trim_lower( ` Hello World ` ). " => 'hello world'
DATA(lv_trim) = zabaputil_cl_util_context=>c_trim( ` Hello World ` ). " => 'Hello World'
" Predicates
DATA(lv_has) = zabaputil_cl_util_context=>c_contains( val = `Hello World` sub = `World` ). " => abap_true
DATA(lv_pre) = zabaputil_cl_util_context=>c_starts_with( val = `Hello World` prefix = `Hello` ). " => abap_true
DATA(lv_suf) = zabaputil_cl_util_context=>c_ends_with( val = `Hello World` suffix = `World` ). " => abap_true
" Split & Join
DATA(lt_parts) = zabaputil_cl_util_context=>c_split( val = `a,b,c` sep = `,` ). " => ('a' 'b' 'c')
DATA(lv_csv) = zabaputil_cl_util_context=>c_join( tab = lt_parts sep = `;` ). " => 'a;b;c'
" Padding, truncating, replacing
DATA(lv_pad) = zabaputil_cl_util_context=>c_pad_left( val = `42` len = 5 ). " => '00042'
DATA(lv_cut) = zabaputil_cl_util_context=>c_truncate( val = `Hello World` max = 8 ). " => 'Hello...'
DATA(lv_rep) = zabaputil_cl_util_context=>c_replace_all( val = `a-b-c` sub = `-` new_val = `_` ). " => 'a_b_c'
DATA(lv_sub) = zabaputil_cl_util_context=>c_substring_safe( val = `abc` off = 1 len = 99 ). " no dump => 'bc'
DATA(lv_blank) = zabaputil_cl_util_context=>c_is_blank( ` ` ). " => abap_true
DATA(lv_ok1) = zabaputil_cl_util_context=>check_is_email( `mail@example.com` ). " => abap_true
DATA(lv_ok2) = zabaputil_cl_util_context=>check_is_numeric_string( `12.34` ). " => abap_true
DATA(lv_ok3) = zabaputil_cl_util_context=>check_is_date_valid( `2025-02-30` ). " => abap_false
DATA(lv_ok4) = zabaputil_cl_util_context=>check_is_guid( lv_uuid ).
DATA(lv_ok5) = zabaputil_cl_util_context=>check_max_length( val = lv_input max = 40 ).
" Structure to JSON
DATA(lv_json) = zabaputil_cl_util_context=>json_stringify( ls_flight ).
" => '{"CARRID":"LH","CONNID":"0400","FLDATE":"2025-01-15"}'
" JSON to Structure
zabaputil_cl_util_context=>json_parse(
val = lv_json
data = ls_flight ).
" Serialize any ABAP data to XML
DATA(lv_xml) = zabaputil_cl_util_context=>xml_stringify( ls_data ).
" Deserialize XML back to ABAP data
zabaputil_cl_util_context=>xml_parse(
xml = lv_xml
any = ls_data ).
DATA(lv_uuid_32) = zabaputil_cl_util_context=>uuid_get_c32( ). " => '550E8400E29B41D4A716446655440000'
DATA(lv_uuid_22) = zabaputil_cl_util_context=>uuid_get_c22( ). " => 'VQ6EAOKbQdSnFkRmVU'
DATA(lv_uuid_36) = zabaputil_cl_util_context=>uuid_get_c36( ). " => '550E8400-E29B-41D4-A716-446655440000'
" Convert between formats
DATA(lv_c36) = zabaputil_cl_util_context=>uuid_conv_c32_to_c36( lv_uuid_32 ).
DATA(lv_c32) = zabaputil_cl_util_context=>uuid_conv_c36_to_c32( lv_c36 ).
DATA(lv_c22) = zabaputil_cl_util_context=>uuid_conv_c32_to_c22( lv_uuid_32 ).
DATA(lv_html) = zabaputil_cl_util_context=>c_escape_html( `Tom & <b>Jerry</b>` ). " => 'Tom & <b>Jerry</b>'
DATA(lv_json) = zabaputil_cl_util_context=>c_escape_json( `say "hi"` ). " => 'say \"hi\"'
DATA(lv_enc) = zabaputil_cl_util_context=>url_encode( `a b&c=ä` ). " => 'a%20b%26c%3D%C3%A4'
DATA(lv_dec) = zabaputil_cl_util_context=>url_decode( lv_enc ). " => 'a b&c=ä'
PCRE on ABAP Cloud, POSIX on Standard ABAP - same API everywhere.
DATA(lv_match) = zabaputil_cl_util_context=>regex_match( val = `ID-4711` regex = `^ID-\d+$` ). " => abap_true
DATA(lt_nums) = zabaputil_cl_util_context=>regex_find_all( val = `a1 b22 c333` regex = `\d+` ). " => ('1' '22' '333')
DATA(lv_new) = zabaputil_cl_util_context=>regex_replace_all(
val = `a1b2`
regex = `\d`
new_val = `#` ). " => 'a#b#'
DATA(lv_hash) = zabaputil_cl_util_context=>hash_calculate( `Hello World` ). " SHA256 hex string
DATA(lv_sha1) = zabaputil_cl_util_context=>hash_calculate( val = `Hello` algorithm = `SHA1` ).
DATA(lv_hmac) = zabaputil_cl_util_context=>hash_hmac( val = `payload` key = `secret` ). " HMAC-SHA256
Unified API - cl_web_http_client on ABAP Cloud, cl_http_client on-premise.
DATA(ls_response) = zabaputil_cl_util_context=>http_get( `https://api.example.com/data` ).
" => ls_response-code = 200, ls_response-body = '...'
DATA(ls_result) = zabaputil_cl_util_context=>http_post(
url = `https://api.example.com/items`
body = lv_json
content_type = `application/json`
t_header = VALUE #( ( n = `Authorization` v = `Bearer ...` ) ) ).
DATA(lv_decimals) = zabaputil_cl_util_context=>cur_get_decimals( `JPY` ). " => 0 (TCURX / I_Currency)
" Shift internal amounts to their display value and back
DATA(lv_display) = zabaputil_cl_util_context=>cur_amount_to_external( val = lv_amount currency = `JPY` ).
DATA(lv_internal) = zabaputil_cl_util_context=>cur_amount_to_internal( val = lv_display currency = `JPY` ).
" Unit conversion (UNIT_CONVERSION_SIMPLE / I_UnitOfMeasure)
DATA(lv_meters) = zabaputil_cl_util_context=>unit_convert( val = CONV decfloat34( 2 ) unit_from = `KM` unit_to = `M` ).
DATA(lv_iso) = zabaputil_cl_util_context=>lang_sap_to_iso( `D` ). " => 'de'
DATA(lv_sap) = zabaputil_cl_util_context=>lang_iso_to_sap( `en` ). " => 'E'
" Check if a class exists
IF zabaputil_cl_util_context=>rtti_check_class_exists( 'ZCL_MY_CLASS' ) = abap_true.
" ...
ENDIF.
" Get type name of any variable
DATA(lv_type) = zabaputil_cl_util_context=>rtti_get_type_name( ls_flight ). " => 'SFLIGHT'
" Create dynamic internal table by DDIC name
DATA(lr_table) = zabaputil_cl_util_context=>rtti_create_tab_by_name( 'SFLIGHT' ).
" Get component list of a structure
DATA(lt_components) = zabaputil_cl_util_context=>rtti_get_t_attri_by_any( ls_flight ).
" Read a parameter from URL
DATA(lv_id) = zabaputil_cl_util_context=>url_param_get(
val = 'ID'
url = '/sap/bc/http/myapp?ID=12345&MODE=edit' ). " => '12345'
" Build a URL from parameters
DATA(lv_url) = zabaputil_cl_util_context=>url_param_create_url(
t_params = VALUE #(
( n = 'ID' v = '12345' )
( n = 'MODE' v = 'edit' ) ) ). " => 'ID=12345&MODE=edit'
" Add/update a parameter
DATA(lv_new_url) = zabaputil_cl_util_context=>url_param_set(
url = '/app?ID=1'
name = 'LANG'
value = 'DE' ). " => '/app?ID=1&LANG=DE'
" String <-> xstring
DATA(lv_xstring) = zabaputil_cl_util_context=>conv_get_xstring_by_string( 'Hello' ).
DATA(lv_string) = zabaputil_cl_util_context=>conv_get_string_by_xstring( lv_xstring ).
" Base64 encode/decode
DATA(lv_base64) = zabaputil_cl_util_context=>conv_encode_x_base64( lv_xstring ).
DATA(lv_decoded) = zabaputil_cl_util_context=>conv_decode_x_base64( lv_base64 ).
" Internal table to CSV
DATA(lv_csv) = zabaputil_cl_util_context=>itab_get_csv_by_itab( lt_flights ).
" CSV to internal table (returns data reference)
DATA(lr_itab) = zabaputil_cl_util_context=>itab_get_itab_by_csv( lv_csv ).
" Internal table to Excel
DATA(lv_xlsx) = zabaputil_cl_util_context=>conv_get_xlsx_by_itab( lt_flights ).
" Excel to internal table
zabaputil_cl_util_context=>conv_get_itab_by_xlsx(
EXPORTING val = lv_xlsx
IMPORTING result = lr_data ).
" Move corresponding rows between tables of different row types
zabaputil_cl_util_context=>itab_corresponding(
EXPORTING val = lt_source
CHANGING tab = lt_target ).
" Filter table in place by a substring across all clike fields
zabaputil_cl_util_context=>itab_filter_by_val(
EXPORTING val = `LH`
CHANGING tab = lt_flights ).
" Project a flat structure to a list of name/value pairs
DATA(lt_kv) = zabaputil_cl_util_context=>itab_get_by_struc( ls_flight ).
" => [ ( name = 'CARRID' value = 'LH' ) ( name = 'CONNID' value = '0400' ) ... ]
" Sort, slice & paginate dynamically
zabaputil_cl_util_context=>itab_sort_by(
EXPORTING fieldname = `PRICE` descending = abap_true
CHANGING tab = lt_flights ).
DATA(lr_top10) = zabaputil_cl_util_context=>itab_slice( tab = lt_flights from = 1 to = 10 ).
zabaputil_cl_util_context=>itab_paginate(
EXPORTING tab = lt_flights page = 2 page_size = 20
IMPORTING result = lr_page
total_count = lv_count
total_pages = lv_pages ).
" Count rows grouped by a field
DATA(lt_counts) = zabaputil_cl_util_context=>itab_count_by( tab = lt_flights fieldname = `CARRID` ).
" => [ ( n = 'LH' v = '42' ) ( n = 'AA' v = '17' ) ... ]
" Aggregations
To keep this page readable, only the first part of the README is shown. Open the original README for the full document.