ABAP & SAP Data & tekst
Data & tekst

Strings, conversies, datums & tijd

String templates en stringfuncties, reguliere expressies, conversie-exits (voorloopnullen!), en het rekenen met datums, tijden en timestamps inclusief tijdzones.

Op deze pagina

01Stringbewerking

Van klassiek CONCATENATE tot moderne stringfuncties en templates.

Samenvoegen

" Klassiek
CONCATENATE lv_voornaam lv_achternaam INTO lv_naam SEPARATED BY space.

" Modern: template of &&-operator
lv_naam = |{ lv_voornaam } { lv_achternaam }|.
lv_pad  = lv_map && '/' && lv_bestand.
Vaste-lengte-valkuil — bij c-velden worden afsluitende spaties bij concatenatie genegeerd. In een string template kun je ze behouden met { lv_c } plus opmaakopties, of door eerst naar string te converteren.

Splitsen, zoeken, vervangen

SPLIT lv_csv AT ';' INTO TABLE DATA(lt_velden).
SPLIT lv_naam AT space INTO lv_voor lv_achter.

FIND 'fout' IN lv_log IGNORING CASE.          " sy-subrc = 0 indien gevonden
FIND FIRST OCCURRENCE OF '@' IN lv_email MATCH OFFSET DATA(lv_pos).

REPLACE ALL OCCURRENCES OF ',' IN lv_getal WITH '.'.

CONDENSE lv_tekst.                " meervoudige spaties → één; NO-GAPS: alle weg
TRANSLATE lv_code TO UPPER CASE.
SHIFT lv_nr LEFT DELETING LEADING '0'.  " voorloopnullen weg (zie conversie-exits!)

Stringfuncties (7.40+)

FunctieDoet
strlen( lv ) / numofchar( lv )Lengte (met/zonder afsluitende spaties bij c-velden)
substring( val = lv off = 2 len = 3 )Deelstring; ook substring_before/after/from/to
to_upper( ) / to_lower( )Hoofd-/kleine letters
condense( ), shift_left( ), reverse( )Functievarianten van de statements
contains( val = lv sub = 'x' )Predicaat, direct in een IF te gebruiken
concat_lines_of( table = lt sep = ',' )Tabel → één string
repeat( val = '-' occ = 40 )Herhalen

Klassieke offset/lengte-notatie kom je ook nog tegen: lv_jaar = lv_datum+0(4). betekent: vanaf positie 0, 4 tekens. Werkt alleen op vaste-lengte-velden en structuren, niet op string-delen in expressies.

Reguliere expressies

FIND REGEX '^[A-Z]{2}\d{4}$' IN lv_code.
REPLACE ALL OCCURRENCES OF REGEX '\s+' IN lv_tekst WITH ' '.

DATA(lv_schoon) = replace( val = lv_tekst regex = '[^0-9]' with = '' occ = 0 ).
IF matches( val = lv_email regex = '.+@.+\..+' ). " volledige match

Nieuwere releases onderscheiden POSIX- (REGEX) en PCRE-syntax (PCRE, aan te raden). De class CL_ABAP_MATCHER/CL_ABAP_REGEX biedt een object-API met groepen en herhaald matchen.

02Conversie-exits & in-/uitvoerformaat

Waarom een materiaalnummer in de database 000000000000000100 is maar op het scherm 100 — en hoe je daar niet door verrast wordt.

Een conversie-exit is een paar functiemodules aan een domein: CONVERSION_EXIT_XXXXX_INPUT (schermformaat → intern formaat) en ..._OUTPUT (intern → scherm). De bekendste is ALPHA: voorloopnullen toevoegen/verwijderen.

" Invoer normaliseren vóór een SELECT (anders vind je niets!)
lv_matnr = |{ lv_invoer ALPHA = IN }|.    " '100' → '000000000000000100'
lv_toon  = |{ lv_matnr ALPHA = OUT }|.    " en terug

" Klassiek equivalent
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
  EXPORTING input  = lv_invoer
  IMPORTING output = lv_matnr.
Klassieker — "mijn SELECT vindt het materiaal niet, maar het bestaat echt": de invoer mist voorloopnullen. Interne formaten zijn altijd mét nullen; schermen en ALV tonen zonder. Selectieschermvelden met het juiste DDIC-type converteren automatisch; strings en bestandsinvoer niet.

Andere veel voorkomende exits: MATN1 (materiaalnummer), CUNIT (maateenheden: intern ST, extern PCE/"stuks"), PERI (periodes). Getallen- en datumnotatie per gebruiker (punt/komma, dd.mm.jjjj) worden geregeld via de gebruikersinstellingen (SU3) en de opmaakopties NUMBER = USER / DATE = USER in templates, of WRITE ... TO.

03Datums & tijd

Datums zijn tekstvelden met rekenkracht: je kunt er gewoon mee optellen en aftrekken.

DATA: lv_vandaag TYPE dats,
      lv_morgen  TYPE dats.

lv_vandaag = sy-datum.            " systeemdatum (applicatieserver)
lv_morgen  = lv_vandaag + 1.      " datumrekenen in dagen
DATA(lv_dagen) = lv_tot - lv_van. " verschil = integer (dagen)

DATA(lv_jaar)  = lv_vandaag+0(4). " JJJJ  — offset/lengte
DATA(lv_maand) = lv_vandaag+4(2). " MM
DATA(lv_dag)   = lv_vandaag+6(2). " DD
SysteemveldInhoud
sy-datum / sy-uzeitDatum en tijd van de applicatieserver (serversysteemtijd)
sy-datlo / sy-timloLokale datum/tijd van de gebruiker (diens tijdzone)
sy-zonloTijdzone van de gebruiker
sy-fdaywWeekdag van de fabriekskalender

Eind van de maand, werkdagen, kalenders

Timestamps & tijdzones

DATA lv_ts TYPE timestamp.       " JJJJMMDDUUMMSS als packed getal (UTC!)
GET TIME STAMP FIELD lv_ts.

" Timestamp → lokale datum/tijd
CONVERT TIME STAMP lv_ts TIME ZONE sy-zonlo
        INTO DATE DATA(lv_datum) TIME DATA(lv_tijd).

" Lokale datum/tijd → timestamp
CONVERT DATE lv_datum TIME lv_tijd INTO TIME STAMP lv_ts TIME ZONE 'CET'.
Onthoud — een timestamp is altijd UTC; sy-datum/sy-uzeit zijn servertijd; sy-datlo/sy-timlo zijn gebruikerstijd. Vergelijk nooit een timestamp rechtstreeks met sy-datum zonder conversie. timestampl is de variant met 7 decimalen (microseconden). Moderne releases kennen ook utclong met eigen functies (utclong_current( ), utclong_add( )).