ABAP ofrece numerosas funciones integradas para operaciones frecuentes. Estas funciones pueden usarse inline en expresiones y hacen el código más compacto y legible.
Operaciones con tablas
line_exists() – Verificar si existe una línea
DATA: lt_names TYPE TABLE OF string.
lt_names = VALUE #( ( `Anna` ) ( `Bernd` ) ( `Clara` ) ).
" Verificar si existe la línea (sin excepción)IF line_exists( lt_names[ 2 ] ). WRITE: / 'La línea 2 existe'.ENDIF.
" Con claveDATA: lt_customers TYPE SORTED TABLE OF ty_customer WITH UNIQUE KEY id.
IF line_exists( lt_customers[ id = 1001 ] ). WRITE: / 'Cliente 1001 encontrado'.ENDIF.
" En condicionesDATA(lv_has_admin) = xsdbool( line_exists( lt_users[ role = 'ADMIN' ] ) ).lines() – Número de líneas
DATA: lt_items TYPE TABLE OF string.
lt_items = VALUE #( ( `A` ) ( `B` ) ( `C` ) ).
" Número de líneasDATA(lv_count) = lines( lt_items ).WRITE: / 'Cantidad:', lv_count. " 3
" En condicionesIF lines( lt_items ) > 0. WRITE: / 'La tabla no está vacía'.ENDIF.
" Leer última líneaIF lines( lt_items ) > 0. DATA(lv_last) = lt_items[ lines( lt_items ) ].ENDIF.line_index() – Índice de una línea
DATA: lt_names TYPE TABLE OF string.
lt_names = VALUE #( ( `Anna` ) ( `Bernd` ) ( `Clara` ) ).
" Determinar el índice de una líneaDATA(lv_index) = line_index( lt_names[ table_line = `Bernd` ] ).WRITE: / 'Índice de Bernd:', lv_index. " 2
" En tablas ordenadas con claveDATA: lt_sorted TYPE SORTED TABLE OF ty_customer WITH UNIQUE KEY id.
DATA(lv_cust_idx) = line_index( lt_sorted[ id = 1001 ] ).Funciones booleanas
xsdbool() – Conversión a booleano
DATA: lv_age TYPE i VALUE 25.
" Convertir condición a booleanoDATA(lv_is_adult) = xsdbool( lv_age >= 18 ).
IF lv_is_adult = abap_true. WRITE: / 'Adulto'.ENDIF.
" En asignacionesDATA: lv_active TYPE abap_bool.lv_active = xsdbool( sy-subrc = 0 ).
" Condiciones complejasDATA(lv_valid) = xsdbool( lv_name IS NOT INITIAL AND lv_email CS '@' AND lv_age BETWEEN 18 AND 99).boolc() – Booleano a carácter
" Devuelve 'X' o ' 'DATA(lv_flag) = boolc( lv_age >= 18 ).
" Útil para campos legacyDATA: lv_legacy_flag TYPE c LENGTH 1.lv_legacy_flag = boolc( lv_condition = abap_true ).Funciones de cadenas
condense() – Eliminar espacios
DATA: lv_text TYPE string VALUE ' Hola Mundo '.
" Eliminar espacios iniciales/finales, reducir múltiples a unoDATA(lv_condensed) = condense( lv_text ).WRITE: / lv_condensed. " 'Hola Mundo'
" Solo eliminar iniciales/finales (NO-GAPS = FALSE)DATA(lv_trimmed) = condense( val = lv_text del = ` ` ).
" Eliminar todos los espaciosDATA(lv_no_spaces) = condense( val = lv_text from = ` ` to = `` ).WRITE: / lv_no_spaces. " 'HolaMundo'concat_lines_of() – Tabla a cadena
DATA: lt_words TYPE TABLE OF string.
lt_words = VALUE #( ( `Uno` ) ( `Dos` ) ( `Tres` ) ).
" Unir con separadorDATA(lv_sentence) = concat_lines_of( table = lt_words sep = `, ` ).WRITE: / lv_sentence. " 'Uno, Dos, Tres'
" Sin separadorDATA(lv_concat) = concat_lines_of( table = lt_words ).WRITE: / lv_concat. " 'UnoDosTres'
" Con salto de líneaDATA(lv_lines) = concat_lines_of( table = lt_words sep = cl_abap_char_utilities=>newline ).to_upper() / to_lower() – Mayúsculas/Minúsculas
DATA: lv_text TYPE string VALUE 'Hola Mundo'.
DATA(lv_upper) = to_upper( lv_text ).WRITE: / lv_upper. " 'HOLA MUNDO'
DATA(lv_lower) = to_lower( lv_text ).WRITE: / lv_lower. " 'hola mundo'
" En comparacionesIF to_upper( lv_input ) = 'SI'. WRITE: / 'Confirmado'.ENDIF.to_mixed() / from_mixed() – CamelCase
" A CamelCaseDATA(lv_camel) = to_mixed( val = 'CUSTOMER_ORDER_ID' sep = '_' ).WRITE: / lv_camel. " 'CustomerOrderId'
" Desde CamelCaseDATA(lv_snake) = from_mixed( val = 'CustomerOrderId' sep = '_' ).WRITE: / lv_snake. " 'customer_order_id'shift_left() / shift_right() – Desplazar
DATA: lv_num TYPE string VALUE '000123'.
" Eliminar caracteres inicialesDATA(lv_shifted) = shift_left( val = lv_num sub = '0' ).WRITE: / lv_shifted. " '123'
" Desplazar n posicionesDATA(lv_shift2) = shift_left( val = 'ABCDEF' places = 2 ).WRITE: / lv_shift2. " 'CDEF'
" Desplazar a la derecha (con relleno)DATA(lv_right) = shift_right( val = '123' places = 5 ).reverse() – Invertir cadena
DATA(lv_reversed) = reverse( 'ABAP' ).WRITE: / lv_reversed. " 'PABA'escape() – Escapar caracteres
DATA: lv_html TYPE string VALUE '<div>Test & "Valor"</div>'.
" Escapar HTMLDATA(lv_escaped) = escape( val = lv_html format = cl_abap_format=>e_html_text ).WRITE: / lv_escaped. " '<div>Test & "Valor"</div>'
" Escapar regexDATA(lv_regex_safe) = escape( val = 'a.b*c?' format = cl_abap_format=>e_regex ).repeat() – Repetir caracteres
DATA(lv_line) = repeat( val = '-' occ = 50 ).WRITE: / lv_line. " '--------------------------------------------------'
DATA(lv_spaces) = repeat( val = ` ` occ = 10 ).substring() – Subcadena
DATA: lv_text TYPE string VALUE 'Hello World'.
" Desde posición 7 (basado en 0)DATA(lv_sub1) = substring( val = lv_text off = 6 ).WRITE: / lv_sub1. " 'World'
" Desde posición con longitudDATA(lv_sub2) = substring( val = lv_text off = 0 len = 5 ).WRITE: / lv_sub2. " 'Hello'
" AtajosDATA(lv_before) = substring_before( val = lv_text sub = ' ' ). " 'Hello'DATA(lv_after) = substring_after( val = lv_text sub = ' ' ). " 'World'DATA(lv_from) = substring_from( val = lv_text sub = 'Wo' ). " 'World'DATA(lv_to) = substring_to( val = lv_text sub = 'o ' ). " 'Hello 'strlen() / numofchar() – Longitud de cadena
DATA: lv_text TYPE string VALUE 'Hallo'.
DATA(lv_len) = strlen( lv_text ).WRITE: / 'Longitud:', lv_len. " 5
" Para tipos de caracteres arbitrariosDATA: lv_char TYPE c LENGTH 10 VALUE 'Test'.DATA(lv_numchar) = numofchar( lv_char ). " 4 (sin espacios finales)contains() / matches() – Búsqueda
" ¿Contiene subcadena?IF contains( val = lv_email sub = '@' ). WRITE: / 'Email válido (contiene @)'.ENDIF.
" ¿Comienza con?IF contains( val = lv_email start = 'test' ). WRITE: / 'Comienza con test'.ENDIF.
" ¿Termina con?IF contains( val = lv_email end = '.com' ). WRITE: / 'Termina con .com'.ENDIF.
" Match con RegexIF matches( val = lv_email regex = '^\w+@\w+\.\w+$' ). WRITE: / 'Formato de email correcto'.ENDIF.find() / count() – Buscar y contar
DATA: lv_text TYPE string VALUE 'ABAP es genial, ABAP es fantástico'.
" Encontrar posiciónDATA(lv_pos) = find( val = lv_text sub = 'es' ).WRITE: / 'Posición:', lv_pos. " 5
" Contar todas las ocurrenciasDATA(lv_count) = count( val = lv_text sub = 'ABAP' ).WRITE: / 'Cantidad:', lv_count. " 2
" Con RegexDATA(lv_regex_count) = count( val = lv_text regex = '\bes\b' ).replace() – Reemplazar
DATA: lv_text TYPE string VALUE 'Hola Mundo'.
" Reemplazar primera ocurrenciaDATA(lv_new1) = replace( val = lv_text sub = 'Mundo' with = 'ABAP' ).WRITE: / lv_new1. " 'Hola ABAP'
" Reemplazar todas las ocurrenciasDATA: lv_multi TYPE string VALUE 'a-b-c-d'.DATA(lv_new2) = replace( val = lv_multi sub = '-' with = '_' occ = 0 ).WRITE: / lv_new2. " 'a_b_c_d'
" Con RegexDATA(lv_digits) = replace( val = 'abc123def' regex = '\d+' with = 'XXX' ).WRITE: / lv_digits. " 'abcXXXdef'segment() – Dividir cadena
DATA: lv_path TYPE string VALUE '/usr/local/bin/app'.
" Extraer segmento (basado en 1)DATA(lv_seg1) = segment( val = lv_path index = 1 sep = '/' ). " ''DATA(lv_seg2) = segment( val = lv_path index = 2 sep = '/' ). " 'usr'DATA(lv_seg3) = segment( val = lv_path index = -1 sep = '/' ). " 'app' (último)Funciones numéricas
abs() – Valor absoluto
DATA(lv_abs) = abs( -42 ).WRITE: / lv_abs. " 42sign() – Signo
DATA(lv_sign1) = sign( -5 ). " -1DATA(lv_sign2) = sign( 0 ). " 0DATA(lv_sign3) = sign( 10 ). " 1ceil() / floor() / trunc() – Redondeo
DATA: lv_num TYPE p DECIMALS 2 VALUE '3.7'.
DATA(lv_ceil) = ceil( lv_num ). " 4 (redondear hacia arriba)DATA(lv_floor) = floor( lv_num ). " 3 (redondear hacia abajo)DATA(lv_trunc) = trunc( lv_num ). " 3 (truncar)round() – Redondear
DATA: lv_num TYPE p DECIMALS 4 VALUE '3.14159'.
DATA(lv_rounded) = round( val = lv_num dec = 2 ).WRITE: / lv_rounded. " 3.14
" Redondear a múltiploDATA(lv_round_5) = round( val = 127 dec = 0 prec = 5 ). " 125nmin() / nmax() – Mínimo/Máximo
DATA(lv_min) = nmin( val1 = 10 val2 = 5 ).WRITE: / 'Mín:', lv_min. " 5
DATA(lv_max) = nmax( val1 = 10 val2 = 5 ).WRITE: / 'Máx:', lv_max. " 10
" Más de 2 valoresDATA(lv_max3) = nmax( val1 = 10 val2 = 25 val3 = 15 ).WRITE: / 'Máx:', lv_max3. " 25ipow() – Potencia (entero)
DATA(lv_power) = ipow( base = 2 exp = 10 ).WRITE: / lv_power. " 1024frac() – Parte decimal
DATA: lv_num TYPE p DECIMALS 2 VALUE '3.75'.
DATA(lv_frac) = frac( lv_num ).WRITE: / lv_frac. " 0.75Funciones de fecha/hora
utclong_current() – Marca de tiempo actual
DATA(lv_timestamp) = utclong_current( ).WRITE: / lv_timestamp. " 2024-11-24 10:30:00.1234567utclong_add() – Añadir tiempo
DATA(lv_now) = utclong_current( ).
" Añadir 1 díaDATA(lv_tomorrow) = utclong_add( val = lv_now days = 1).
" Añadir 2 horasDATA(lv_later) = utclong_add( val = lv_now hours = 2).utclong_diff() – Diferencia de tiempo
DATA: lv_start TYPE utclong, lv_end TYPE utclong.
" Diferencia en segundosDATA(lv_seconds) = utclong_diff( high = lv_end low = lv_start).Funciones de tipo
cl_abap_typedescr – Información de tipo
DATA: lv_string TYPE string VALUE 'Test'.
" Determinar nombre de tipoDATA(lo_type) = cl_abap_typedescr=>describe_by_data( lv_string ).WRITE: / 'Tipo:', lo_type->get_relative_name( ). " 'STRING'WRITE: / 'Kind:', lo_type->kind. " 'E' (Elementary)Resumen por categoría
| Categoría | Funciones |
|---|---|
| Tablas | lines(), line_exists(), line_index() |
| Booleanas | xsdbool(), boolc() |
| Manipulación de cadenas | condense(), to_upper(), to_lower(), to_mixed(), from_mixed() |
| Búsqueda de cadenas | contains(), matches(), find(), count() |
| Extracción de cadenas | substring(), substring_before(), substring_after(), segment() |
| Cadenas - Otros | concat_lines_of(), escape(), repeat(), reverse(), replace(), strlen() |
| Numéricas | abs(), sign(), ceil(), floor(), trunc(), round(), nmin(), nmax(), ipow(), frac() |
| Fecha/Hora | utclong_current(), utclong_add(), utclong_diff() |
Notas importantes / Mejores prácticas
- Las funciones integradas son eficientes – prefierelas sobre implementaciones propias.
line_exists()evita excepciones al acceder a tablas – mejor que TRY-CATCH.xsdbool()devuelveabap_true/abap_false– ideal para expresiones booleanas.condense()reemplaza el statementCONDENSEen expresiones.concat_lines_of()reemplaza construcciones LOOP complejas para concatenación de cadenas.to_upper()/to_lower()son funciones –TRANSLATE ... TO UPPER/LOWERes un statement.- Combina con
String Templatespara formateo legible. nmin()/nmax()soportan hasta 9 valores.matches()para verificaciones regex,contains()para búsqueda simple de subcadenas.- Usa
CONVcuando se necesite conversión de tipos.